diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 6cb62280a595e..7dfcf1ab50e41 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -909,6 +909,7 @@ impl<'ll> CodegenCx<'ll, '_> { ifn!("llvm.is.constant.isize", fn(t_isize) -> i1); ifn!("llvm.is.constant.f32", fn(t_f32) -> i1); ifn!("llvm.is.constant.f64", fn(t_f64) -> i1); + ifn!("llvm.is.constant.ptr", fn(ptr) -> i1); ifn!("llvm.expect.i1", fn(i1, i1) -> i1); ifn!("llvm.eh.typeid.for", fn(ptr) -> t_i32); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index f1a6f7bd8e690..b4512af38e37b 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -119,10 +119,18 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { sym::likely => { self.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(true)]) } - sym::is_val_statically_known => self.call_intrinsic( - &format!("llvm.is.constant.{:?}", args[0].layout.immediate_llvm_type(self.cx)), - &[args[0].immediate()], - ), + sym::is_val_statically_known => { + let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx); + match self.type_kind(intrinsic_type) { + TypeKind::Pointer | TypeKind::Integer | TypeKind::Float | TypeKind::Double => { + self.call_intrinsic( + &format!("llvm.is.constant.{:?}", intrinsic_type), + &[args[0].immediate()], + ) + } + _ => self.const_bool(false), + } + } sym::unlikely => self .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]), kw::Try => { diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs index 44187d4f667dd..8f084f6c54bdc 100644 --- a/tests/codegen/is_val_statically_known.rs +++ b/tests/codegen/is_val_statically_known.rs @@ -46,3 +46,41 @@ pub fn _bool_false(b: bool) -> i32 { // CHECK: ret i32 2 _bool(b) } + +#[inline] +pub fn _iref(a: &u8) -> i32 { + if unsafe { is_val_statically_known(a) } { 5 } else { 4 } +} + +// CHECK-LABEL: @_iref_borrow( +#[no_mangle] +pub fn _iref_borrow() -> i32 { + // CHECK: ret i32 4 + _iref(&0) +} + +// CHECK-LABEL: @_iref_arg( +#[no_mangle] +pub fn _iref_arg(a: &u8) -> i32 { + // CHECK: ret i32 4 + _iref(a) +} + +#[inline] +pub fn _slice_ref(a: &[u8]) -> i32 { + if unsafe { is_val_statically_known(a) } { 7 } else { 6 } +} + +// CHECK-LABEL: @_slice_ref_borrow( +#[no_mangle] +pub fn _slice_ref_borrow() -> i32 { + // CHECK: ret i32 6 + _slice_ref(&[0;3]) +} + +// CHECK-LABEL: @_slice_ref_arg( +#[no_mangle] +pub fn _slice_ref_arg(a: &[u8]) -> i32 { + // CHECK: ret i32 6 + _slice_ref(a) +}