mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
FileCheck gvn.
This commit is contained in:
parent
50559ceec4
commit
ac0228da59
@ -1,133 +0,0 @@
|
||||
- // MIR for `aggregates` before GVN
|
||||
+ // MIR for `aggregates` after GVN
|
||||
|
||||
fn aggregates() -> () {
|
||||
let mut _0: ();
|
||||
let _1: S<[u8; 0]>;
|
||||
let mut _2: [u8; 0];
|
||||
let mut _4: [u16; 0];
|
||||
let mut _6: ();
|
||||
let mut _8: ();
|
||||
let mut _11: i32;
|
||||
let mut _12: i32;
|
||||
let mut _13: i32;
|
||||
let mut _14: i32;
|
||||
let mut _15: i32;
|
||||
let mut _16: i32;
|
||||
let mut _17: i32;
|
||||
let mut _18: i32;
|
||||
let mut _19: i32;
|
||||
let mut _20: i32;
|
||||
scope 1 {
|
||||
debug a_array => _1;
|
||||
let _3: S<[u16; 0]>;
|
||||
scope 2 {
|
||||
debug b_array => _3;
|
||||
let _5: S<()>;
|
||||
scope 3 {
|
||||
debug a_tuple => _5;
|
||||
let _7: S<()>;
|
||||
scope 4 {
|
||||
debug b_tuple => _7;
|
||||
let _9: i32;
|
||||
scope 5 {
|
||||
debug val => _9;
|
||||
let _10: [i32; 10];
|
||||
scope 6 {
|
||||
debug array => _10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- _2 = [];
|
||||
- _1 = S::<[u8; 0]>(move _2);
|
||||
+ _2 = const [];
|
||||
+ _1 = const S::<[u8; 0]>([]);
|
||||
StorageDead(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
- _4 = [];
|
||||
- _3 = S::<[u16; 0]>(move _4);
|
||||
+ _4 = const [];
|
||||
+ _3 = const S::<[u16; 0]>([]);
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
- StorageLive(_6);
|
||||
- _6 = ();
|
||||
- _5 = S::<()>(move _6);
|
||||
- StorageDead(_6);
|
||||
+ nop;
|
||||
+ _6 = const ();
|
||||
+ _5 = const S::<()>(());
|
||||
+ nop;
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
- _8 = ();
|
||||
- _7 = S::<()>(move _8);
|
||||
+ _8 = const ();
|
||||
+ _7 = const S::<()>(());
|
||||
StorageDead(_8);
|
||||
- StorageLive(_9);
|
||||
+ nop;
|
||||
_9 = const 5_i32;
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
- _11 = _9;
|
||||
+ _11 = const 5_i32;
|
||||
StorageLive(_12);
|
||||
- _12 = _9;
|
||||
+ _12 = const 5_i32;
|
||||
StorageLive(_13);
|
||||
- _13 = _9;
|
||||
+ _13 = const 5_i32;
|
||||
StorageLive(_14);
|
||||
- _14 = _9;
|
||||
+ _14 = const 5_i32;
|
||||
StorageLive(_15);
|
||||
- _15 = _9;
|
||||
+ _15 = const 5_i32;
|
||||
StorageLive(_16);
|
||||
- _16 = _9;
|
||||
+ _16 = const 5_i32;
|
||||
StorageLive(_17);
|
||||
- _17 = _9;
|
||||
+ _17 = const 5_i32;
|
||||
StorageLive(_18);
|
||||
- _18 = _9;
|
||||
+ _18 = const 5_i32;
|
||||
StorageLive(_19);
|
||||
- _19 = _9;
|
||||
+ _19 = const 5_i32;
|
||||
StorageLive(_20);
|
||||
- _20 = _9;
|
||||
- _10 = [move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20];
|
||||
+ _20 = const 5_i32;
|
||||
+ _10 = [const 5_i32; 10];
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
_0 = const ();
|
||||
StorageDead(_10);
|
||||
- StorageDead(_9);
|
||||
+ nop;
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,133 +0,0 @@
|
||||
- // MIR for `aggregates` before GVN
|
||||
+ // MIR for `aggregates` after GVN
|
||||
|
||||
fn aggregates() -> () {
|
||||
let mut _0: ();
|
||||
let _1: S<[u8; 0]>;
|
||||
let mut _2: [u8; 0];
|
||||
let mut _4: [u16; 0];
|
||||
let mut _6: ();
|
||||
let mut _8: ();
|
||||
let mut _11: i32;
|
||||
let mut _12: i32;
|
||||
let mut _13: i32;
|
||||
let mut _14: i32;
|
||||
let mut _15: i32;
|
||||
let mut _16: i32;
|
||||
let mut _17: i32;
|
||||
let mut _18: i32;
|
||||
let mut _19: i32;
|
||||
let mut _20: i32;
|
||||
scope 1 {
|
||||
debug a_array => _1;
|
||||
let _3: S<[u16; 0]>;
|
||||
scope 2 {
|
||||
debug b_array => _3;
|
||||
let _5: S<()>;
|
||||
scope 3 {
|
||||
debug a_tuple => _5;
|
||||
let _7: S<()>;
|
||||
scope 4 {
|
||||
debug b_tuple => _7;
|
||||
let _9: i32;
|
||||
scope 5 {
|
||||
debug val => _9;
|
||||
let _10: [i32; 10];
|
||||
scope 6 {
|
||||
debug array => _10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
- _2 = [];
|
||||
- _1 = S::<[u8; 0]>(move _2);
|
||||
+ _2 = const [];
|
||||
+ _1 = const S::<[u8; 0]>([]);
|
||||
StorageDead(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
- _4 = [];
|
||||
- _3 = S::<[u16; 0]>(move _4);
|
||||
+ _4 = const [];
|
||||
+ _3 = const S::<[u16; 0]>([]);
|
||||
StorageDead(_4);
|
||||
StorageLive(_5);
|
||||
- StorageLive(_6);
|
||||
- _6 = ();
|
||||
- _5 = S::<()>(move _6);
|
||||
- StorageDead(_6);
|
||||
+ nop;
|
||||
+ _6 = const ();
|
||||
+ _5 = const S::<()>(());
|
||||
+ nop;
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
- _8 = ();
|
||||
- _7 = S::<()>(move _8);
|
||||
+ _8 = const ();
|
||||
+ _7 = const S::<()>(());
|
||||
StorageDead(_8);
|
||||
- StorageLive(_9);
|
||||
+ nop;
|
||||
_9 = const 5_i32;
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
- _11 = _9;
|
||||
+ _11 = const 5_i32;
|
||||
StorageLive(_12);
|
||||
- _12 = _9;
|
||||
+ _12 = const 5_i32;
|
||||
StorageLive(_13);
|
||||
- _13 = _9;
|
||||
+ _13 = const 5_i32;
|
||||
StorageLive(_14);
|
||||
- _14 = _9;
|
||||
+ _14 = const 5_i32;
|
||||
StorageLive(_15);
|
||||
- _15 = _9;
|
||||
+ _15 = const 5_i32;
|
||||
StorageLive(_16);
|
||||
- _16 = _9;
|
||||
+ _16 = const 5_i32;
|
||||
StorageLive(_17);
|
||||
- _17 = _9;
|
||||
+ _17 = const 5_i32;
|
||||
StorageLive(_18);
|
||||
- _18 = _9;
|
||||
+ _18 = const 5_i32;
|
||||
StorageLive(_19);
|
||||
- _19 = _9;
|
||||
+ _19 = const 5_i32;
|
||||
StorageLive(_20);
|
||||
- _20 = _9;
|
||||
- _10 = [move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20];
|
||||
+ _20 = const 5_i32;
|
||||
+ _10 = [const 5_i32; 10];
|
||||
StorageDead(_20);
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
_0 = const ();
|
||||
StorageDead(_10);
|
||||
- StorageDead(_9);
|
||||
+ nop;
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageDead(_3);
|
||||
StorageDead(_1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -20,57 +20,6 @@
|
||||
let mut _15: u64;
|
||||
let mut _16: u64;
|
||||
let mut _17: (u64, bool);
|
||||
let _18: ();
|
||||
let mut _19: u64;
|
||||
let mut _20: u64;
|
||||
let mut _21: bool;
|
||||
let _22: ();
|
||||
let mut _23: u64;
|
||||
let mut _24: u64;
|
||||
let mut _25: bool;
|
||||
let _26: ();
|
||||
let mut _27: u64;
|
||||
let mut _28: u64;
|
||||
let mut _29: bool;
|
||||
let _30: ();
|
||||
let mut _31: u64;
|
||||
let mut _32: u64;
|
||||
let mut _33: bool;
|
||||
let _34: ();
|
||||
let mut _35: u64;
|
||||
let mut _36: u64;
|
||||
let mut _37: bool;
|
||||
let _38: ();
|
||||
let mut _39: u64;
|
||||
let mut _40: u64;
|
||||
let mut _41: bool;
|
||||
let _42: ();
|
||||
let mut _43: u64;
|
||||
let mut _44: u64;
|
||||
let mut _45: bool;
|
||||
let _46: ();
|
||||
let mut _47: u64;
|
||||
let mut _48: u64;
|
||||
let mut _49: bool;
|
||||
let _50: ();
|
||||
let mut _51: u64;
|
||||
let mut _52: u64;
|
||||
let _53: ();
|
||||
let mut _54: u64;
|
||||
let mut _55: u64;
|
||||
let _56: ();
|
||||
let mut _57: u64;
|
||||
let mut _58: u64;
|
||||
let _59: ();
|
||||
let mut _60: u64;
|
||||
let mut _61: u64;
|
||||
let mut _62: u32;
|
||||
let mut _63: bool;
|
||||
let _64: ();
|
||||
let mut _65: u64;
|
||||
let mut _66: u64;
|
||||
let mut _67: u32;
|
||||
let mut _68: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
@ -149,249 +98,6 @@
|
||||
bb8: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
_20 = _1;
|
||||
- _21 = Eq(const 0_u64, const 0_u64);
|
||||
- assert(!move _21, "attempt to divide `{}` by zero", _20) -> [success: bb9, unwind unreachable];
|
||||
+ _21 = const true;
|
||||
+ assert(!const true, "attempt to divide `{}` by zero", _1) -> [success: bb9, unwind unreachable];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
- _19 = Div(move _20, const 0_u64);
|
||||
+ _19 = Div(_1, const 0_u64);
|
||||
StorageDead(_20);
|
||||
_18 = opaque::<u64>(move _19) -> [return: bb10, unwind unreachable];
|
||||
}
|
||||
|
||||
bb10: {
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
StorageLive(_24);
|
||||
_24 = _1;
|
||||
- _25 = Eq(const 1_u64, const 0_u64);
|
||||
- assert(!move _25, "attempt to divide `{}` by zero", _24) -> [success: bb11, unwind unreachable];
|
||||
+ _25 = const false;
|
||||
+ assert(!const false, "attempt to divide `{}` by zero", _1) -> [success: bb11, unwind unreachable];
|
||||
}
|
||||
|
||||
bb11: {
|
||||
- _23 = Div(move _24, const 1_u64);
|
||||
+ _23 = Div(_1, const 1_u64);
|
||||
StorageDead(_24);
|
||||
_22 = opaque::<u64>(move _23) -> [return: bb12, unwind unreachable];
|
||||
}
|
||||
|
||||
bb12: {
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
StorageLive(_26);
|
||||
StorageLive(_27);
|
||||
StorageLive(_28);
|
||||
_28 = _1;
|
||||
- _29 = Eq(_28, const 0_u64);
|
||||
- assert(!move _29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind unreachable];
|
||||
+ _29 = Eq(_1, const 0_u64);
|
||||
+ assert(!_29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind unreachable];
|
||||
}
|
||||
|
||||
bb13: {
|
||||
- _27 = Div(const 0_u64, move _28);
|
||||
+ _27 = Div(const 0_u64, _1);
|
||||
StorageDead(_28);
|
||||
_26 = opaque::<u64>(move _27) -> [return: bb14, unwind unreachable];
|
||||
}
|
||||
|
||||
bb14: {
|
||||
StorageDead(_27);
|
||||
StorageDead(_26);
|
||||
StorageLive(_30);
|
||||
StorageLive(_31);
|
||||
StorageLive(_32);
|
||||
_32 = _1;
|
||||
- _33 = Eq(_32, const 0_u64);
|
||||
- assert(!move _33, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind unreachable];
|
||||
+ _33 = _29;
|
||||
+ assert(!_29, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind unreachable];
|
||||
}
|
||||
|
||||
bb15: {
|
||||
- _31 = Div(const 1_u64, move _32);
|
||||
+ _31 = Div(const 1_u64, _1);
|
||||
StorageDead(_32);
|
||||
_30 = opaque::<u64>(move _31) -> [return: bb16, unwind unreachable];
|
||||
}
|
||||
|
||||
bb16: {
|
||||
StorageDead(_31);
|
||||
StorageDead(_30);
|
||||
StorageLive(_34);
|
||||
StorageLive(_35);
|
||||
StorageLive(_36);
|
||||
_36 = _1;
|
||||
- _37 = Eq(const 0_u64, const 0_u64);
|
||||
- assert(!move _37, "attempt to calculate the remainder of `{}` with a divisor of zero", _36) -> [success: bb17, unwind unreachable];
|
||||
+ _37 = const true;
|
||||
+ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb17, unwind unreachable];
|
||||
}
|
||||
|
||||
bb17: {
|
||||
- _35 = Rem(move _36, const 0_u64);
|
||||
+ _35 = Rem(_1, const 0_u64);
|
||||
StorageDead(_36);
|
||||
_34 = opaque::<u64>(move _35) -> [return: bb18, unwind unreachable];
|
||||
}
|
||||
|
||||
bb18: {
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
StorageLive(_38);
|
||||
StorageLive(_39);
|
||||
StorageLive(_40);
|
||||
_40 = _1;
|
||||
- _41 = Eq(const 1_u64, const 0_u64);
|
||||
- assert(!move _41, "attempt to calculate the remainder of `{}` with a divisor of zero", _40) -> [success: bb19, unwind unreachable];
|
||||
+ _41 = const false;
|
||||
+ assert(!const false, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb19, unwind unreachable];
|
||||
}
|
||||
|
||||
bb19: {
|
||||
- _39 = Rem(move _40, const 1_u64);
|
||||
+ _39 = Rem(_1, const 1_u64);
|
||||
StorageDead(_40);
|
||||
_38 = opaque::<u64>(move _39) -> [return: bb20, unwind unreachable];
|
||||
}
|
||||
|
||||
bb20: {
|
||||
StorageDead(_39);
|
||||
StorageDead(_38);
|
||||
StorageLive(_42);
|
||||
StorageLive(_43);
|
||||
StorageLive(_44);
|
||||
_44 = _1;
|
||||
- _45 = Eq(_44, const 0_u64);
|
||||
- assert(!move _45, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind unreachable];
|
||||
+ _45 = _29;
|
||||
+ assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind unreachable];
|
||||
}
|
||||
|
||||
bb21: {
|
||||
- _43 = Rem(const 0_u64, move _44);
|
||||
+ _43 = Rem(const 0_u64, _1);
|
||||
StorageDead(_44);
|
||||
_42 = opaque::<u64>(move _43) -> [return: bb22, unwind unreachable];
|
||||
}
|
||||
|
||||
bb22: {
|
||||
StorageDead(_43);
|
||||
StorageDead(_42);
|
||||
StorageLive(_46);
|
||||
StorageLive(_47);
|
||||
StorageLive(_48);
|
||||
_48 = _1;
|
||||
- _49 = Eq(_48, const 0_u64);
|
||||
- assert(!move _49, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind unreachable];
|
||||
+ _49 = _29;
|
||||
+ assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind unreachable];
|
||||
}
|
||||
|
||||
bb23: {
|
||||
- _47 = Rem(const 1_u64, move _48);
|
||||
+ _47 = Rem(const 1_u64, _1);
|
||||
StorageDead(_48);
|
||||
_46 = opaque::<u64>(move _47) -> [return: bb24, unwind unreachable];
|
||||
}
|
||||
|
||||
bb24: {
|
||||
StorageDead(_47);
|
||||
StorageDead(_46);
|
||||
StorageLive(_50);
|
||||
StorageLive(_51);
|
||||
StorageLive(_52);
|
||||
_52 = _1;
|
||||
- _51 = BitAnd(move _52, const 0_u64);
|
||||
+ _51 = BitAnd(_1, const 0_u64);
|
||||
StorageDead(_52);
|
||||
_50 = opaque::<u64>(move _51) -> [return: bb25, unwind unreachable];
|
||||
}
|
||||
|
||||
bb25: {
|
||||
StorageDead(_51);
|
||||
StorageDead(_50);
|
||||
StorageLive(_53);
|
||||
StorageLive(_54);
|
||||
StorageLive(_55);
|
||||
_55 = _1;
|
||||
- _54 = BitOr(move _55, const 0_u64);
|
||||
+ _54 = BitOr(_1, const 0_u64);
|
||||
StorageDead(_55);
|
||||
_53 = opaque::<u64>(move _54) -> [return: bb26, unwind unreachable];
|
||||
}
|
||||
|
||||
bb26: {
|
||||
StorageDead(_54);
|
||||
StorageDead(_53);
|
||||
StorageLive(_56);
|
||||
StorageLive(_57);
|
||||
StorageLive(_58);
|
||||
_58 = _1;
|
||||
- _57 = BitXor(move _58, const 0_u64);
|
||||
+ _57 = BitXor(_1, const 0_u64);
|
||||
StorageDead(_58);
|
||||
_56 = opaque::<u64>(move _57) -> [return: bb27, unwind unreachable];
|
||||
}
|
||||
|
||||
bb27: {
|
||||
StorageDead(_57);
|
||||
StorageDead(_56);
|
||||
StorageLive(_59);
|
||||
StorageLive(_60);
|
||||
StorageLive(_61);
|
||||
_61 = _1;
|
||||
- _62 = const 0_i32 as u32 (IntToInt);
|
||||
- _63 = Lt(move _62, const 64_u32);
|
||||
- assert(move _63, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind unreachable];
|
||||
+ _62 = const 0_u32;
|
||||
+ _63 = const true;
|
||||
+ assert(const true, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind unreachable];
|
||||
}
|
||||
|
||||
bb28: {
|
||||
- _60 = Shr(move _61, const 0_i32);
|
||||
+ _60 = Shr(_1, const 0_i32);
|
||||
StorageDead(_61);
|
||||
_59 = opaque::<u64>(move _60) -> [return: bb29, unwind unreachable];
|
||||
}
|
||||
|
||||
bb29: {
|
||||
StorageDead(_60);
|
||||
StorageDead(_59);
|
||||
StorageLive(_64);
|
||||
StorageLive(_65);
|
||||
StorageLive(_66);
|
||||
_66 = _1;
|
||||
- _67 = const 0_i32 as u32 (IntToInt);
|
||||
- _68 = Lt(move _67, const 64_u32);
|
||||
- assert(move _68, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind unreachable];
|
||||
+ _67 = const 0_u32;
|
||||
+ _68 = const true;
|
||||
+ assert(const true, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind unreachable];
|
||||
}
|
||||
|
||||
bb30: {
|
||||
- _65 = Shl(move _66, const 0_i32);
|
||||
+ _65 = Shl(_1, const 0_i32);
|
||||
StorageDead(_66);
|
||||
_64 = opaque::<u64>(move _65) -> [return: bb31, unwind unreachable];
|
||||
}
|
||||
|
||||
bb31: {
|
||||
StorageDead(_65);
|
||||
StorageDead(_64);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
|
@ -20,57 +20,6 @@
|
||||
let mut _15: u64;
|
||||
let mut _16: u64;
|
||||
let mut _17: (u64, bool);
|
||||
let _18: ();
|
||||
let mut _19: u64;
|
||||
let mut _20: u64;
|
||||
let mut _21: bool;
|
||||
let _22: ();
|
||||
let mut _23: u64;
|
||||
let mut _24: u64;
|
||||
let mut _25: bool;
|
||||
let _26: ();
|
||||
let mut _27: u64;
|
||||
let mut _28: u64;
|
||||
let mut _29: bool;
|
||||
let _30: ();
|
||||
let mut _31: u64;
|
||||
let mut _32: u64;
|
||||
let mut _33: bool;
|
||||
let _34: ();
|
||||
let mut _35: u64;
|
||||
let mut _36: u64;
|
||||
let mut _37: bool;
|
||||
let _38: ();
|
||||
let mut _39: u64;
|
||||
let mut _40: u64;
|
||||
let mut _41: bool;
|
||||
let _42: ();
|
||||
let mut _43: u64;
|
||||
let mut _44: u64;
|
||||
let mut _45: bool;
|
||||
let _46: ();
|
||||
let mut _47: u64;
|
||||
let mut _48: u64;
|
||||
let mut _49: bool;
|
||||
let _50: ();
|
||||
let mut _51: u64;
|
||||
let mut _52: u64;
|
||||
let _53: ();
|
||||
let mut _54: u64;
|
||||
let mut _55: u64;
|
||||
let _56: ();
|
||||
let mut _57: u64;
|
||||
let mut _58: u64;
|
||||
let _59: ();
|
||||
let mut _60: u64;
|
||||
let mut _61: u64;
|
||||
let mut _62: u32;
|
||||
let mut _63: bool;
|
||||
let _64: ();
|
||||
let mut _65: u64;
|
||||
let mut _66: u64;
|
||||
let mut _67: u32;
|
||||
let mut _68: bool;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
@ -149,249 +98,6 @@
|
||||
bb8: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
StorageLive(_18);
|
||||
StorageLive(_19);
|
||||
StorageLive(_20);
|
||||
_20 = _1;
|
||||
- _21 = Eq(const 0_u64, const 0_u64);
|
||||
- assert(!move _21, "attempt to divide `{}` by zero", _20) -> [success: bb9, unwind continue];
|
||||
+ _21 = const true;
|
||||
+ assert(!const true, "attempt to divide `{}` by zero", _1) -> [success: bb9, unwind continue];
|
||||
}
|
||||
|
||||
bb9: {
|
||||
- _19 = Div(move _20, const 0_u64);
|
||||
+ _19 = Div(_1, const 0_u64);
|
||||
StorageDead(_20);
|
||||
_18 = opaque::<u64>(move _19) -> [return: bb10, unwind continue];
|
||||
}
|
||||
|
||||
bb10: {
|
||||
StorageDead(_19);
|
||||
StorageDead(_18);
|
||||
StorageLive(_22);
|
||||
StorageLive(_23);
|
||||
StorageLive(_24);
|
||||
_24 = _1;
|
||||
- _25 = Eq(const 1_u64, const 0_u64);
|
||||
- assert(!move _25, "attempt to divide `{}` by zero", _24) -> [success: bb11, unwind continue];
|
||||
+ _25 = const false;
|
||||
+ assert(!const false, "attempt to divide `{}` by zero", _1) -> [success: bb11, unwind continue];
|
||||
}
|
||||
|
||||
bb11: {
|
||||
- _23 = Div(move _24, const 1_u64);
|
||||
+ _23 = Div(_1, const 1_u64);
|
||||
StorageDead(_24);
|
||||
_22 = opaque::<u64>(move _23) -> [return: bb12, unwind continue];
|
||||
}
|
||||
|
||||
bb12: {
|
||||
StorageDead(_23);
|
||||
StorageDead(_22);
|
||||
StorageLive(_26);
|
||||
StorageLive(_27);
|
||||
StorageLive(_28);
|
||||
_28 = _1;
|
||||
- _29 = Eq(_28, const 0_u64);
|
||||
- assert(!move _29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind continue];
|
||||
+ _29 = Eq(_1, const 0_u64);
|
||||
+ assert(!_29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind continue];
|
||||
}
|
||||
|
||||
bb13: {
|
||||
- _27 = Div(const 0_u64, move _28);
|
||||
+ _27 = Div(const 0_u64, _1);
|
||||
StorageDead(_28);
|
||||
_26 = opaque::<u64>(move _27) -> [return: bb14, unwind continue];
|
||||
}
|
||||
|
||||
bb14: {
|
||||
StorageDead(_27);
|
||||
StorageDead(_26);
|
||||
StorageLive(_30);
|
||||
StorageLive(_31);
|
||||
StorageLive(_32);
|
||||
_32 = _1;
|
||||
- _33 = Eq(_32, const 0_u64);
|
||||
- assert(!move _33, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind continue];
|
||||
+ _33 = _29;
|
||||
+ assert(!_29, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind continue];
|
||||
}
|
||||
|
||||
bb15: {
|
||||
- _31 = Div(const 1_u64, move _32);
|
||||
+ _31 = Div(const 1_u64, _1);
|
||||
StorageDead(_32);
|
||||
_30 = opaque::<u64>(move _31) -> [return: bb16, unwind continue];
|
||||
}
|
||||
|
||||
bb16: {
|
||||
StorageDead(_31);
|
||||
StorageDead(_30);
|
||||
StorageLive(_34);
|
||||
StorageLive(_35);
|
||||
StorageLive(_36);
|
||||
_36 = _1;
|
||||
- _37 = Eq(const 0_u64, const 0_u64);
|
||||
- assert(!move _37, "attempt to calculate the remainder of `{}` with a divisor of zero", _36) -> [success: bb17, unwind continue];
|
||||
+ _37 = const true;
|
||||
+ assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb17, unwind continue];
|
||||
}
|
||||
|
||||
bb17: {
|
||||
- _35 = Rem(move _36, const 0_u64);
|
||||
+ _35 = Rem(_1, const 0_u64);
|
||||
StorageDead(_36);
|
||||
_34 = opaque::<u64>(move _35) -> [return: bb18, unwind continue];
|
||||
}
|
||||
|
||||
bb18: {
|
||||
StorageDead(_35);
|
||||
StorageDead(_34);
|
||||
StorageLive(_38);
|
||||
StorageLive(_39);
|
||||
StorageLive(_40);
|
||||
_40 = _1;
|
||||
- _41 = Eq(const 1_u64, const 0_u64);
|
||||
- assert(!move _41, "attempt to calculate the remainder of `{}` with a divisor of zero", _40) -> [success: bb19, unwind continue];
|
||||
+ _41 = const false;
|
||||
+ assert(!const false, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb19, unwind continue];
|
||||
}
|
||||
|
||||
bb19: {
|
||||
- _39 = Rem(move _40, const 1_u64);
|
||||
+ _39 = Rem(_1, const 1_u64);
|
||||
StorageDead(_40);
|
||||
_38 = opaque::<u64>(move _39) -> [return: bb20, unwind continue];
|
||||
}
|
||||
|
||||
bb20: {
|
||||
StorageDead(_39);
|
||||
StorageDead(_38);
|
||||
StorageLive(_42);
|
||||
StorageLive(_43);
|
||||
StorageLive(_44);
|
||||
_44 = _1;
|
||||
- _45 = Eq(_44, const 0_u64);
|
||||
- assert(!move _45, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind continue];
|
||||
+ _45 = _29;
|
||||
+ assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind continue];
|
||||
}
|
||||
|
||||
bb21: {
|
||||
- _43 = Rem(const 0_u64, move _44);
|
||||
+ _43 = Rem(const 0_u64, _1);
|
||||
StorageDead(_44);
|
||||
_42 = opaque::<u64>(move _43) -> [return: bb22, unwind continue];
|
||||
}
|
||||
|
||||
bb22: {
|
||||
StorageDead(_43);
|
||||
StorageDead(_42);
|
||||
StorageLive(_46);
|
||||
StorageLive(_47);
|
||||
StorageLive(_48);
|
||||
_48 = _1;
|
||||
- _49 = Eq(_48, const 0_u64);
|
||||
- assert(!move _49, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind continue];
|
||||
+ _49 = _29;
|
||||
+ assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind continue];
|
||||
}
|
||||
|
||||
bb23: {
|
||||
- _47 = Rem(const 1_u64, move _48);
|
||||
+ _47 = Rem(const 1_u64, _1);
|
||||
StorageDead(_48);
|
||||
_46 = opaque::<u64>(move _47) -> [return: bb24, unwind continue];
|
||||
}
|
||||
|
||||
bb24: {
|
||||
StorageDead(_47);
|
||||
StorageDead(_46);
|
||||
StorageLive(_50);
|
||||
StorageLive(_51);
|
||||
StorageLive(_52);
|
||||
_52 = _1;
|
||||
- _51 = BitAnd(move _52, const 0_u64);
|
||||
+ _51 = BitAnd(_1, const 0_u64);
|
||||
StorageDead(_52);
|
||||
_50 = opaque::<u64>(move _51) -> [return: bb25, unwind continue];
|
||||
}
|
||||
|
||||
bb25: {
|
||||
StorageDead(_51);
|
||||
StorageDead(_50);
|
||||
StorageLive(_53);
|
||||
StorageLive(_54);
|
||||
StorageLive(_55);
|
||||
_55 = _1;
|
||||
- _54 = BitOr(move _55, const 0_u64);
|
||||
+ _54 = BitOr(_1, const 0_u64);
|
||||
StorageDead(_55);
|
||||
_53 = opaque::<u64>(move _54) -> [return: bb26, unwind continue];
|
||||
}
|
||||
|
||||
bb26: {
|
||||
StorageDead(_54);
|
||||
StorageDead(_53);
|
||||
StorageLive(_56);
|
||||
StorageLive(_57);
|
||||
StorageLive(_58);
|
||||
_58 = _1;
|
||||
- _57 = BitXor(move _58, const 0_u64);
|
||||
+ _57 = BitXor(_1, const 0_u64);
|
||||
StorageDead(_58);
|
||||
_56 = opaque::<u64>(move _57) -> [return: bb27, unwind continue];
|
||||
}
|
||||
|
||||
bb27: {
|
||||
StorageDead(_57);
|
||||
StorageDead(_56);
|
||||
StorageLive(_59);
|
||||
StorageLive(_60);
|
||||
StorageLive(_61);
|
||||
_61 = _1;
|
||||
- _62 = const 0_i32 as u32 (IntToInt);
|
||||
- _63 = Lt(move _62, const 64_u32);
|
||||
- assert(move _63, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind continue];
|
||||
+ _62 = const 0_u32;
|
||||
+ _63 = const true;
|
||||
+ assert(const true, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind continue];
|
||||
}
|
||||
|
||||
bb28: {
|
||||
- _60 = Shr(move _61, const 0_i32);
|
||||
+ _60 = Shr(_1, const 0_i32);
|
||||
StorageDead(_61);
|
||||
_59 = opaque::<u64>(move _60) -> [return: bb29, unwind continue];
|
||||
}
|
||||
|
||||
bb29: {
|
||||
StorageDead(_60);
|
||||
StorageDead(_59);
|
||||
StorageLive(_64);
|
||||
StorageLive(_65);
|
||||
StorageLive(_66);
|
||||
_66 = _1;
|
||||
- _67 = const 0_i32 as u32 (IntToInt);
|
||||
- _68 = Lt(move _67, const 64_u32);
|
||||
- assert(move _68, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind continue];
|
||||
+ _67 = const 0_u32;
|
||||
+ _68 = const true;
|
||||
+ assert(const true, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind continue];
|
||||
}
|
||||
|
||||
bb30: {
|
||||
- _65 = Shl(move _66, const 0_i32);
|
||||
+ _65 = Shl(_1, const 0_i32);
|
||||
StorageDead(_66);
|
||||
_64 = opaque::<u64>(move _65) -> [return: bb31, unwind continue];
|
||||
}
|
||||
|
||||
bb31: {
|
||||
StorageDead(_65);
|
||||
StorageDead(_64);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
|
94
tests/mir-opt/gvn.comparison.GVN.panic-abort.diff
Normal file
94
tests/mir-opt/gvn.comparison.GVN.panic-abort.diff
Normal file
@ -0,0 +1,94 @@
|
||||
- // MIR for `comparison` before GVN
|
||||
+ // MIR for `comparison` after GVN
|
||||
|
||||
fn comparison(_1: u64, _2: u64) -> () {
|
||||
debug x => _1;
|
||||
debug y => _2;
|
||||
let mut _0: ();
|
||||
let _3: ();
|
||||
let mut _4: bool;
|
||||
let mut _5: u64;
|
||||
let mut _6: u64;
|
||||
let _7: ();
|
||||
let mut _8: bool;
|
||||
let mut _9: u64;
|
||||
let mut _10: u64;
|
||||
let _11: ();
|
||||
let mut _12: bool;
|
||||
let mut _13: u64;
|
||||
let mut _14: u64;
|
||||
let _15: ();
|
||||
let mut _16: bool;
|
||||
let mut _17: u64;
|
||||
let mut _18: u64;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = _1;
|
||||
StorageLive(_6);
|
||||
_6 = _1;
|
||||
- _4 = Eq(move _5, move _6);
|
||||
+ _4 = Eq(_1, _1);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
_3 = opaque::<bool>(move _4) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = _1;
|
||||
StorageLive(_10);
|
||||
_10 = _1;
|
||||
- _8 = Ne(move _9, move _10);
|
||||
+ _8 = Ne(_1, _1);
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
_7 = opaque::<bool>(move _8) -> [return: bb2, unwind unreachable];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_13 = _1;
|
||||
StorageLive(_14);
|
||||
_14 = _2;
|
||||
- _12 = Eq(move _13, move _14);
|
||||
+ _12 = Eq(_1, _2);
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
_11 = opaque::<bool>(move _12) -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
StorageLive(_17);
|
||||
_17 = _1;
|
||||
StorageLive(_18);
|
||||
_18 = _2;
|
||||
- _16 = Ne(move _17, move _18);
|
||||
+ _16 = Ne(_1, _2);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
_15 = opaque::<bool>(move _16) -> [return: bb4, unwind unreachable];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
94
tests/mir-opt/gvn.comparison.GVN.panic-unwind.diff
Normal file
94
tests/mir-opt/gvn.comparison.GVN.panic-unwind.diff
Normal file
@ -0,0 +1,94 @@
|
||||
- // MIR for `comparison` before GVN
|
||||
+ // MIR for `comparison` after GVN
|
||||
|
||||
fn comparison(_1: u64, _2: u64) -> () {
|
||||
debug x => _1;
|
||||
debug y => _2;
|
||||
let mut _0: ();
|
||||
let _3: ();
|
||||
let mut _4: bool;
|
||||
let mut _5: u64;
|
||||
let mut _6: u64;
|
||||
let _7: ();
|
||||
let mut _8: bool;
|
||||
let mut _9: u64;
|
||||
let mut _10: u64;
|
||||
let _11: ();
|
||||
let mut _12: bool;
|
||||
let mut _13: u64;
|
||||
let mut _14: u64;
|
||||
let _15: ();
|
||||
let mut _16: bool;
|
||||
let mut _17: u64;
|
||||
let mut _18: u64;
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = _1;
|
||||
StorageLive(_6);
|
||||
_6 = _1;
|
||||
- _4 = Eq(move _5, move _6);
|
||||
+ _4 = Eq(_1, _1);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
_3 = opaque::<bool>(move _4) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
StorageLive(_9);
|
||||
_9 = _1;
|
||||
StorageLive(_10);
|
||||
_10 = _1;
|
||||
- _8 = Ne(move _9, move _10);
|
||||
+ _8 = Ne(_1, _1);
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
_7 = opaque::<bool>(move _8) -> [return: bb2, unwind continue];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageLive(_11);
|
||||
StorageLive(_12);
|
||||
StorageLive(_13);
|
||||
_13 = _1;
|
||||
StorageLive(_14);
|
||||
_14 = _2;
|
||||
- _12 = Eq(move _13, move _14);
|
||||
+ _12 = Eq(_1, _2);
|
||||
StorageDead(_14);
|
||||
StorageDead(_13);
|
||||
_11 = opaque::<bool>(move _12) -> [return: bb3, unwind continue];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_15);
|
||||
StorageLive(_16);
|
||||
StorageLive(_17);
|
||||
_17 = _1;
|
||||
StorageLive(_18);
|
||||
_18 = _2;
|
||||
- _16 = Ne(move _17, move _18);
|
||||
+ _16 = Ne(_1, _2);
|
||||
StorageDead(_18);
|
||||
StorageDead(_17);
|
||||
_15 = opaque::<bool>(move _16) -> [return: bb4, unwind continue];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_16);
|
||||
StorageDead(_15);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
79
tests/mir-opt/gvn.repeat.GVN.panic-abort.diff
Normal file
79
tests/mir-opt/gvn.repeat.GVN.panic-abort.diff
Normal file
@ -0,0 +1,79 @@
|
||||
- // MIR for `repeat` before GVN
|
||||
+ // MIR for `repeat` after GVN
|
||||
|
||||
fn repeat() -> () {
|
||||
let mut _0: ();
|
||||
let _1: i32;
|
||||
let mut _3: i32;
|
||||
let mut _4: i32;
|
||||
let mut _5: i32;
|
||||
let mut _6: i32;
|
||||
let mut _7: i32;
|
||||
let mut _8: i32;
|
||||
let mut _9: i32;
|
||||
let mut _10: i32;
|
||||
let mut _11: i32;
|
||||
let mut _12: i32;
|
||||
scope 1 {
|
||||
debug val => _1;
|
||||
let _2: [i32; 10];
|
||||
scope 2 {
|
||||
debug array => _2;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_1);
|
||||
+ nop;
|
||||
_1 = const 5_i32;
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
+ _3 = const 5_i32;
|
||||
StorageLive(_4);
|
||||
- _4 = _1;
|
||||
+ _4 = const 5_i32;
|
||||
StorageLive(_5);
|
||||
- _5 = _1;
|
||||
+ _5 = const 5_i32;
|
||||
StorageLive(_6);
|
||||
- _6 = _1;
|
||||
+ _6 = const 5_i32;
|
||||
StorageLive(_7);
|
||||
- _7 = _1;
|
||||
+ _7 = const 5_i32;
|
||||
StorageLive(_8);
|
||||
- _8 = _1;
|
||||
+ _8 = const 5_i32;
|
||||
StorageLive(_9);
|
||||
- _9 = _1;
|
||||
+ _9 = const 5_i32;
|
||||
StorageLive(_10);
|
||||
- _10 = _1;
|
||||
+ _10 = const 5_i32;
|
||||
StorageLive(_11);
|
||||
- _11 = _1;
|
||||
+ _11 = const 5_i32;
|
||||
StorageLive(_12);
|
||||
- _12 = _1;
|
||||
- _2 = [move _3, move _4, move _5, move _6, move _7, move _8, move _9, move _10, move _11, move _12];
|
||||
+ _12 = const 5_i32;
|
||||
+ _2 = [const 5_i32; 10];
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
- StorageDead(_1);
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
79
tests/mir-opt/gvn.repeat.GVN.panic-unwind.diff
Normal file
79
tests/mir-opt/gvn.repeat.GVN.panic-unwind.diff
Normal file
@ -0,0 +1,79 @@
|
||||
- // MIR for `repeat` before GVN
|
||||
+ // MIR for `repeat` after GVN
|
||||
|
||||
fn repeat() -> () {
|
||||
let mut _0: ();
|
||||
let _1: i32;
|
||||
let mut _3: i32;
|
||||
let mut _4: i32;
|
||||
let mut _5: i32;
|
||||
let mut _6: i32;
|
||||
let mut _7: i32;
|
||||
let mut _8: i32;
|
||||
let mut _9: i32;
|
||||
let mut _10: i32;
|
||||
let mut _11: i32;
|
||||
let mut _12: i32;
|
||||
scope 1 {
|
||||
debug val => _1;
|
||||
let _2: [i32; 10];
|
||||
scope 2 {
|
||||
debug array => _2;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_1);
|
||||
+ nop;
|
||||
_1 = const 5_i32;
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = _1;
|
||||
+ _3 = const 5_i32;
|
||||
StorageLive(_4);
|
||||
- _4 = _1;
|
||||
+ _4 = const 5_i32;
|
||||
StorageLive(_5);
|
||||
- _5 = _1;
|
||||
+ _5 = const 5_i32;
|
||||
StorageLive(_6);
|
||||
- _6 = _1;
|
||||
+ _6 = const 5_i32;
|
||||
StorageLive(_7);
|
||||
- _7 = _1;
|
||||
+ _7 = const 5_i32;
|
||||
StorageLive(_8);
|
||||
- _8 = _1;
|
||||
+ _8 = const 5_i32;
|
||||
StorageLive(_9);
|
||||
- _9 = _1;
|
||||
+ _9 = const 5_i32;
|
||||
StorageLive(_10);
|
||||
- _10 = _1;
|
||||
+ _10 = const 5_i32;
|
||||
StorageLive(_11);
|
||||
- _11 = _1;
|
||||
+ _11 = const 5_i32;
|
||||
StorageLive(_12);
|
||||
- _12 = _1;
|
||||
- _2 = [move _3, move _4, move _5, move _6, move _7, move _8, move _9, move _10, move _11, move _12];
|
||||
+ _12 = const 5_i32;
|
||||
+ _2 = [const 5_i32; 10];
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageDead(_10);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_0 = const ();
|
||||
StorageDead(_2);
|
||||
- StorageDead(_1);
|
||||
+ nop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
// unit-test: GVN
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
// only-64bit
|
||||
@ -15,48 +14,120 @@ use std::mem::transmute;
|
||||
struct S<T>(T);
|
||||
|
||||
fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
|
||||
// CHECK-LABEL: fn subexpression_elimination(
|
||||
|
||||
// CHECK: [[add:_.*]] = Add(_1, _2);
|
||||
// CHECK: opaque::<u64>([[add]])
|
||||
opaque(x + y);
|
||||
// CHECK: [[mul:_.*]] = Mul(_1, _2);
|
||||
// CHECK: opaque::<u64>([[mul]])
|
||||
opaque(x * y);
|
||||
// CHECK: [[sub:_.*]] = Sub(_1, _2);
|
||||
// CHECK: opaque::<u64>([[sub]])
|
||||
opaque(x - y);
|
||||
// CHECK: [[div:_.*]] = Div(_1, _2);
|
||||
// CHECK: opaque::<u64>([[div]])
|
||||
opaque(x / y);
|
||||
// CHECK: [[rem:_.*]] = Rem(_1, _2);
|
||||
// CHECK: opaque::<u64>([[rem]])
|
||||
opaque(x % y);
|
||||
// CHECK: [[and:_.*]] = BitAnd(_1, _2);
|
||||
// CHECK: opaque::<u64>([[and]])
|
||||
opaque(x & y);
|
||||
// CHECK: [[or:_.*]] = BitOr(_1, _2);
|
||||
// CHECK: opaque::<u64>([[or]])
|
||||
opaque(x | y);
|
||||
// CHECK: [[xor:_.*]] = BitXor(_1, _2);
|
||||
// CHECK: opaque::<u64>([[xor]])
|
||||
opaque(x ^ y);
|
||||
// CHECK: [[shl:_.*]] = Shl(_1, _2);
|
||||
// CHECK: opaque::<u64>([[shl]])
|
||||
opaque(x << y);
|
||||
// CHECK: [[shr:_.*]] = Shr(_1, _2);
|
||||
// CHECK: opaque::<u64>([[shr]])
|
||||
opaque(x >> y);
|
||||
// CHECK: [[int:_.*]] = _1 as u32 (IntToInt);
|
||||
// CHECK: opaque::<u32>([[int]])
|
||||
opaque(x as u32);
|
||||
// CHECK: [[float:_.*]] = _1 as f32 (IntToFloat);
|
||||
// CHECK: opaque::<f32>([[float]])
|
||||
opaque(x as f32);
|
||||
// CHECK: [[wrap:_.*]] = S::<u64>(_1);
|
||||
// CHECK: opaque::<S<u64>>([[wrap]])
|
||||
opaque(S(x));
|
||||
// CHECK: opaque::<u64>(_1)
|
||||
opaque(S(x).0);
|
||||
|
||||
// Those are duplicates to substitute somehow.
|
||||
opaque((x + y) + z);
|
||||
opaque((x * y) + z);
|
||||
opaque((x - y) + z);
|
||||
opaque((x / y) + z);
|
||||
opaque((x % y) + z);
|
||||
opaque((x & y) + z);
|
||||
opaque((x | y) + z);
|
||||
opaque((x ^ y) + z);
|
||||
opaque((x << y) + z);
|
||||
opaque((x >> y) + z);
|
||||
// CHECK: opaque::<u64>([[add]])
|
||||
opaque(x + y);
|
||||
// CHECK: opaque::<u64>([[mul]])
|
||||
opaque(x * y);
|
||||
// CHECK: opaque::<u64>([[sub]])
|
||||
opaque(x - y);
|
||||
// CHECK: opaque::<u64>([[div]])
|
||||
opaque(x / y);
|
||||
// CHECK: opaque::<u64>([[rem]])
|
||||
opaque(x % y);
|
||||
// CHECK: opaque::<u64>([[and]])
|
||||
opaque(x & y);
|
||||
// CHECK: opaque::<u64>([[or]])
|
||||
opaque(x | y);
|
||||
// CHECK: opaque::<u64>([[xor]])
|
||||
opaque(x ^ y);
|
||||
// CHECK: opaque::<u64>([[shl]])
|
||||
opaque(x << y);
|
||||
// CHECK: opaque::<u64>([[shr]])
|
||||
opaque(x >> y);
|
||||
// CHECK: opaque::<u32>([[int]])
|
||||
opaque(x as u32);
|
||||
// CHECK: opaque::<f32>([[float]])
|
||||
opaque(x as f32);
|
||||
// CHECK: opaque::<S<u64>>([[wrap]])
|
||||
opaque(S(x));
|
||||
// CHECK: opaque::<u64>(_1)
|
||||
opaque(S(x).0);
|
||||
|
||||
// We can substitute through a complex expression.
|
||||
// CHECK: [[compound:_.*]] = Sub([[mul]], _2);
|
||||
// CHECK: opaque::<u64>([[compound]])
|
||||
// CHECK: opaque::<u64>([[compound]])
|
||||
opaque((x * y) - y);
|
||||
opaque((x * y) - y);
|
||||
|
||||
// We can substitute through an immutable reference too.
|
||||
// CHECK: [[ref:_.*]] = &_3;
|
||||
// CHECK: [[deref:_.*]] = (*[[ref]]);
|
||||
// CHECK: [[addref:_.*]] = Add([[deref]], _1);
|
||||
// CHECK: opaque::<u64>([[addref]])
|
||||
// CHECK: opaque::<u64>([[addref]])
|
||||
let a = &z;
|
||||
opaque(*a + x);
|
||||
opaque(*a + x);
|
||||
|
||||
// But not through a mutable reference or a pointer.
|
||||
// CHECK: [[mut:_.*]] = &mut _3;
|
||||
// CHECK: [[addmut:_.*]] = Add(
|
||||
// CHECK: opaque::<u64>(move [[addmut]])
|
||||
// CHECK: [[addmut2:_.*]] = Add(
|
||||
// CHECK: opaque::<u64>(move [[addmut2]])
|
||||
let b = &mut z;
|
||||
opaque(*b + x);
|
||||
opaque(*b + x);
|
||||
unsafe {
|
||||
// CHECK: [[raw:_.*]] = &raw const _3;
|
||||
// CHECK: [[addraw:_.*]] = Add(
|
||||
// CHECK: opaque::<u64>(move [[addraw]])
|
||||
// CHECK: [[addraw2:_.*]] = Add(
|
||||
// CHECK: opaque::<u64>(move [[addraw2]])
|
||||
let c = &raw const z;
|
||||
opaque(*c + x);
|
||||
opaque(*c + x);
|
||||
// CHECK: [[ptr:_.*]] = &raw mut _3;
|
||||
// CHECK: [[addptr:_.*]] = Add(
|
||||
// CHECK: opaque::<u64>(move [[addptr]])
|
||||
// CHECK: [[addptr2:_.*]] = Add(
|
||||
// CHECK: opaque::<u64>(move [[addptr2]])
|
||||
let d = &raw mut z;
|
||||
opaque(*d + x);
|
||||
opaque(*d + x);
|
||||
@ -64,12 +135,21 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
|
||||
|
||||
// We can substitute again, but not with the earlier computations.
|
||||
// Important: `e` is not `a`!
|
||||
// CHECK: [[ref2:_.*]] = &_3;
|
||||
// CHECK: [[deref2:_.*]] = (*[[ref2]]);
|
||||
// CHECK: [[addref2:_.*]] = Add([[deref2]], _1);
|
||||
// CHECK: opaque::<u64>([[addref2]])
|
||||
// CHECK: opaque::<u64>([[addref2]])
|
||||
let e = &z;
|
||||
opaque(*e + x);
|
||||
opaque(*e + x);
|
||||
}
|
||||
|
||||
fn wrap_unwrap<T: Copy>(x: T) -> T {
|
||||
// CHECK-LABEL: fn wrap_unwrap(
|
||||
// CHECK: [[some:_.*]] = Option::<T>::Some(_1);
|
||||
// CHECK: switchInt(const 1_isize)
|
||||
// CHECK: _0 = _1;
|
||||
match Some(x) {
|
||||
Some(y) => y,
|
||||
None => panic!(),
|
||||
@ -77,155 +157,354 @@ fn wrap_unwrap<T: Copy>(x: T) -> T {
|
||||
}
|
||||
|
||||
fn repeated_index<T: Copy, const N: usize>(x: T, idx: usize) {
|
||||
// CHECK-LABEL: fn repeated_index(
|
||||
// CHECK: [[a:_.*]] = [_1; N];
|
||||
let a = [x; N];
|
||||
// CHECK: opaque::<T>(_1)
|
||||
opaque(a[0]);
|
||||
// CHECK: opaque::<T>(_1)
|
||||
opaque(a[idx]);
|
||||
}
|
||||
|
||||
/// Verify symbolic integer arithmetic simplifications.
|
||||
fn arithmetic(x: u64) {
|
||||
// CHECK-LABEL: fn arithmetic(
|
||||
// CHECK: [[add:_.*]] = Add(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[add]])
|
||||
opaque(x + 0);
|
||||
// CHECK: [[sub:_.*]] = Sub(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[sub]])
|
||||
opaque(x - 0);
|
||||
// CHECK: [[mul0:_.*]] = Mul(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[mul0]])
|
||||
opaque(x * 0);
|
||||
// CHECK: [[mul1:_.*]] = Mul(_1, const 1_u64);
|
||||
// CHECK: opaque::<u64>(move [[mul1]])
|
||||
opaque(x * 1);
|
||||
// CHECK: [[div0:_.*]] = Div(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[div0]])
|
||||
opaque(x / 0);
|
||||
// CHECK: [[div1:_.*]] = Div(_1, const 1_u64);
|
||||
// CHECK: opaque::<u64>(move [[div1]])
|
||||
opaque(x / 1);
|
||||
// CHECK: [[zdiv:_.*]] = Div(const 0_u64, _1);
|
||||
// CHECK: opaque::<u64>(move [[zdiv]])
|
||||
opaque(0 / x);
|
||||
// CHECK: [[odiv:_.*]] = Div(const 1_u64, _1);
|
||||
// CHECK: opaque::<u64>(move [[odiv]])
|
||||
opaque(1 / x);
|
||||
// CHECK: [[rem0:_.*]] = Rem(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[rem0]])
|
||||
opaque(x % 0);
|
||||
// CHECK: [[rem1:_.*]] = Rem(_1, const 1_u64);
|
||||
// CHECK: opaque::<u64>(move [[rem1]])
|
||||
opaque(x % 1);
|
||||
// CHECK: [[zrem:_.*]] = Rem(const 0_u64, _1);
|
||||
// CHECK: opaque::<u64>(move [[zrem]])
|
||||
opaque(0 % x);
|
||||
// CHECK: [[orem:_.*]] = Rem(const 1_u64, _1);
|
||||
// CHECK: opaque::<u64>(move [[orem]])
|
||||
opaque(1 % x);
|
||||
// CHECK: [[and:_.*]] = BitAnd(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[and]])
|
||||
opaque(x & 0);
|
||||
// CHECK: [[or:_.*]] = BitOr(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[or]])
|
||||
opaque(x | 0);
|
||||
// CHECK: [[xor:_.*]] = BitXor(_1, const 0_u64);
|
||||
// CHECK: opaque::<u64>(move [[xor]])
|
||||
opaque(x ^ 0);
|
||||
// CHECK: [[shr:_.*]] = Shr(_1, const 0_i32);
|
||||
// CHECK: opaque::<u64>(move [[shr]])
|
||||
opaque(x >> 0);
|
||||
// CHECK: [[shl:_.*]] = Shl(_1, const 0_i32);
|
||||
// CHECK: opaque::<u64>(move [[shl]])
|
||||
opaque(x << 0);
|
||||
}
|
||||
|
||||
fn comparison(x: u64, y: u64) {
|
||||
// CHECK-LABEL: fn comparison(
|
||||
// CHECK: [[eqxx:_.*]] = Eq(_1, _1);
|
||||
// CHECK: opaque::<bool>(move [[eqxx]])
|
||||
opaque(x == x);
|
||||
// CHECK: [[nexx:_.*]] = Ne(_1, _1);
|
||||
// CHECK: opaque::<bool>(move [[nexx]])
|
||||
opaque(x != x);
|
||||
// CHECK: [[eqxy:_.*]] = Eq(_1, _2);
|
||||
// CHECK: opaque::<bool>(move [[eqxy]])
|
||||
opaque(x == y);
|
||||
// CHECK: [[nexy:_.*]] = Ne(_1, _2);
|
||||
// CHECK: opaque::<bool>(move [[nexy]])
|
||||
opaque(x != y);
|
||||
}
|
||||
|
||||
/// Verify symbolic integer arithmetic simplifications on checked ops.
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn arithmetic_checked(x: u64) {
|
||||
// CHECK-LABEL: fn arithmetic_checked(
|
||||
// CHECK: [[cadd:_.*]] = CheckedAdd(_1, const 0_u64);
|
||||
// CHECK: [[add:_.*]] = move ([[cadd]].0: u64);
|
||||
// CHECK: opaque::<u64>(move [[add]])
|
||||
opaque(x + 0);
|
||||
// CHECK: [[csub:_.*]] = CheckedSub(_1, const 0_u64);
|
||||
// CHECK: [[sub:_.*]] = move ([[csub]].0: u64);
|
||||
// CHECK: opaque::<u64>(move [[sub]])
|
||||
opaque(x - 0);
|
||||
// CHECK: [[cmul0:_.*]] = CheckedMul(_1, const 0_u64);
|
||||
// CHECK: [[mul0:_.*]] = move ([[cmul0]].0: u64);
|
||||
// CHECK: opaque::<u64>(move [[mul0]])
|
||||
opaque(x * 0);
|
||||
// CHECK: [[cmul1:_.*]] = CheckedMul(_1, const 1_u64);
|
||||
// CHECK: [[mul1:_.*]] = move ([[cmul1]].0: u64);
|
||||
// CHECK: opaque::<u64>(move [[mul1]])
|
||||
opaque(x * 1);
|
||||
opaque(x / 0);
|
||||
opaque(x / 1);
|
||||
opaque(0 / x);
|
||||
opaque(1 / x);
|
||||
opaque(x % 0);
|
||||
opaque(x % 1);
|
||||
opaque(0 % x);
|
||||
opaque(1 % x);
|
||||
opaque(x & 0);
|
||||
opaque(x | 0);
|
||||
opaque(x ^ 0);
|
||||
opaque(x >> 0);
|
||||
opaque(x << 0);
|
||||
}
|
||||
|
||||
/// Verify that we do not apply arithmetic simplifications on floats.
|
||||
fn arithmetic_float(x: f64) {
|
||||
// CHECK-LABEL: fn arithmetic_float(
|
||||
// CHECK: [[add:_.*]] = Add(_1, const 0f64);
|
||||
// CHECK: opaque::<f64>(move [[add]])
|
||||
opaque(x + 0.);
|
||||
// CHECK: [[sub:_.*]] = Sub(_1, const 0f64);
|
||||
// CHECK: opaque::<f64>(move [[sub]])
|
||||
opaque(x - 0.);
|
||||
// CHECK: [[mul:_.*]] = Mul(_1, const 0f64);
|
||||
// CHECK: opaque::<f64>(move [[mul]])
|
||||
opaque(x * 0.);
|
||||
// CHECK: [[div0:_.*]] = Div(_1, const 0f64);
|
||||
// CHECK: opaque::<f64>(move [[div0]])
|
||||
opaque(x / 0.);
|
||||
// CHECK: [[zdiv:_.*]] = Div(const 0f64, _1);
|
||||
// CHECK: opaque::<f64>(move [[zdiv]])
|
||||
opaque(0. / x);
|
||||
// CHECK: [[rem0:_.*]] = Rem(_1, const 0f64);
|
||||
// CHECK: opaque::<f64>(move [[rem0]])
|
||||
opaque(x % 0.);
|
||||
// CHECK: [[zrem:_.*]] = Rem(const 0f64, _1);
|
||||
// CHECK: opaque::<f64>(move [[zrem]])
|
||||
opaque(0. % x);
|
||||
// Those are not simplifiable to `true`/`false`, thanks to NaNs.
|
||||
// CHECK: [[eq:_.*]] = Eq(_1, _1);
|
||||
// CHECK: opaque::<bool>(move [[eq]])
|
||||
opaque(x == x);
|
||||
// CHECK: [[ne:_.*]] = Ne(_1, _1);
|
||||
// CHECK: opaque::<bool>(move [[ne]])
|
||||
opaque(x != x);
|
||||
}
|
||||
|
||||
fn cast() {
|
||||
// CHECK-LABEL: fn cast(
|
||||
let i = 1_i64;
|
||||
let u = 1_u64;
|
||||
let f = 1_f64;
|
||||
// CHECK: opaque::<u8>(const 1_u8)
|
||||
opaque(i as u8);
|
||||
// CHECK: opaque::<u16>(const 1_u16)
|
||||
opaque(i as u16);
|
||||
// CHECK: opaque::<u32>(const 1_u32)
|
||||
opaque(i as u32);
|
||||
// CHECK: opaque::<u64>(const 1_u64)
|
||||
opaque(i as u64);
|
||||
// CHECK: opaque::<i8>(const 1_i8)
|
||||
opaque(i as i8);
|
||||
// CHECK: opaque::<i16>(const 1_i16)
|
||||
opaque(i as i16);
|
||||
// CHECK: opaque::<i32>(const 1_i32)
|
||||
opaque(i as i32);
|
||||
// CHECK: opaque::<i64>(const 1_i64)
|
||||
opaque(i as i64);
|
||||
// CHECK: opaque::<f32>(const 1f32)
|
||||
opaque(i as f32);
|
||||
// CHECK: opaque::<f64>(const 1f64)
|
||||
opaque(i as f64);
|
||||
// CHECK: opaque::<u8>(const 1_u8)
|
||||
opaque(u as u8);
|
||||
// CHECK: opaque::<u16>(const 1_u16)
|
||||
opaque(u as u16);
|
||||
// CHECK: opaque::<u32>(const 1_u32)
|
||||
opaque(u as u32);
|
||||
// CHECK: opaque::<u64>(const 1_u64)
|
||||
opaque(u as u64);
|
||||
// CHECK: opaque::<i8>(const 1_i8)
|
||||
opaque(u as i8);
|
||||
// CHECK: opaque::<i16>(const 1_i16)
|
||||
opaque(u as i16);
|
||||
// CHECK: opaque::<i32>(const 1_i32)
|
||||
opaque(u as i32);
|
||||
// CHECK: opaque::<i64>(const 1_i64)
|
||||
opaque(u as i64);
|
||||
// CHECK: opaque::<f32>(const 1f32)
|
||||
opaque(u as f32);
|
||||
// CHECK: opaque::<f64>(const 1f64)
|
||||
opaque(u as f64);
|
||||
// CHECK: opaque::<u8>(const 1_u8)
|
||||
opaque(f as u8);
|
||||
// CHECK: opaque::<u16>(const 1_u16)
|
||||
opaque(f as u16);
|
||||
// CHECK: opaque::<u32>(const 1_u32)
|
||||
opaque(f as u32);
|
||||
// CHECK: opaque::<u64>(const 1_u64)
|
||||
opaque(f as u64);
|
||||
// CHECK: opaque::<i8>(const 1_i8)
|
||||
opaque(f as i8);
|
||||
// CHECK: opaque::<i16>(const 1_i16)
|
||||
opaque(f as i16);
|
||||
// CHECK: opaque::<i32>(const 1_i32)
|
||||
opaque(f as i32);
|
||||
// CHECK: opaque::<i64>(const 1_i64)
|
||||
opaque(f as i64);
|
||||
// CHECK: opaque::<f32>(const 1f32)
|
||||
opaque(f as f32);
|
||||
// CHECK: opaque::<f64>(const 1f64)
|
||||
opaque(f as f64);
|
||||
}
|
||||
|
||||
fn multiple_branches(t: bool, x: u8, y: u8) {
|
||||
// CHECK-LABEL: fn multiple_branches(
|
||||
// CHECK: switchInt(_1) -> [0: [[bbf:bb.*]], otherwise: [[bbt:bb.*]]];
|
||||
if t {
|
||||
opaque(x + y); // a
|
||||
opaque(x + y); // should reuse a
|
||||
// CHECK: [[bbt]]: {
|
||||
// CHECK: [[a:_.*]] = Add(_2, _3);
|
||||
// CHECK: opaque::<u8>([[a]])
|
||||
// CHECK: opaque::<u8>([[a]])
|
||||
// CHECK: goto -> [[bbc:bb.*]];
|
||||
opaque(x + y);
|
||||
opaque(x + y);
|
||||
} else {
|
||||
opaque(x + y); // b
|
||||
opaque(x + y); // shoud reuse b
|
||||
// CHECK: [[bbf]]: {
|
||||
// CHECK: [[b:_.*]] = Add(_2, _3);
|
||||
// CHECK: opaque::<u8>([[b]])
|
||||
// CHECK: opaque::<u8>([[b]])
|
||||
// CHECK: goto -> [[bbc:bb.*]];
|
||||
opaque(x + y);
|
||||
opaque(x + y);
|
||||
}
|
||||
opaque(x + y); // c
|
||||
// Neither `a` nor `b` dominate `c`, so we cannot reuse any of them.
|
||||
// CHECK: [[bbc]]: {
|
||||
// CHECK: [[c:_.*]] = Add(_2, _3);
|
||||
// CHECK: opaque::<u8>([[c]])
|
||||
opaque(x + y);
|
||||
|
||||
// `c` dominates both calls, so we can reuse it.
|
||||
if t {
|
||||
opaque(x + y); // should reuse c
|
||||
// CHECK: opaque::<u8>([[c]])
|
||||
opaque(x + y);
|
||||
} else {
|
||||
opaque(x + y); // should reuse c
|
||||
// CHECK: opaque::<u8>([[c]])
|
||||
opaque(x + y);
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify that we do not reuse a `&raw? mut?` rvalue.
|
||||
fn references(mut x: impl Sized) {
|
||||
// CHECK-LABEL: fn references(
|
||||
// CHECK: [[ref1:_.*]] = &_1;
|
||||
// CHECK: opaque::<&impl Sized>(move [[ref1]])
|
||||
opaque(&x);
|
||||
opaque(&x); // should not reuse a
|
||||
// CHECK: [[ref2:_.*]] = &_1;
|
||||
// CHECK: opaque::<&impl Sized>(move [[ref2]])
|
||||
opaque(&x);
|
||||
// CHECK: [[ref3:_.*]] = &mut _1;
|
||||
// CHECK: opaque::<&mut impl Sized>(move [[ref3]])
|
||||
opaque(&mut x);
|
||||
opaque(&mut x); // should not reuse a
|
||||
// CHECK: [[ref4:_.*]] = &mut _1;
|
||||
// CHECK: opaque::<&mut impl Sized>(move [[ref4]])
|
||||
opaque(&mut x);
|
||||
// CHECK: [[ref5:_.*]] = &raw const _1;
|
||||
// CHECK: opaque::<*const impl Sized>(move [[ref5]])
|
||||
opaque(&raw const x);
|
||||
opaque(&raw const x); // should not reuse a
|
||||
// CHECK: [[ref6:_.*]] = &raw const _1;
|
||||
// CHECK: opaque::<*const impl Sized>(move [[ref6]])
|
||||
opaque(&raw const x);
|
||||
// CHECK: [[ref7:_.*]] = &raw mut _1;
|
||||
// CHECK: opaque::<*mut impl Sized>(move [[ref7]])
|
||||
opaque(&raw mut x);
|
||||
// CHECK: [[ref8:_.*]] = &raw mut _1;
|
||||
// CHECK: opaque::<*mut impl Sized>(move [[ref8]])
|
||||
opaque(&raw mut x);
|
||||
opaque(&raw mut x); // should not reuse a
|
||||
|
||||
let r = &mut x;
|
||||
let s = S(r).0; // Obfuscate `r`.
|
||||
opaque(&*s); // This is `&*r`.
|
||||
opaque(&mut *s); // This is `&*r`.
|
||||
opaque(&raw const *s); // This is `&*r`.
|
||||
opaque(&raw mut *s); // This is `&*r`.
|
||||
let s = S(r).0; // Obfuscate `r`. Following lines should still reborrow `r`.
|
||||
// CHECK: [[ref9:_.*]] = &mut _1;
|
||||
// CHECK: [[ref10:_.*]] = &(*[[ref9]]);
|
||||
// CHECK: opaque::<&impl Sized>(move [[ref10]])
|
||||
opaque(&*s);
|
||||
// CHECK: [[ref11:_.*]] = &mut (*[[ref9]]);
|
||||
// CHECK: opaque::<&mut impl Sized>(move [[ref11]])
|
||||
opaque(&mut *s);
|
||||
// CHECK: [[ref12:_.*]] = &raw const (*[[ref9]]);
|
||||
// CHECK: opaque::<*const impl Sized>(move [[ref12]])
|
||||
opaque(&raw const *s);
|
||||
// CHECK: [[ref12:_.*]] = &raw mut (*[[ref9]]);
|
||||
// CHECK: opaque::<*mut impl Sized>(move [[ref12]])
|
||||
opaque(&raw mut *s);
|
||||
}
|
||||
|
||||
fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
|
||||
// CHECK-LABEL: fn dereferences(
|
||||
|
||||
// Do not reuse dereferences of `&mut`.
|
||||
// CHECK: [[st1:_.*]] = (*_1);
|
||||
// CHECK: opaque::<u32>(move [[st1]])
|
||||
// CHECK: [[st2:_.*]] = (*_1);
|
||||
// CHECK: opaque::<u32>(move [[st2]])
|
||||
opaque(*t);
|
||||
opaque(*t); // this cannot reuse a, as x is &mut.
|
||||
opaque(*t);
|
||||
|
||||
// Do not reuse dereferences of `*const`.
|
||||
// CHECK: [[raw:_.*]] = &raw const (*_1);
|
||||
// CHECK: [[st3:_.*]] = (*[[raw]]);
|
||||
// CHECK: opaque::<u32>(move [[st3]])
|
||||
// CHECK: [[st4:_.*]] = (*[[raw]]);
|
||||
// CHECK: opaque::<u32>(move [[st4]])
|
||||
let z = &raw const *t;
|
||||
unsafe { opaque(*z) };
|
||||
unsafe { opaque(*z) }; // this cannot reuse a, as x is *const.
|
||||
unsafe { opaque(*z) };
|
||||
|
||||
// Do not reuse dereferences of `*mut`.
|
||||
// CHECK: [[ptr:_.*]] = &raw mut (*_1);
|
||||
// CHECK: [[st5:_.*]] = (*[[ptr]]);
|
||||
// CHECK: opaque::<u32>(move [[st5]])
|
||||
// CHECK: [[st6:_.*]] = (*[[ptr]]);
|
||||
// CHECK: opaque::<u32>(move [[st6]])
|
||||
let z = &raw mut *t;
|
||||
unsafe { opaque(*z) };
|
||||
unsafe { opaque(*z) }; // this cannot reuse a, as x is *mut.
|
||||
unsafe { opaque(*z) };
|
||||
|
||||
// We can reuse dereferences of `&Freeze`.
|
||||
// CHECK: [[ref:_.*]] = &(*_1);
|
||||
// CHECK: [[st7:_.*]] = (*[[ref]]);
|
||||
// CHECK: opaque::<u32>([[st7]])
|
||||
// CHECK: opaque::<u32>([[st7]])
|
||||
let z = &*t;
|
||||
opaque(*z);
|
||||
opaque(*z); // this can reuse, as `z` is immutable ref, Freeze and Copy.
|
||||
opaque(&*z); // but not for a reborrow.
|
||||
opaque(*z);
|
||||
// But not in reborrows.
|
||||
// CHECK: [[reborrow:_.*]] = &(*[[ref]]);
|
||||
// CHECK: opaque::<&u32>(move [[reborrow]])
|
||||
opaque(&*z);
|
||||
|
||||
// `*u` is not Freeze, so we cannot reuse.
|
||||
// CHECK: [[st8:_.*]] = (*_2);
|
||||
// CHECK: opaque::<impl Copy>(move [[st8]])
|
||||
// CHECK: [[st9:_.*]] = (*_2);
|
||||
// CHECK: opaque::<impl Copy>(move [[st9]])
|
||||
opaque(*u);
|
||||
opaque(*u); // this cannot reuse, as `z` is not Freeze.
|
||||
opaque(*u);
|
||||
|
||||
// `*s` is not Copy, by `(*s).0` is, so we can reuse.
|
||||
// CHECK: [[st10:_.*]] = ((*_3).0: u32);
|
||||
// CHECK: opaque::<u32>([[st10]])
|
||||
// CHECK: opaque::<u32>([[st10]])
|
||||
opaque(s.0);
|
||||
opaque(s.0);
|
||||
opaque(s.0); // *s is not Copy, by (*s).0 is, so we can reuse.
|
||||
}
|
||||
|
||||
fn slices() {
|
||||
// CHECK-LABEL: fn slices(
|
||||
// CHECK: {{_.*}} = const "
|
||||
// CHECK-NOT: {{_.*}} = const "
|
||||
let s = "my favourite slice"; // This is a `Const::Slice` in MIR.
|
||||
opaque(s);
|
||||
let t = s; // This should be the same pointer, so cannot be a `Const::Slice`.
|
||||
@ -238,6 +517,7 @@ fn slices() {
|
||||
|
||||
#[custom_mir(dialect = "analysis")]
|
||||
fn duplicate_slice() -> (bool, bool) {
|
||||
// CHECK-LABEL: fn duplicate_slice(
|
||||
mir!(
|
||||
let au: u128;
|
||||
let bu: u128;
|
||||
@ -246,41 +526,50 @@ fn duplicate_slice() -> (bool, bool) {
|
||||
let c: &str;
|
||||
let d: &str;
|
||||
{
|
||||
// CHECK: [[a:_.*]] = (const "a",);
|
||||
// CHECK: [[au:_.*]] = ([[a]].0: &str) as u128 (Transmute);
|
||||
let a = ("a",);
|
||||
Call(au = transmute::<_, u128>(a.0), bb1)
|
||||
}
|
||||
bb1 = {
|
||||
// CHECK: [[c:_.*]] = identity::<&str>(([[a]].0: &str))
|
||||
Call(c = identity(a.0), bb2)
|
||||
}
|
||||
bb2 = {
|
||||
// CHECK: [[cu:_.*]] = [[c]] as u128 (Transmute);
|
||||
Call(cu = transmute::<_, u128>(c), bb3)
|
||||
}
|
||||
bb3 = {
|
||||
let b = "a"; // This slice is different from `a.0`.
|
||||
Call(bu = transmute::<_, u128>(b), bb4) // Hence `bu` is not `au`.
|
||||
// This slice is different from `a.0`. Hence `bu` is not `au`.
|
||||
// CHECK: [[b:_.*]] = const "a";
|
||||
// CHECK: [[bu:_.*]] = [[b]] as u128 (Transmute);
|
||||
let b = "a";
|
||||
Call(bu = transmute::<_, u128>(b), bb4)
|
||||
}
|
||||
bb4 = {
|
||||
Call(d = identity(b), bb5) // This returns a copy of `b`, which is not `a`.
|
||||
// This returns a copy of `b`, which is not `a`.
|
||||
// CHECK: [[d:_.*]] = identity::<&str>([[b]])
|
||||
Call(d = identity(b), bb5)
|
||||
}
|
||||
bb5 = {
|
||||
// CHECK: [[du:_.*]] = [[d]] as u128 (Transmute);
|
||||
Call(du = transmute::<_, u128>(d), bb6)
|
||||
}
|
||||
bb6 = {
|
||||
let direct = au == bu; // Must not fold to `true`...
|
||||
let indirect = cu == du; // ...as this will not.
|
||||
// `direct` must not fold to `true`, as `indirect` will not.
|
||||
// CHECK: = Eq([[au]], [[bu]]);
|
||||
// CHECK: = Eq([[cu]], [[du]]);
|
||||
let direct = au == bu;
|
||||
let indirect = cu == du;
|
||||
RET = (direct, indirect);
|
||||
Return()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fn aggregates() {
|
||||
let a_array: S<[u8; 0]> = S([]);
|
||||
let b_array: S<[u16; 0]> = S([]); // This must not be merged with `a_array`.
|
||||
|
||||
let a_tuple: S<()> = S(());
|
||||
let b_tuple: S<()> = S(()); // But this can be with `a_tuple`.
|
||||
|
||||
fn repeat() {
|
||||
// CHECK-LABEL: fn repeat(
|
||||
// CHECK: = [const 5_i32; 10];
|
||||
let val = 5;
|
||||
let array = [val, val, val, val, val, val, val, val, val, val];
|
||||
}
|
||||
@ -290,6 +579,7 @@ fn main() {
|
||||
wrap_unwrap(5);
|
||||
repeated_index::<u32, 7>(5, 3);
|
||||
arithmetic(5);
|
||||
comparison(5, 6);
|
||||
arithmetic_checked(5);
|
||||
arithmetic_float(5.);
|
||||
cast();
|
||||
@ -299,7 +589,7 @@ fn main() {
|
||||
slices();
|
||||
let (direct, indirect) = duplicate_slice();
|
||||
assert_eq!(direct, indirect);
|
||||
aggregates();
|
||||
repeat();
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
@ -314,6 +604,7 @@ fn identity<T>(x: T) -> T {
|
||||
// EMIT_MIR gvn.wrap_unwrap.GVN.diff
|
||||
// EMIT_MIR gvn.repeated_index.GVN.diff
|
||||
// EMIT_MIR gvn.arithmetic.GVN.diff
|
||||
// EMIT_MIR gvn.comparison.GVN.diff
|
||||
// EMIT_MIR gvn.arithmetic_checked.GVN.diff
|
||||
// EMIT_MIR gvn.arithmetic_float.GVN.diff
|
||||
// EMIT_MIR gvn.cast.GVN.diff
|
||||
@ -322,4 +613,4 @@ fn identity<T>(x: T) -> T {
|
||||
// EMIT_MIR gvn.dereferences.GVN.diff
|
||||
// EMIT_MIR gvn.slices.GVN.diff
|
||||
// EMIT_MIR gvn.duplicate_slice.GVN.diff
|
||||
// EMIT_MIR gvn.aggregates.GVN.diff
|
||||
// EMIT_MIR gvn.repeat.GVN.diff
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user