diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 0c8638b673d4..05656774f0e9 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -253,14 +253,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx.sub(tag, bx.cx().const_uint_big(niche_llty, niche_start)) }; let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32(); - let is_niche = { - let relative_max = if relative_max == 0 { - // Avoid calling `const_uint`, which wouldn't work for pointers. - // FIXME(eddyb) check the actual primitive type here. - bx.cx().const_null(niche_llty) - } else { - bx.cx().const_uint(niche_llty, relative_max as u64) - }; + let is_niche = if relative_max == 0 { + // Avoid calling `const_uint`, which wouldn't work for pointers. + // Also use canonical == 0 instead of non-canonical u<= 0. + // FIXME(eddyb) check the actual primitive type here. + bx.icmp(IntPredicate::IntEQ, relative_discr, bx.cx().const_null(niche_llty)) + } else { + let relative_max = bx.cx().const_uint(niche_llty, relative_max as u64); bx.icmp(IntPredicate::IntULE, relative_discr, relative_max) }; diff --git a/src/test/codegen/some-global-nonnull.rs b/src/test/codegen/some-global-nonnull.rs new file mode 100644 index 000000000000..59c47de4129c --- /dev/null +++ b/src/test/codegen/some-global-nonnull.rs @@ -0,0 +1,25 @@ +// compile-flags: -O + +#![crate_type = "lib"] + +// CHECK-LABEL: @test +// CHECK-NEXT: start: +// CHECK-NEXT: tail call void @ext_fn0() +#[no_mangle] +pub fn test() { + test_inner(Some(inner0)); +} + +fn test_inner(f_maybe: Option) { + if let Some(f) = f_maybe { + f(); + } +} + +fn inner0() { + unsafe { ext_fn0() }; +} + +extern "C" { + fn ext_fn0(); +}