From 029579d1770fb23c693b2ecbab724fe3af66349b Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 9 Oct 2025 19:00:21 -0400 Subject: [PATCH] Change int-to-ptr transmute lowering back to inttoptr --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 4 ++-- tests/codegen-llvm/common_prim_int_ptr.rs | 2 +- tests/codegen-llvm/enum/enum-aggregate.rs | 2 +- .../int-ptr-int-enum-miscompile.rs | 22 +++++++++++++++++++ .../intrinsics/transmute-niched.rs | 2 +- tests/codegen-llvm/intrinsics/transmute.rs | 4 ++-- tests/codegen-llvm/transmute-scalar.rs | 2 +- 7 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 tests/codegen-llvm/int-ptr-int-enum-miscompile.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index d629003bff5e8..88ece6318acf7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1010,14 +1010,14 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( imm = match (from_scalar.primitive(), to_scalar.primitive()) { (Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty), (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty), - (Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm), + (Int(..), Pointer(..)) => bx.inttoptr(imm, to_backend_ty), (Pointer(..), Int(..)) => { // FIXME: this exposes the provenance, which shouldn't be necessary. bx.ptrtoint(imm, to_backend_ty) } (Float(_), Pointer(..)) => { let int_imm = bx.bitcast(imm, bx.cx().type_isize()); - bx.ptradd(bx.const_null(bx.type_ptr()), int_imm) + bx.inttoptr(int_imm, to_backend_ty) } (Pointer(..), Float(_)) => { // FIXME: this exposes the provenance, which shouldn't be necessary. diff --git a/tests/codegen-llvm/common_prim_int_ptr.rs b/tests/codegen-llvm/common_prim_int_ptr.rs index 53716adccbf21..2c906e86bd736 100644 --- a/tests/codegen-llvm/common_prim_int_ptr.rs +++ b/tests/codegen-llvm/common_prim_int_ptr.rs @@ -11,7 +11,7 @@ #[no_mangle] pub fn insert_int(x: usize) -> Result> { // CHECK: start: - // CHECK-NEXT: %[[WO_PROV:.+]] = getelementptr i8, ptr null, [[USIZE:i[0-9]+]] %x + // CHECK-NEXT: %[[WO_PROV:.+]] = inttoptr [[USIZE:i[0-9]+]] %x to ptr // CHECK-NEXT: %[[R:.+]] = insertvalue { [[USIZE]], ptr } { [[USIZE]] 0, ptr poison }, ptr %[[WO_PROV]], 1 // CHECK-NEXT: ret { [[USIZE]], ptr } %[[R]] Ok(x) diff --git a/tests/codegen-llvm/enum/enum-aggregate.rs b/tests/codegen-llvm/enum/enum-aggregate.rs index 7d450a89e2e3c..89517008c6374 100644 --- a/tests/codegen-llvm/enum/enum-aggregate.rs +++ b/tests/codegen-llvm/enum/enum-aggregate.rs @@ -70,7 +70,7 @@ fn make_ok_ptr(x: NonNull) -> Result, usize> { fn make_ok_int(x: usize) -> Result> { // CHECK-LABEL: { i64, ptr } @make_ok_int(i64 %x) // CHECK-NEXT: start: - // CHECK-NEXT: %[[NOPROV:.+]] = getelementptr i8, ptr null, i64 %x + // CHECK-NEXT: %[[NOPROV:.+]] = inttoptr i64 %x to ptr // CHECK-NEXT: %[[R:.+]] = insertvalue { i64, ptr } { i64 0, ptr poison }, ptr %[[NOPROV]], 1 // CHECK-NEXT: ret { i64, ptr } %[[R]] Ok(x) diff --git a/tests/codegen-llvm/int-ptr-int-enum-miscompile.rs b/tests/codegen-llvm/int-ptr-int-enum-miscompile.rs new file mode 100644 index 0000000000000..299c3bf8847b2 --- /dev/null +++ b/tests/codegen-llvm/int-ptr-int-enum-miscompile.rs @@ -0,0 +1,22 @@ +// This is a regression test for https://github.com/rust-lang/rust/issues/147265. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +#[no_mangle] +pub fn mk_result(a: usize) -> Result { + // CHECK-LABEL: @mk_result + // CHECK-NOT: unreachable + // CHECK: load i8, + // CHECK-NOT: unreachable + match g(a) { + Ok(b) => Ok(unsafe { *(b as *const u8) }), + Err(c) => Err(c), + } +} + +#[cold] +fn g(a: usize) -> Result { + Ok(a) +} diff --git a/tests/codegen-llvm/intrinsics/transmute-niched.rs b/tests/codegen-llvm/intrinsics/transmute-niched.rs index a886d9eee5909..8c647655f65bb 100644 --- a/tests/codegen-llvm/intrinsics/transmute-niched.rs +++ b/tests/codegen-llvm/intrinsics/transmute-niched.rs @@ -249,7 +249,7 @@ pub unsafe fn check_four_or_eight_to_nonnull(x: FourOrEight) -> NonNull { // OPT: call void @llvm.assume(i1 %1) // CHECK-NOT: icmp // CHECK-NOT: assume - // CHECK: %[[RET:.+]] = getelementptr i8, ptr null, i64 %x + // CHECK: %[[RET:.+]] = inttoptr i64 %x to ptr // CHECK-NEXT: ret ptr %[[RET]] transmute(x) diff --git a/tests/codegen-llvm/intrinsics/transmute.rs b/tests/codegen-llvm/intrinsics/transmute.rs index e327c100d7ddd..b86c6df3267e4 100644 --- a/tests/codegen-llvm/intrinsics/transmute.rs +++ b/tests/codegen-llvm/intrinsics/transmute.rs @@ -303,7 +303,7 @@ pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) { pub unsafe fn check_float_to_pointer(x: f64) -> *const () { // CHECK-NOT: alloca // CHECK: %0 = bitcast double %x to i64 - // CHECK: %_0 = getelementptr i8, ptr null, i64 %0 + // CHECK: %_0 = inttoptr i64 %0 to ptr // CHECK: ret ptr %_0 transmute(x) } @@ -378,7 +378,7 @@ pub unsafe fn check_issue_110005(x: (usize, bool)) -> Option> { // CHECK-LABEL: @check_pair_to_dst_ref( #[no_mangle] pub unsafe fn check_pair_to_dst_ref<'a>(x: (usize, usize)) -> &'a [u8] { - // CHECK: %_0.0 = getelementptr i8, ptr null, i64 %x.0 + // CHECK: %_0.0 = inttoptr i64 %x.0 to ptr // CHECK: %0 = icmp ne ptr %_0.0, null // CHECK: call void @llvm.assume(i1 %0) // CHECK: %1 = insertvalue { ptr, i64 } poison, ptr %_0.0, 0 diff --git a/tests/codegen-llvm/transmute-scalar.rs b/tests/codegen-llvm/transmute-scalar.rs index 21f7287047cf0..e1ce8e506066a 100644 --- a/tests/codegen-llvm/transmute-scalar.rs +++ b/tests/codegen-llvm/transmute-scalar.rs @@ -56,7 +56,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { } // CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i) -// CHECK: %_0 = getelementptr i8, ptr null, [[USIZE]] %i +// CHECK: %_0 = inttoptr [[USIZE]] %i to ptr // CHECK-NEXT: ret ptr %_0 #[no_mangle] pub fn int_to_ptr(i: usize) -> *mut u16 {