Don't drop Rvalue::WrapUnsafeBinder during GVN
This commit is contained in:
parent
4d30011f6c
commit
13134dd096
4 changed files with 102 additions and 2 deletions
|
@ -872,8 +872,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
self.simplify_place_projection(place, location);
|
||||
return self.new_pointer(*place, AddressKind::Address(mutbl));
|
||||
}
|
||||
Rvalue::WrapUnsafeBinder(ref mut op, _) => {
|
||||
return self.simplify_operand(op, location);
|
||||
Rvalue::WrapUnsafeBinder(ref mut op, ty) => {
|
||||
let value = self.simplify_operand(op, location)?;
|
||||
Value::Cast {
|
||||
kind: CastKind::Transmute,
|
||||
value,
|
||||
from: op.ty(self.local_decls, self.tcx),
|
||||
to: ty,
|
||||
}
|
||||
}
|
||||
|
||||
// Operations.
|
||||
|
|
35
tests/mir-opt/gvn_on_unsafe_binder.propagate.GVN.diff
Normal file
35
tests/mir-opt/gvn_on_unsafe_binder.propagate.GVN.diff
Normal file
|
@ -0,0 +1,35 @@
|
|||
- // MIR for `propagate` before GVN
|
||||
+ // MIR for `propagate` after GVN
|
||||
|
||||
fn propagate() -> unsafe<> i32 {
|
||||
let mut _0: unsafe<> i32;
|
||||
let _1: i32;
|
||||
let mut _3: i32;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
let _2: unsafe<> i32;
|
||||
scope 2 {
|
||||
debug binder => _2;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_1);
|
||||
+ nop;
|
||||
_1 = const 1_i32;
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = copy _1;
|
||||
- _2 = wrap_binder!(move _3; unsafe<> i32);
|
||||
+ _3 = const 1_i32;
|
||||
+ _2 = const {transmute(0x00000001): unsafe<> i32};
|
||||
StorageDead(_3);
|
||||
- _0 = move _2;
|
||||
+ _0 = const {transmute(0x00000001): unsafe<> i32};
|
||||
StorageDead(_2);
|
||||
- StorageDead(_1);
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
29
tests/mir-opt/gvn_on_unsafe_binder.rs
Normal file
29
tests/mir-opt/gvn_on_unsafe_binder.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// skip-filecheck
|
||||
//@ test-mir-pass: GVN
|
||||
|
||||
// EMIT_MIR gvn_on_unsafe_binder.test.GVN.diff
|
||||
// EMIT_MIR gvn_on_unsafe_binder.propagate.GVN.diff
|
||||
|
||||
#![feature(unsafe_binders)]
|
||||
|
||||
use std::unsafe_binder::wrap_binder;
|
||||
|
||||
// Test for ICE <https://github.com/rust-lang/rust/issues/137846>.
|
||||
fn test() {
|
||||
unsafe {
|
||||
let x = 1;
|
||||
let binder: unsafe<'a> &'a i32 = wrap_binder!(&x);
|
||||
}
|
||||
}
|
||||
|
||||
// Test that GVN propagates const values through unsafe binders.
|
||||
//
|
||||
// The lifetime `'a` is redundant (and doesn't print when we print out the type).
|
||||
// However, we need it so that rustfmt doesn't rip out the `unsafe<>` part for now.
|
||||
fn propagate() -> unsafe<'a> i32 {
|
||||
unsafe {
|
||||
let x = 1;
|
||||
let binder: unsafe<'a> i32 = wrap_binder!(x);
|
||||
binder
|
||||
}
|
||||
}
|
30
tests/mir-opt/gvn_on_unsafe_binder.test.GVN.diff
Normal file
30
tests/mir-opt/gvn_on_unsafe_binder.test.GVN.diff
Normal file
|
@ -0,0 +1,30 @@
|
|||
- // MIR for `test` before GVN
|
||||
+ // MIR for `test` after GVN
|
||||
|
||||
fn test() -> () {
|
||||
let mut _0: ();
|
||||
let _1: i32;
|
||||
let mut _3: &i32;
|
||||
scope 1 {
|
||||
debug x => _1;
|
||||
let _2: unsafe<'a> &'a i32;
|
||||
scope 2 {
|
||||
debug binder => _2;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
_1 = const 1_i32;
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = &_1;
|
||||
_2 = wrap_binder!(move _3; unsafe<'a> &'a i32);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue