Auto merge of #147541 - saethlin:transmute-carefully, r=scottmcm

Change int-to-ptr transmute lowering back to inttoptr

This is a revert of https://github.com/rust-lang/rust/pull/121282, but with a regression test to cover the reported miscompile in https://github.com/rust-lang/rust/issues/147265 that was caused by the way the code here combines with https://github.com/rust-lang/rust/pull/138759.
This commit is contained in:
bors 2025-10-13 15:24:11 +00:00
commit ed1d94311e
7 changed files with 30 additions and 8 deletions

View file

@ -1008,14 +1008,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.

View file

@ -11,7 +11,7 @@
#[no_mangle]
pub fn insert_int(x: usize) -> Result<usize, Box<()>> {
// 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)

View file

@ -70,7 +70,7 @@ fn make_ok_ptr(x: NonNull<u16>) -> Result<NonNull<u16>, usize> {
fn make_ok_int(x: usize) -> Result<usize, NonNull<u16>> {
// 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)

View file

@ -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<u8, *const u8> {
// 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<usize, *const u8> {
Ok(a)
}

View file

@ -249,7 +249,7 @@ pub unsafe fn check_four_or_eight_to_nonnull(x: FourOrEight) -> NonNull<u8> {
// 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)

View file

@ -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<Box<[u8]>> {
// 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

View file

@ -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 {