mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 10:33:34 +00:00
GVN away PtrToPtr before comparisons
Notably this happens in `NonNull::eq` :/
This commit is contained in:
parent
a76e1d9b09
commit
dd1e19e7c2
@ -823,18 +823,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
return self.simplify_cast(kind, value, to, location);
|
||||
}
|
||||
Rvalue::BinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
|
||||
let ty = lhs.ty(self.local_decls, self.tcx);
|
||||
let lhs = self.simplify_operand(lhs, location);
|
||||
let rhs = self.simplify_operand(rhs, location);
|
||||
// Only short-circuit options after we called `simplify_operand`
|
||||
// on both operands for side effect.
|
||||
let lhs = lhs?;
|
||||
let rhs = rhs?;
|
||||
|
||||
if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
Value::BinaryOp(op, lhs, rhs)
|
||||
return self.simplify_binary(op, lhs, rhs, location);
|
||||
}
|
||||
Rvalue::UnaryOp(op, ref mut arg_op) => {
|
||||
return self.simplify_unary(op, arg_op, location);
|
||||
@ -1059,6 +1048,52 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn simplify_binary(
|
||||
&mut self,
|
||||
op: BinOp,
|
||||
lhs_operand: &mut Operand<'tcx>,
|
||||
rhs_operand: &mut Operand<'tcx>,
|
||||
location: Location,
|
||||
) -> Option<VnIndex> {
|
||||
|
||||
let lhs = self.simplify_operand(lhs_operand, location);
|
||||
let rhs = self.simplify_operand(rhs_operand, location);
|
||||
// Only short-circuit options after we called `simplify_operand`
|
||||
// on both operands for side effect.
|
||||
let mut lhs = lhs?;
|
||||
let mut rhs = rhs?;
|
||||
|
||||
let lhs_ty = lhs_operand.ty(self.local_decls, self.tcx);
|
||||
|
||||
// If we're comparing pointers, remove `PtrToPtr` casts if the from
|
||||
// types of both casts and the metadata all match.
|
||||
if let BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge = op
|
||||
&& lhs_ty.is_any_ptr()
|
||||
&& let Value::Cast { kind: CastKind::PtrToPtr, value: lhs_value, from: lhs_from, .. } =
|
||||
self.get(lhs)
|
||||
&& let Value::Cast { kind: CastKind::PtrToPtr, value: rhs_value, from: rhs_from, .. } =
|
||||
self.get(rhs)
|
||||
&& lhs_from == rhs_from
|
||||
&& lhs_from.pointee_metadata_ty_or_projection(self.tcx)
|
||||
== lhs_ty.pointee_metadata_ty_or_projection(self.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(value) = self.simplify_binary_inner(op, lhs_ty, lhs, rhs) {
|
||||
return Some(value);
|
||||
}
|
||||
let value = Value::BinaryOp(op, lhs, rhs);
|
||||
Some(self.insert(value))
|
||||
}
|
||||
|
||||
fn simplify_binary_inner(
|
||||
&mut self,
|
||||
op: BinOp,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
|
134
tests/mir-opt/gvn.cast_pointer_eq.GVN.panic-abort.diff
Normal file
134
tests/mir-opt/gvn.cast_pointer_eq.GVN.panic-abort.diff
Normal file
@ -0,0 +1,134 @@
|
||||
- // MIR for `cast_pointer_eq` before GVN
|
||||
+ // MIR for `cast_pointer_eq` after GVN
|
||||
|
||||
fn cast_pointer_eq(_1: *mut u8, _2: *mut u32, _3: *mut u32, _4: *mut [u32]) -> () {
|
||||
debug p1 => _1;
|
||||
debug p2 => _2;
|
||||
debug p3 => _3;
|
||||
debug p4 => _4;
|
||||
let mut _0: ();
|
||||
let _5: *const u32;
|
||||
let mut _6: *mut u8;
|
||||
let mut _8: *const u32;
|
||||
let mut _9: *mut u32;
|
||||
let mut _11: *const u32;
|
||||
let mut _12: *mut u32;
|
||||
let mut _14: *mut [u32];
|
||||
let mut _16: *const u32;
|
||||
let mut _17: *const u32;
|
||||
let mut _19: *const u32;
|
||||
let mut _20: *const u32;
|
||||
let mut _22: *const u32;
|
||||
let mut _23: *const u32;
|
||||
scope 1 {
|
||||
debug m1 => _5;
|
||||
let _7: *const u32;
|
||||
scope 2 {
|
||||
debug m2 => _7;
|
||||
let _10: *const u32;
|
||||
scope 3 {
|
||||
debug m3 => _10;
|
||||
let _13: *const u32;
|
||||
scope 4 {
|
||||
debug m4 => _13;
|
||||
let _15: bool;
|
||||
scope 5 {
|
||||
debug eq_different_thing => _15;
|
||||
let _18: bool;
|
||||
scope 6 {
|
||||
debug eq_optimize => _18;
|
||||
let _21: bool;
|
||||
scope 7 {
|
||||
debug eq_thin_fat => _21;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_6);
|
||||
_6 = _1;
|
||||
- _5 = move _6 as *const u32 (PtrToPtr);
|
||||
+ _5 = _1 as *const u32 (PtrToPtr);
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
- StorageLive(_8);
|
||||
+ nop;
|
||||
StorageLive(_9);
|
||||
_9 = _2;
|
||||
- _8 = move _9 as *const u32 (PtrToPtr);
|
||||
+ _8 = _2 as *const u32 (PtrToPtr);
|
||||
StorageDead(_9);
|
||||
- _7 = move _8 as *const u32 (PtrToPtr);
|
||||
- StorageDead(_8);
|
||||
+ _7 = _8;
|
||||
+ nop;
|
||||
StorageLive(_10);
|
||||
- StorageLive(_11);
|
||||
+ nop;
|
||||
StorageLive(_12);
|
||||
_12 = _3;
|
||||
- _11 = move _12 as *const u32 (PtrToPtr);
|
||||
+ _11 = _3 as *const u32 (PtrToPtr);
|
||||
StorageDead(_12);
|
||||
- _10 = move _11 as *const u32 (PtrToPtr);
|
||||
- StorageDead(_11);
|
||||
- StorageLive(_13);
|
||||
+ _10 = _11;
|
||||
+ nop;
|
||||
+ nop;
|
||||
StorageLive(_14);
|
||||
_14 = _4;
|
||||
- _13 = move _14 as *const u32 (PtrToPtr);
|
||||
+ _13 = _4 as *const u32 (PtrToPtr);
|
||||
StorageDead(_14);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
_16 = _5;
|
||||
StorageLive(_17);
|
||||
- _17 = _7;
|
||||
- _15 = Eq(move _16, move _17);
|
||||
+ _17 = _8;
|
||||
+ _15 = Eq(_5, _8);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
- _19 = _7;
|
||||
+ _19 = _8;
|
||||
StorageLive(_20);
|
||||
- _20 = _10;
|
||||
- _18 = Eq(move _19, move _20);
|
||||
+ _20 = _11;
|
||||
+ _18 = Eq(_2, _3);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageLive(_21);
|
||||
StorageLive(_22);
|
||||
- _22 = _10;
|
||||
+ _22 = _11;
|
||||
StorageLive(_23);
|
||||
_23 = _13;
|
||||
- _21 = Eq(move _22, move _23);
|
||||
+ _21 = Eq(_11, _13);
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
_0 = const ();
|
||||
StorageDead(_21);
|
||||
StorageDead(_18);
|
||||
StorageDead(_15);
|
||||
- StorageDead(_13);
|
||||
+ nop;
|
||||
StorageDead(_10);
|
||||
StorageDead(_7);
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
134
tests/mir-opt/gvn.cast_pointer_eq.GVN.panic-unwind.diff
Normal file
134
tests/mir-opt/gvn.cast_pointer_eq.GVN.panic-unwind.diff
Normal file
@ -0,0 +1,134 @@
|
||||
- // MIR for `cast_pointer_eq` before GVN
|
||||
+ // MIR for `cast_pointer_eq` after GVN
|
||||
|
||||
fn cast_pointer_eq(_1: *mut u8, _2: *mut u32, _3: *mut u32, _4: *mut [u32]) -> () {
|
||||
debug p1 => _1;
|
||||
debug p2 => _2;
|
||||
debug p3 => _3;
|
||||
debug p4 => _4;
|
||||
let mut _0: ();
|
||||
let _5: *const u32;
|
||||
let mut _6: *mut u8;
|
||||
let mut _8: *const u32;
|
||||
let mut _9: *mut u32;
|
||||
let mut _11: *const u32;
|
||||
let mut _12: *mut u32;
|
||||
let mut _14: *mut [u32];
|
||||
let mut _16: *const u32;
|
||||
let mut _17: *const u32;
|
||||
let mut _19: *const u32;
|
||||
let mut _20: *const u32;
|
||||
let mut _22: *const u32;
|
||||
let mut _23: *const u32;
|
||||
scope 1 {
|
||||
debug m1 => _5;
|
||||
let _7: *const u32;
|
||||
scope 2 {
|
||||
debug m2 => _7;
|
||||
let _10: *const u32;
|
||||
scope 3 {
|
||||
debug m3 => _10;
|
||||
let _13: *const u32;
|
||||
scope 4 {
|
||||
debug m4 => _13;
|
||||
let _15: bool;
|
||||
scope 5 {
|
||||
debug eq_different_thing => _15;
|
||||
let _18: bool;
|
||||
scope 6 {
|
||||
debug eq_optimize => _18;
|
||||
let _21: bool;
|
||||
scope 7 {
|
||||
debug eq_thin_fat => _21;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_5);
|
||||
+ nop;
|
||||
StorageLive(_6);
|
||||
_6 = _1;
|
||||
- _5 = move _6 as *const u32 (PtrToPtr);
|
||||
+ _5 = _1 as *const u32 (PtrToPtr);
|
||||
StorageDead(_6);
|
||||
StorageLive(_7);
|
||||
- StorageLive(_8);
|
||||
+ nop;
|
||||
StorageLive(_9);
|
||||
_9 = _2;
|
||||
- _8 = move _9 as *const u32 (PtrToPtr);
|
||||
+ _8 = _2 as *const u32 (PtrToPtr);
|
||||
StorageDead(_9);
|
||||
- _7 = move _8 as *const u32 (PtrToPtr);
|
||||
- StorageDead(_8);
|
||||
+ _7 = _8;
|
||||
+ nop;
|
||||
StorageLive(_10);
|
||||
- StorageLive(_11);
|
||||
+ nop;
|
||||
StorageLive(_12);
|
||||
_12 = _3;
|
||||
- _11 = move _12 as *const u32 (PtrToPtr);
|
||||
+ _11 = _3 as *const u32 (PtrToPtr);
|
||||
StorageDead(_12);
|
||||
- _10 = move _11 as *const u32 (PtrToPtr);
|
||||
- StorageDead(_11);
|
||||
- StorageLive(_13);
|
||||
+ _10 = _11;
|
||||
+ nop;
|
||||
+ nop;
|
||||
StorageLive(_14);
|
||||
_14 = _4;
|
||||
- _13 = move _14 as *const u32 (PtrToPtr);
|
||||
+ _13 = _4 as *const u32 (PtrToPtr);
|
||||
StorageDead(_14);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
_16 = _5;
|
||||
StorageLive(_17);
|
||||
- _17 = _7;
|
||||
- _15 = Eq(move _16, move _17);
|
||||
+ _17 = _8;
|
||||
+ _15 = Eq(_5, _8);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
- _19 = _7;
|
||||
+ _19 = _8;
|
||||
StorageLive(_20);
|
||||
- _20 = _10;
|
||||
- _18 = Eq(move _19, move _20);
|
||||
+ _20 = _11;
|
||||
+ _18 = Eq(_2, _3);
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageLive(_21);
|
||||
StorageLive(_22);
|
||||
- _22 = _10;
|
||||
+ _22 = _11;
|
||||
StorageLive(_23);
|
||||
_23 = _13;
|
||||
- _21 = Eq(move _22, move _23);
|
||||
+ _21 = Eq(_11, _13);
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
_0 = const ();
|
||||
StorageDead(_21);
|
||||
StorageDead(_18);
|
||||
StorageDead(_15);
|
||||
- StorageDead(_13);
|
||||
+ nop;
|
||||
StorageDead(_10);
|
||||
StorageDead(_7);
|
||||
- StorageDead(_5);
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -883,6 +883,36 @@ fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A,
|
||||
}
|
||||
}
|
||||
|
||||
fn cast_pointer_eq(p1: *mut u8, p2: *mut u32, p3: *mut u32, p4: *mut [u32]) {
|
||||
// CHECK-LABEL: fn cast_pointer_eq
|
||||
// CHECK: debug p1 => [[P1:_1]];
|
||||
// CHECK: debug p2 => [[P2:_2]];
|
||||
// CHECK: debug p3 => [[P3:_3]];
|
||||
// CHECK: debug p4 => [[P4:_4]];
|
||||
|
||||
// CHECK: [[M1:_.+]] = [[P1]] as *const u32 (PtrToPtr);
|
||||
// CHECK: [[M2:_.+]] = [[P2]] as *const u32 (PtrToPtr);
|
||||
// CHECK: [[M3:_.+]] = [[P3]] as *const u32 (PtrToPtr);
|
||||
// CHECK: [[M4:_.+]] = [[P4]] as *const u32 (PtrToPtr);
|
||||
let m1 = p1 as *const u32;
|
||||
let m2 = p2 as *const u32;
|
||||
let m3 = p3 as *const u32;
|
||||
let m4 = p4 as *const u32;
|
||||
|
||||
// CHECK-NOT: Eq
|
||||
// CHECK: Eq([[M1]], [[M2]])
|
||||
// CHECK-NOT: Eq
|
||||
// CHECK: Eq([[P2]], [[P3]])
|
||||
// CHECK-NOT: Eq
|
||||
// CHECK: Eq([[M3]], [[M4]])
|
||||
// CHECK-NOT: Eq
|
||||
let eq_different_thing = m1 == m2;
|
||||
let eq_optimize = m2 == m3;
|
||||
let eq_thin_fat = m3 == m4;
|
||||
|
||||
// CHECK: _0 = const ();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
subexpression_elimination(2, 4, 5);
|
||||
wrap_unwrap(5);
|
||||
@ -950,3 +980,4 @@ fn identity<T>(x: T) -> T {
|
||||
// EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
|
||||
// EMIT_MIR gvn.array_len.GVN.diff
|
||||
// EMIT_MIR gvn.generic_cast_metadata.GVN.diff
|
||||
// EMIT_MIR gvn.cast_pointer_eq.GVN.diff
|
||||
|
@ -6,27 +6,25 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
|
||||
scope 1 (inlined <std::slice::Iter<'_, T> as ExactSizeIterator>::is_empty) {
|
||||
let mut _2: *const *const T;
|
||||
let mut _3: *const std::ptr::NonNull<T>;
|
||||
let mut _10: *const T;
|
||||
let mut _8: *const T;
|
||||
scope 2 {
|
||||
let _4: std::ptr::NonNull<T>;
|
||||
let _12: usize;
|
||||
let _10: usize;
|
||||
scope 3 {
|
||||
}
|
||||
scope 4 {
|
||||
scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
|
||||
let mut _5: std::ptr::NonNull<T>;
|
||||
let mut _7: *mut T;
|
||||
let mut _9: *mut T;
|
||||
scope 9 (inlined NonNull::<T>::as_ptr) {
|
||||
let mut _6: *const T;
|
||||
}
|
||||
scope 10 (inlined NonNull::<T>::as_ptr) {
|
||||
let mut _8: *const T;
|
||||
let mut _7: *const T;
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 5 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
|
||||
let mut _11: *const ();
|
||||
let mut _9: *const ();
|
||||
scope 6 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
|
||||
}
|
||||
}
|
||||
@ -36,7 +34,7 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_12);
|
||||
StorageLive(_10);
|
||||
StorageLive(_4);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
@ -49,40 +47,34 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
|
||||
StorageDead(_2);
|
||||
_4 = (*_3);
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_5);
|
||||
_5 = ((*_1).0: std::ptr::NonNull<T>);
|
||||
StorageLive(_6);
|
||||
_6 = (_5.0: *const T);
|
||||
_7 = move _6 as *mut T (PtrToPtr);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_9);
|
||||
StorageLive(_8);
|
||||
_8 = (_4.0: *const T);
|
||||
_9 = move _8 as *mut T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
_0 = Eq(move _7, move _9);
|
||||
StorageDead(_9);
|
||||
_7 = (_4.0: *const T);
|
||||
_0 = Eq(_6, _7);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_10);
|
||||
_10 = ((*_1).1: *const T);
|
||||
StorageLive(_11);
|
||||
_11 = _10 as *const () (PtrToPtr);
|
||||
_12 = move _11 as usize (Transmute);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = Eq(_12, const 0_usize);
|
||||
StorageLive(_8);
|
||||
_8 = ((*_1).1: *const T);
|
||||
StorageLive(_9);
|
||||
_9 = _8 as *const () (PtrToPtr);
|
||||
_10 = move _9 as usize (Transmute);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
_0 = Eq(_10, const 0_usize);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_12);
|
||||
StorageDead(_10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -6,27 +6,25 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
|
||||
scope 1 (inlined <std::slice::Iter<'_, T> as ExactSizeIterator>::is_empty) {
|
||||
let mut _2: *const *const T;
|
||||
let mut _3: *const std::ptr::NonNull<T>;
|
||||
let mut _10: *const T;
|
||||
let mut _8: *const T;
|
||||
scope 2 {
|
||||
let _4: std::ptr::NonNull<T>;
|
||||
let _12: usize;
|
||||
let _10: usize;
|
||||
scope 3 {
|
||||
}
|
||||
scope 4 {
|
||||
scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
|
||||
let mut _5: std::ptr::NonNull<T>;
|
||||
let mut _7: *mut T;
|
||||
let mut _9: *mut T;
|
||||
scope 9 (inlined NonNull::<T>::as_ptr) {
|
||||
let mut _6: *const T;
|
||||
}
|
||||
scope 10 (inlined NonNull::<T>::as_ptr) {
|
||||
let mut _8: *const T;
|
||||
let mut _7: *const T;
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 5 (inlined std::ptr::const_ptr::<impl *const T>::addr) {
|
||||
let mut _11: *const ();
|
||||
let mut _9: *const ();
|
||||
scope 6 (inlined std::ptr::const_ptr::<impl *const T>::cast::<()>) {
|
||||
}
|
||||
}
|
||||
@ -36,7 +34,7 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_12);
|
||||
StorageLive(_10);
|
||||
StorageLive(_4);
|
||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
@ -49,40 +47,34 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
|
||||
StorageDead(_2);
|
||||
_4 = (*_3);
|
||||
StorageDead(_3);
|
||||
StorageLive(_6);
|
||||
StorageLive(_7);
|
||||
StorageLive(_5);
|
||||
_5 = ((*_1).0: std::ptr::NonNull<T>);
|
||||
StorageLive(_6);
|
||||
_6 = (_5.0: *const T);
|
||||
_7 = move _6 as *mut T (PtrToPtr);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_9);
|
||||
StorageLive(_8);
|
||||
_8 = (_4.0: *const T);
|
||||
_9 = move _8 as *mut T (PtrToPtr);
|
||||
StorageDead(_8);
|
||||
_0 = Eq(move _7, move _9);
|
||||
StorageDead(_9);
|
||||
_7 = (_4.0: *const T);
|
||||
_0 = Eq(_6, _7);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_10);
|
||||
_10 = ((*_1).1: *const T);
|
||||
StorageLive(_11);
|
||||
_11 = _10 as *const () (PtrToPtr);
|
||||
_12 = move _11 as usize (Transmute);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
_0 = Eq(_12, const 0_usize);
|
||||
StorageLive(_8);
|
||||
_8 = ((*_1).1: *const T);
|
||||
StorageLive(_9);
|
||||
_9 = _8 as *const () (PtrToPtr);
|
||||
_10 = move _9 as usize (Transmute);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
_0 = Eq(_10, const 0_usize);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_12);
|
||||
StorageDead(_10);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user