Skip to content

Commit 6f24836

Browse files
authored
Rollup merge of #120484 - Teapot4195:issue-120480-fix, r=compiler-errors
Avoid ICE when is_val_statically_known is not of a supported type 2 ICE with 1 stone! 1. Implement `llvm.is.constant.ptr` to avoid first ICE in linked issue. 2. return `false` when the argument is not one of `i*`/`f*`/`ptr` to avoid second ICE. fixes #120480
2 parents b11fbfb + a97ff2a commit 6f24836

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

compiler/rustc_codegen_llvm/src/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ impl<'ll> CodegenCx<'ll, '_> {
909909
ifn!("llvm.is.constant.isize", fn(t_isize) -> i1);
910910
ifn!("llvm.is.constant.f32", fn(t_f32) -> i1);
911911
ifn!("llvm.is.constant.f64", fn(t_f64) -> i1);
912+
ifn!("llvm.is.constant.ptr", fn(ptr) -> i1);
912913

913914
ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
914915
ifn!("llvm.eh.typeid.for", fn(ptr) -> t_i32);

compiler/rustc_codegen_llvm/src/intrinsic.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,18 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
119119
sym::likely => {
120120
self.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(true)])
121121
}
122-
sym::is_val_statically_known => self.call_intrinsic(
123-
&format!("llvm.is.constant.{:?}", args[0].layout.immediate_llvm_type(self.cx)),
124-
&[args[0].immediate()],
125-
),
122+
sym::is_val_statically_known => {
123+
let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx);
124+
match self.type_kind(intrinsic_type) {
125+
TypeKind::Pointer | TypeKind::Integer | TypeKind::Float | TypeKind::Double => {
126+
self.call_intrinsic(
127+
&format!("llvm.is.constant.{:?}", intrinsic_type),
128+
&[args[0].immediate()],
129+
)
130+
}
131+
_ => self.const_bool(false),
132+
}
133+
}
126134
sym::unlikely => self
127135
.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]),
128136
kw::Try => {

tests/codegen/is_val_statically_known.rs

+38
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,41 @@ pub fn _bool_false(b: bool) -> i32 {
4646
// CHECK: ret i32 2
4747
_bool(b)
4848
}
49+
50+
#[inline]
51+
pub fn _iref(a: &u8) -> i32 {
52+
if unsafe { is_val_statically_known(a) } { 5 } else { 4 }
53+
}
54+
55+
// CHECK-LABEL: @_iref_borrow(
56+
#[no_mangle]
57+
pub fn _iref_borrow() -> i32 {
58+
// CHECK: ret i32 4
59+
_iref(&0)
60+
}
61+
62+
// CHECK-LABEL: @_iref_arg(
63+
#[no_mangle]
64+
pub fn _iref_arg(a: &u8) -> i32 {
65+
// CHECK: ret i32 4
66+
_iref(a)
67+
}
68+
69+
#[inline]
70+
pub fn _slice_ref(a: &[u8]) -> i32 {
71+
if unsafe { is_val_statically_known(a) } { 7 } else { 6 }
72+
}
73+
74+
// CHECK-LABEL: @_slice_ref_borrow(
75+
#[no_mangle]
76+
pub fn _slice_ref_borrow() -> i32 {
77+
// CHECK: ret i32 6
78+
_slice_ref(&[0;3])
79+
}
80+
81+
// CHECK-LABEL: @_slice_ref_arg(
82+
#[no_mangle]
83+
pub fn _slice_ref_arg(a: &[u8]) -> i32 {
84+
// CHECK: ret i32 6
85+
_slice_ref(a)
86+
}

0 commit comments

Comments
 (0)