Skip to content

Commit

Permalink
Only update Eq operands in GVN if you can update both sides
Browse files Browse the repository at this point in the history
Otherwise the types might not match

Fixes 127089
  • Loading branch information
scottmcm committed Jun 29, 2024
1 parent e9e6e2e commit c9f36f8
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 5 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1074,11 +1074,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
{
lhs = *lhs_value;
rhs = *rhs_value;
if let Some(op) = self.try_as_operand(lhs, location) {
*lhs_operand = op;
}
if let Some(op) = self.try_as_operand(rhs, location) {
*rhs_operand = op;
if let Some(lhs_op) = self.try_as_operand(lhs, location)
&& let Some(rhs_op) = self.try_as_operand(rhs, location)
{
*lhs_operand = lhs_op;
*rhs_operand = rhs_op;
}
}

Expand Down
52 changes: 52 additions & 0 deletions tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
- // MIR for `main` before GVN
+ // MIR for `main` after GVN

fn main() -> () {
let mut _0: ();
let _1: bool;
let mut _2: *mut u8;
scope 1 (inlined dangling_mut::<u8>) {
let mut _3: usize;
scope 2 (inlined align_of::<u8>) {
}
scope 3 (inlined without_provenance_mut::<u8>) {
}
}
scope 4 (inlined Foo::<u8>::cmp_ptr) {
let mut _4: *const u8;
let mut _5: *mut u8;
let mut _6: *const u8;
scope 5 (inlined std::ptr::eq::<u8>) {
}
}

bb0: {
StorageLive(_1);
StorageLive(_2);
StorageLive(_3);
- _3 = AlignOf(u8);
- _2 = _3 as *mut u8 (Transmute);
+ _3 = const 1_usize;
+ _2 = const {0x1 as *mut u8};
StorageDead(_3);
StorageLive(_4);
StorageLive(_5);
- _5 = _2;
- _4 = _2 as *const u8 (PtrToPtr);
+ _5 = const {0x1 as *mut u8};
+ _4 = const {0x1 as *const u8};
StorageDead(_5);
StorageLive(_6);
- _6 = const Foo::<u8>::SENTINEL as *const u8 (PtrToPtr);
- _1 = Eq(_4, _6);
+ _6 = const {0x1 as *const u8};
+ _1 = const true;
StorageDead(_6);
StorageDead(_4);
StorageDead(_2);
StorageDead(_1);
_0 = const ();
return;
}
}

23 changes: 23 additions & 0 deletions tests/mir-opt/gvn_ptr_eq_with_constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// skip-filecheck
//@ test-mir-pass: GVN
//@ only-64bit
//@ compile-flags: -Z mir-enable-passes=+Inline

// Regression for <https://github.com/rust-lang/rust/issues/127089>

#![feature(strict_provenance)]

struct Foo<T>(std::marker::PhantomData<T>);

impl<T> Foo<T> {
const SENTINEL: *mut T = std::ptr::dangling_mut();

fn cmp_ptr(a: *mut T) -> bool {
std::ptr::eq(a, Self::SENTINEL)
}
}

// EMIT_MIR gvn_ptr_eq_with_constant.main.GVN.diff
pub fn main() {
Foo::<u8>::cmp_ptr(std::ptr::dangling_mut());
}

0 comments on commit c9f36f8

Please sign in to comment.