From b421a563644dafdb8a5a9c48fe21c4a449da18fa Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 5 Jan 2025 23:27:24 -0800 Subject: [PATCH] Make the aggregate-then-transmute handling more general --- compiler/rustc_mir_transform/src/gvn.rs | 22 +- ...struct_then_transmute.GVN.panic-abort.diff | 395 +++++++++++------- ...truct_then_transmute.GVN.panic-unwind.diff | 395 +++++++++++------- tests/mir-opt/gvn.rs | 14 +- 4 files changed, 516 insertions(+), 310 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 7c600fc1ceb2..71bec38c405d 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1370,12 +1370,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { loop { let mut was_updated_this_iteration = false; - // Transmuting `*const T` <=> `*mut T` is just a pointer cast, - // which we might be able to merge with other ones later. + // Transmuting between raw pointers is just a pointer cast so long as + // they have the same metadata type (like `*const i32` <=> `*mut u64` + // or `*mut [i32]` <=> `*const [u64]`), including the common special + // case of `*const T` <=> `*mut T`. if let Transmute = kind - && let ty::RawPtr(from_pointee, _) = from.kind() - && let ty::RawPtr(to_pointee, _) = to.kind() - && from_pointee == to_pointee + && from.is_unsafe_ptr() + && to.is_unsafe_ptr() + && self.pointers_have_same_metadata(from, to) { *kind = PtrToPtr; was_updated_this_iteration = true; @@ -1400,15 +1402,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // Aggregate-then-Transmute can just transmute the original field value, // so long as the bytes of a value from only from a single field. if let Transmute = kind - && let Value::Aggregate( - AggregateTy::Def(aggregate_did, aggregate_args), - variant_idx, - field_values, - ) = self.get(value) - && let aggregate_ty = - self.tcx.type_of(aggregate_did).instantiate(self.tcx, aggregate_args) + && let Value::Aggregate(_aggregate_ty, variant_idx, field_values) = self.get(value) && let Some((field_idx, field_ty)) = - self.value_is_all_in_one_field(aggregate_ty, *variant_idx) + self.value_is_all_in_one_field(from, *variant_idx) { from = field_ty; value = field_values[field_idx.as_usize()]; diff --git a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff index 1f9291802472..5ae575f300af 100644 --- a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff @@ -1,61 +1,87 @@ - // MIR for `aggregate_struct_then_transmute` before GVN + // MIR for `aggregate_struct_then_transmute` after GVN - fn aggregate_struct_then_transmute(_1: u16) -> () { + fn aggregate_struct_then_transmute(_1: u16, _2: *const u8) -> () { debug id => _1; + debug thin => _2; let mut _0: (); - let _2: MyId; - let mut _3: u16; - let _4: (); - let mut _5: u16; - let mut _6: MyId; - let mut _8: u16; - let mut _9: std::marker::PhantomData; - let _10: (); - let mut _11: u16; - let mut _12: TypedId; - let mut _14: u16; - let _15: (); - let mut _16: u16; - let mut _17: std::result::Result; - let mut _19: u16; - let _20: (); - let mut _21: u32; - let mut _22: std::option::Option; - let mut _24: u16; - let _25: (); - let mut _26: i16; - let mut _27: MyId; - let mut _29: u16; + let _3: MyId; + let mut _4: u16; + let _5: (); + let mut _6: u16; + let mut _7: MyId; + let mut _9: u16; + let mut _10: std::marker::PhantomData; + let _11: (); + let mut _12: u16; + let mut _13: TypedId; + let mut _15: u16; + let _16: (); + let mut _17: u16; + let mut _18: std::result::Result; + let mut _20: u16; + let _21: (); + let mut _22: u32; + let mut _23: std::option::Option; + let mut _25: u16; + let _26: (); + let mut _27: i16; + let mut _28: MyId; let mut _30: u16; - let _31: (); - let mut _32: u32; - let mut _33: aggregate_struct_then_transmute::Pair; - let mut _35: u16; + let mut _31: u16; + let _32: (); + let mut _33: u32; + let mut _34: aggregate_struct_then_transmute::Pair; let mut _36: u16; - let _37: (); - let mut _38: u16; - let mut _39: aggregate_struct_then_transmute::Pair; + let mut _37: u16; + let _38: (); + let mut _39: u16; + let mut _40: aggregate_struct_then_transmute::Pair; + let mut _42: u16; + let _43: (); + let mut _44: u16; + let mut _45: (u16,); + let mut _47: u16; + let _48: (); + let mut _49: u16; + let mut _50: [u16; 1]; + let mut _52: *const u8; + let mut _53: (); + let _54: (); + let mut _55: *const u8; + let mut _56: *const i32; scope 1 { - debug a => _2; - let _7: TypedId; + debug a => _3; + let _8: TypedId; scope 2 { - debug b => _7; - let _13: std::result::Result; + debug b => _8; + let _14: std::result::Result; scope 3 { - debug c => _13; - let _18: std::option::Option; + debug c => _14; + let _19: std::option::Option; scope 4 { - debug d => _18; - let _23: MyId; + debug d => _19; + let _24: MyId; scope 5 { - debug e => _23; - let _28: aggregate_struct_then_transmute::Pair; + debug e => _24; + let _29: aggregate_struct_then_transmute::Pair; scope 6 { - debug f => _28; - let _34: aggregate_struct_then_transmute::Pair; + debug f => _29; + let _35: aggregate_struct_then_transmute::Pair; scope 7 { - debug g => _34; + debug g => _35; + let _41: (u16,); + scope 8 { + debug h => _41; + let _46: [u16; 1]; + scope 9 { + debug i => _46; + let _51: *const i32; + scope 10 { + debug j => _51; + } + } + } } } } @@ -65,172 +91,245 @@ } bb0: { -- StorageLive(_2); +- StorageLive(_3); + nop; - StorageLive(_3); - _3 = copy _1; -- _2 = MyId(move _3); -+ _2 = MyId(copy _1); - StorageDead(_3); StorageLive(_4); + _4 = copy _1; +- _3 = MyId(move _4); ++ _3 = MyId(copy _1); + StorageDead(_4); StorageLive(_5); StorageLive(_6); -- _6 = move _2; -- _5 = move _6 as u16 (Transmute); -+ _6 = copy _2; -+ _5 = copy _1; - StorageDead(_6); -- _4 = opaque::(move _5) -> [return: bb1, unwind unreachable]; -+ _4 = opaque::(copy _1) -> [return: bb1, unwind unreachable]; + StorageLive(_7); +- _7 = move _3; +- _6 = move _7 as u16 (Transmute); ++ _7 = copy _3; ++ _6 = copy _1; + StorageDead(_7); +- _5 = opaque::(move _6) -> [return: bb1, unwind unreachable]; ++ _5 = opaque::(copy _1) -> [return: bb1, unwind unreachable]; } bb1: { + StorageDead(_6); StorageDead(_5); - StorageDead(_4); -- StorageLive(_7); +- StorageLive(_8); + nop; - StorageLive(_8); - _8 = copy _1; StorageLive(_9); -- _9 = PhantomData::; -- _7 = TypedId::(move _8, move _9); -+ _9 = const PhantomData::; -+ _7 = TypedId::(copy _1, const PhantomData::); - StorageDead(_9); - StorageDead(_8); + _9 = copy _1; StorageLive(_10); +- _10 = PhantomData::; +- _8 = TypedId::(move _9, move _10); ++ _10 = const PhantomData::; ++ _8 = TypedId::(copy _1, const PhantomData::); + StorageDead(_10); + StorageDead(_9); StorageLive(_11); StorageLive(_12); -- _12 = move _7; -- _11 = move _12 as u16 (Transmute); -+ _12 = copy _7; -+ _11 = copy _1; - StorageDead(_12); -- _10 = opaque::(move _11) -> [return: bb2, unwind unreachable]; -+ _10 = opaque::(copy _1) -> [return: bb2, unwind unreachable]; + StorageLive(_13); +- _13 = move _8; +- _12 = move _13 as u16 (Transmute); ++ _13 = copy _8; ++ _12 = copy _1; + StorageDead(_13); +- _11 = opaque::(move _12) -> [return: bb2, unwind unreachable]; ++ _11 = opaque::(copy _1) -> [return: bb2, unwind unreachable]; } bb2: { + StorageDead(_12); StorageDead(_11); - StorageDead(_10); -- StorageLive(_13); +- StorageLive(_14); + nop; - StorageLive(_14); - _14 = copy _1; -- _13 = Result::::Err(move _14); -+ _13 = Result::::Err(copy _1); - StorageDead(_14); StorageLive(_15); + _15 = copy _1; +- _14 = Result::::Err(move _15); ++ _14 = Result::::Err(copy _1); + StorageDead(_15); StorageLive(_16); StorageLive(_17); -- _17 = move _13; -- _16 = move _17 as u16 (Transmute); -+ _17 = copy _13; -+ _16 = copy _1; - StorageDead(_17); -- _15 = opaque::(move _16) -> [return: bb3, unwind unreachable]; -+ _15 = opaque::(copy _1) -> [return: bb3, unwind unreachable]; + StorageLive(_18); +- _18 = move _14; +- _17 = move _18 as u16 (Transmute); ++ _18 = copy _14; ++ _17 = copy _1; + StorageDead(_18); +- _16 = opaque::(move _17) -> [return: bb3, unwind unreachable]; ++ _16 = opaque::(copy _1) -> [return: bb3, unwind unreachable]; } bb3: { + StorageDead(_17); StorageDead(_16); - StorageDead(_15); -- StorageLive(_18); +- StorageLive(_19); + nop; - StorageLive(_19); - _19 = copy _1; -- _18 = Option::::Some(move _19); -+ _18 = Option::::Some(copy _1); - StorageDead(_19); StorageLive(_20); + _20 = copy _1; +- _19 = Option::::Some(move _20); ++ _19 = Option::::Some(copy _1); + StorageDead(_20); StorageLive(_21); StorageLive(_22); - _22 = copy _18; -- _21 = move _22 as u32 (Transmute); -+ _21 = copy _18 as u32 (Transmute); - StorageDead(_22); - _20 = opaque::(move _21) -> [return: bb4, unwind unreachable]; + StorageLive(_23); + _23 = copy _19; +- _22 = move _23 as u32 (Transmute); ++ _22 = copy _19 as u32 (Transmute); + StorageDead(_23); + _21 = opaque::(move _22) -> [return: bb4, unwind unreachable]; } bb4: { + StorageDead(_22); StorageDead(_21); - StorageDead(_20); - StorageLive(_23); StorageLive(_24); - _24 = copy _1; -- _23 = MyId(move _24); -+ _23 = copy _2; - StorageDead(_24); StorageLive(_25); + _25 = copy _1; +- _24 = MyId(move _25); ++ _24 = copy _3; + StorageDead(_25); StorageLive(_26); StorageLive(_27); -- _27 = move _23; -- _26 = move _27 as i16 (Transmute); -+ _27 = copy _2; -+ _26 = copy _1 as i16 (Transmute); - StorageDead(_27); - _25 = opaque::(move _26) -> [return: bb5, unwind unreachable]; + StorageLive(_28); +- _28 = move _24; +- _27 = move _28 as i16 (Transmute); ++ _28 = copy _3; ++ _27 = copy _1 as i16 (Transmute); + StorageDead(_28); + _26 = opaque::(move _27) -> [return: bb5, unwind unreachable]; } bb5: { + StorageDead(_27); StorageDead(_26); - StorageDead(_25); -- StorageLive(_28); +- StorageLive(_29); + nop; - StorageLive(_29); - _29 = copy _1; StorageLive(_30); _30 = copy _1; -- _28 = Pair(move _29, move _30); -+ _28 = Pair(copy _1, copy _1); - StorageDead(_30); - StorageDead(_29); StorageLive(_31); + _31 = copy _1; +- _29 = Pair(move _30, move _31); ++ _29 = Pair(copy _1, copy _1); + StorageDead(_31); + StorageDead(_30); StorageLive(_32); StorageLive(_33); -- _33 = move _28; -- _32 = move _33 as u32 (Transmute); -+ _33 = copy _28; -+ _32 = copy _28 as u32 (Transmute); - StorageDead(_33); - _31 = opaque::(move _32) -> [return: bb6, unwind unreachable]; + StorageLive(_34); +- _34 = move _29; +- _33 = move _34 as u32 (Transmute); ++ _34 = copy _29; ++ _33 = copy _29 as u32 (Transmute); + StorageDead(_34); + _32 = opaque::(move _33) -> [return: bb6, unwind unreachable]; } bb6: { + StorageDead(_33); StorageDead(_32); - StorageDead(_31); - StorageLive(_34); StorageLive(_35); - _35 = copy _1; StorageLive(_36); _36 = copy _1; -- _34 = Pair(move _35, move _36); -+ _34 = copy _28; - StorageDead(_36); - StorageDead(_35); StorageLive(_37); + _37 = copy _1; +- _35 = Pair(move _36, move _37); ++ _35 = copy _29; + StorageDead(_37); + StorageDead(_36); StorageLive(_38); StorageLive(_39); -- _39 = move _34; -- _38 = move _39 as u16 (Transmute); -+ _39 = copy _28; -+ _38 = copy _28 as u16 (Transmute); - StorageDead(_39); - _37 = opaque::(move _38) -> [return: bb7, unwind unreachable]; + StorageLive(_40); +- _40 = move _35; +- _39 = move _40 as u16 (Transmute); ++ _40 = copy _29; ++ _39 = copy _29 as u16 (Transmute); + StorageDead(_40); + _38 = opaque::(move _39) -> [return: bb7, unwind unreachable]; } bb7: { + StorageDead(_39); StorageDead(_38); - StorageDead(_37); - _0 = const (); - StorageDead(_34); -- StorageDead(_28); +- StorageLive(_41); + nop; - StorageDead(_23); -- StorageDead(_18); -- StorageDead(_13); -- StorageDead(_7); -- StorageDead(_2); + StorageLive(_42); + _42 = copy _1; +- _41 = (move _42,); ++ _41 = (copy _1,); + StorageDead(_42); + StorageLive(_43); + StorageLive(_44); + StorageLive(_45); + _45 = copy _41; +- _44 = move _45 as u16 (Transmute); ++ _44 = copy _1; + StorageDead(_45); +- _43 = opaque::(move _44) -> [return: bb8, unwind unreachable]; ++ _43 = opaque::(copy _1) -> [return: bb8, unwind unreachable]; + } + + bb8: { + StorageDead(_44); + StorageDead(_43); +- StorageLive(_46); ++ nop; + StorageLive(_47); + _47 = copy _1; +- _46 = [move _47]; ++ _46 = [copy _1]; + StorageDead(_47); + StorageLive(_48); + StorageLive(_49); + StorageLive(_50); + _50 = copy _46; +- _49 = move _50 as u16 (Transmute); ++ _49 = copy _1; + StorageDead(_50); +- _48 = opaque::(move _49) -> [return: bb9, unwind unreachable]; ++ _48 = opaque::(copy _1) -> [return: bb9, unwind unreachable]; + } + + bb9: { + StorageDead(_49); + StorageDead(_48); +- StorageLive(_51); ++ nop; + StorageLive(_52); + _52 = copy _2; + StorageLive(_53); +- _53 = (); +- _51 = *const i32 from (move _52, move _53); ++ _53 = const (); ++ _51 = *const i32 from (copy _2, const ()); + StorageDead(_53); + StorageDead(_52); + StorageLive(_54); + StorageLive(_55); + StorageLive(_56); + _56 = copy _51; +- _55 = move _56 as *const u8 (Transmute); ++ _55 = copy _2; + StorageDead(_56); +- _54 = opaque::<*const u8>(move _55) -> [return: bb10, unwind unreachable]; ++ _54 = opaque::<*const u8>(copy _2) -> [return: bb10, unwind unreachable]; + } + + bb10: { + StorageDead(_55); + StorageDead(_54); + _0 = const (); +- StorageDead(_51); +- StorageDead(_46); +- StorageDead(_41); ++ nop; ++ nop; ++ nop; + StorageDead(_35); +- StorageDead(_29); ++ nop; + StorageDead(_24); +- StorageDead(_19); +- StorageDead(_14); +- StorageDead(_8); +- StorageDead(_3); + nop; + nop; + nop; diff --git a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff index b6b6b1627b72..3119a93fb891 100644 --- a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff @@ -1,61 +1,87 @@ - // MIR for `aggregate_struct_then_transmute` before GVN + // MIR for `aggregate_struct_then_transmute` after GVN - fn aggregate_struct_then_transmute(_1: u16) -> () { + fn aggregate_struct_then_transmute(_1: u16, _2: *const u8) -> () { debug id => _1; + debug thin => _2; let mut _0: (); - let _2: MyId; - let mut _3: u16; - let _4: (); - let mut _5: u16; - let mut _6: MyId; - let mut _8: u16; - let mut _9: std::marker::PhantomData; - let _10: (); - let mut _11: u16; - let mut _12: TypedId; - let mut _14: u16; - let _15: (); - let mut _16: u16; - let mut _17: std::result::Result; - let mut _19: u16; - let _20: (); - let mut _21: u32; - let mut _22: std::option::Option; - let mut _24: u16; - let _25: (); - let mut _26: i16; - let mut _27: MyId; - let mut _29: u16; + let _3: MyId; + let mut _4: u16; + let _5: (); + let mut _6: u16; + let mut _7: MyId; + let mut _9: u16; + let mut _10: std::marker::PhantomData; + let _11: (); + let mut _12: u16; + let mut _13: TypedId; + let mut _15: u16; + let _16: (); + let mut _17: u16; + let mut _18: std::result::Result; + let mut _20: u16; + let _21: (); + let mut _22: u32; + let mut _23: std::option::Option; + let mut _25: u16; + let _26: (); + let mut _27: i16; + let mut _28: MyId; let mut _30: u16; - let _31: (); - let mut _32: u32; - let mut _33: aggregate_struct_then_transmute::Pair; - let mut _35: u16; + let mut _31: u16; + let _32: (); + let mut _33: u32; + let mut _34: aggregate_struct_then_transmute::Pair; let mut _36: u16; - let _37: (); - let mut _38: u16; - let mut _39: aggregate_struct_then_transmute::Pair; + let mut _37: u16; + let _38: (); + let mut _39: u16; + let mut _40: aggregate_struct_then_transmute::Pair; + let mut _42: u16; + let _43: (); + let mut _44: u16; + let mut _45: (u16,); + let mut _47: u16; + let _48: (); + let mut _49: u16; + let mut _50: [u16; 1]; + let mut _52: *const u8; + let mut _53: (); + let _54: (); + let mut _55: *const u8; + let mut _56: *const i32; scope 1 { - debug a => _2; - let _7: TypedId; + debug a => _3; + let _8: TypedId; scope 2 { - debug b => _7; - let _13: std::result::Result; + debug b => _8; + let _14: std::result::Result; scope 3 { - debug c => _13; - let _18: std::option::Option; + debug c => _14; + let _19: std::option::Option; scope 4 { - debug d => _18; - let _23: MyId; + debug d => _19; + let _24: MyId; scope 5 { - debug e => _23; - let _28: aggregate_struct_then_transmute::Pair; + debug e => _24; + let _29: aggregate_struct_then_transmute::Pair; scope 6 { - debug f => _28; - let _34: aggregate_struct_then_transmute::Pair; + debug f => _29; + let _35: aggregate_struct_then_transmute::Pair; scope 7 { - debug g => _34; + debug g => _35; + let _41: (u16,); + scope 8 { + debug h => _41; + let _46: [u16; 1]; + scope 9 { + debug i => _46; + let _51: *const i32; + scope 10 { + debug j => _51; + } + } + } } } } @@ -65,172 +91,245 @@ } bb0: { -- StorageLive(_2); +- StorageLive(_3); + nop; - StorageLive(_3); - _3 = copy _1; -- _2 = MyId(move _3); -+ _2 = MyId(copy _1); - StorageDead(_3); StorageLive(_4); + _4 = copy _1; +- _3 = MyId(move _4); ++ _3 = MyId(copy _1); + StorageDead(_4); StorageLive(_5); StorageLive(_6); -- _6 = move _2; -- _5 = move _6 as u16 (Transmute); -+ _6 = copy _2; -+ _5 = copy _1; - StorageDead(_6); -- _4 = opaque::(move _5) -> [return: bb1, unwind continue]; -+ _4 = opaque::(copy _1) -> [return: bb1, unwind continue]; + StorageLive(_7); +- _7 = move _3; +- _6 = move _7 as u16 (Transmute); ++ _7 = copy _3; ++ _6 = copy _1; + StorageDead(_7); +- _5 = opaque::(move _6) -> [return: bb1, unwind continue]; ++ _5 = opaque::(copy _1) -> [return: bb1, unwind continue]; } bb1: { + StorageDead(_6); StorageDead(_5); - StorageDead(_4); -- StorageLive(_7); +- StorageLive(_8); + nop; - StorageLive(_8); - _8 = copy _1; StorageLive(_9); -- _9 = PhantomData::; -- _7 = TypedId::(move _8, move _9); -+ _9 = const PhantomData::; -+ _7 = TypedId::(copy _1, const PhantomData::); - StorageDead(_9); - StorageDead(_8); + _9 = copy _1; StorageLive(_10); +- _10 = PhantomData::; +- _8 = TypedId::(move _9, move _10); ++ _10 = const PhantomData::; ++ _8 = TypedId::(copy _1, const PhantomData::); + StorageDead(_10); + StorageDead(_9); StorageLive(_11); StorageLive(_12); -- _12 = move _7; -- _11 = move _12 as u16 (Transmute); -+ _12 = copy _7; -+ _11 = copy _1; - StorageDead(_12); -- _10 = opaque::(move _11) -> [return: bb2, unwind continue]; -+ _10 = opaque::(copy _1) -> [return: bb2, unwind continue]; + StorageLive(_13); +- _13 = move _8; +- _12 = move _13 as u16 (Transmute); ++ _13 = copy _8; ++ _12 = copy _1; + StorageDead(_13); +- _11 = opaque::(move _12) -> [return: bb2, unwind continue]; ++ _11 = opaque::(copy _1) -> [return: bb2, unwind continue]; } bb2: { + StorageDead(_12); StorageDead(_11); - StorageDead(_10); -- StorageLive(_13); +- StorageLive(_14); + nop; - StorageLive(_14); - _14 = copy _1; -- _13 = Result::::Err(move _14); -+ _13 = Result::::Err(copy _1); - StorageDead(_14); StorageLive(_15); + _15 = copy _1; +- _14 = Result::::Err(move _15); ++ _14 = Result::::Err(copy _1); + StorageDead(_15); StorageLive(_16); StorageLive(_17); -- _17 = move _13; -- _16 = move _17 as u16 (Transmute); -+ _17 = copy _13; -+ _16 = copy _1; - StorageDead(_17); -- _15 = opaque::(move _16) -> [return: bb3, unwind continue]; -+ _15 = opaque::(copy _1) -> [return: bb3, unwind continue]; + StorageLive(_18); +- _18 = move _14; +- _17 = move _18 as u16 (Transmute); ++ _18 = copy _14; ++ _17 = copy _1; + StorageDead(_18); +- _16 = opaque::(move _17) -> [return: bb3, unwind continue]; ++ _16 = opaque::(copy _1) -> [return: bb3, unwind continue]; } bb3: { + StorageDead(_17); StorageDead(_16); - StorageDead(_15); -- StorageLive(_18); +- StorageLive(_19); + nop; - StorageLive(_19); - _19 = copy _1; -- _18 = Option::::Some(move _19); -+ _18 = Option::::Some(copy _1); - StorageDead(_19); StorageLive(_20); + _20 = copy _1; +- _19 = Option::::Some(move _20); ++ _19 = Option::::Some(copy _1); + StorageDead(_20); StorageLive(_21); StorageLive(_22); - _22 = copy _18; -- _21 = move _22 as u32 (Transmute); -+ _21 = copy _18 as u32 (Transmute); - StorageDead(_22); - _20 = opaque::(move _21) -> [return: bb4, unwind continue]; + StorageLive(_23); + _23 = copy _19; +- _22 = move _23 as u32 (Transmute); ++ _22 = copy _19 as u32 (Transmute); + StorageDead(_23); + _21 = opaque::(move _22) -> [return: bb4, unwind continue]; } bb4: { + StorageDead(_22); StorageDead(_21); - StorageDead(_20); - StorageLive(_23); StorageLive(_24); - _24 = copy _1; -- _23 = MyId(move _24); -+ _23 = copy _2; - StorageDead(_24); StorageLive(_25); + _25 = copy _1; +- _24 = MyId(move _25); ++ _24 = copy _3; + StorageDead(_25); StorageLive(_26); StorageLive(_27); -- _27 = move _23; -- _26 = move _27 as i16 (Transmute); -+ _27 = copy _2; -+ _26 = copy _1 as i16 (Transmute); - StorageDead(_27); - _25 = opaque::(move _26) -> [return: bb5, unwind continue]; + StorageLive(_28); +- _28 = move _24; +- _27 = move _28 as i16 (Transmute); ++ _28 = copy _3; ++ _27 = copy _1 as i16 (Transmute); + StorageDead(_28); + _26 = opaque::(move _27) -> [return: bb5, unwind continue]; } bb5: { + StorageDead(_27); StorageDead(_26); - StorageDead(_25); -- StorageLive(_28); +- StorageLive(_29); + nop; - StorageLive(_29); - _29 = copy _1; StorageLive(_30); _30 = copy _1; -- _28 = Pair(move _29, move _30); -+ _28 = Pair(copy _1, copy _1); - StorageDead(_30); - StorageDead(_29); StorageLive(_31); + _31 = copy _1; +- _29 = Pair(move _30, move _31); ++ _29 = Pair(copy _1, copy _1); + StorageDead(_31); + StorageDead(_30); StorageLive(_32); StorageLive(_33); -- _33 = move _28; -- _32 = move _33 as u32 (Transmute); -+ _33 = copy _28; -+ _32 = copy _28 as u32 (Transmute); - StorageDead(_33); - _31 = opaque::(move _32) -> [return: bb6, unwind continue]; + StorageLive(_34); +- _34 = move _29; +- _33 = move _34 as u32 (Transmute); ++ _34 = copy _29; ++ _33 = copy _29 as u32 (Transmute); + StorageDead(_34); + _32 = opaque::(move _33) -> [return: bb6, unwind continue]; } bb6: { + StorageDead(_33); StorageDead(_32); - StorageDead(_31); - StorageLive(_34); StorageLive(_35); - _35 = copy _1; StorageLive(_36); _36 = copy _1; -- _34 = Pair(move _35, move _36); -+ _34 = copy _28; - StorageDead(_36); - StorageDead(_35); StorageLive(_37); + _37 = copy _1; +- _35 = Pair(move _36, move _37); ++ _35 = copy _29; + StorageDead(_37); + StorageDead(_36); StorageLive(_38); StorageLive(_39); -- _39 = move _34; -- _38 = move _39 as u16 (Transmute); -+ _39 = copy _28; -+ _38 = copy _28 as u16 (Transmute); - StorageDead(_39); - _37 = opaque::(move _38) -> [return: bb7, unwind continue]; + StorageLive(_40); +- _40 = move _35; +- _39 = move _40 as u16 (Transmute); ++ _40 = copy _29; ++ _39 = copy _29 as u16 (Transmute); + StorageDead(_40); + _38 = opaque::(move _39) -> [return: bb7, unwind continue]; } bb7: { + StorageDead(_39); StorageDead(_38); - StorageDead(_37); - _0 = const (); - StorageDead(_34); -- StorageDead(_28); +- StorageLive(_41); + nop; - StorageDead(_23); -- StorageDead(_18); -- StorageDead(_13); -- StorageDead(_7); -- StorageDead(_2); + StorageLive(_42); + _42 = copy _1; +- _41 = (move _42,); ++ _41 = (copy _1,); + StorageDead(_42); + StorageLive(_43); + StorageLive(_44); + StorageLive(_45); + _45 = copy _41; +- _44 = move _45 as u16 (Transmute); ++ _44 = copy _1; + StorageDead(_45); +- _43 = opaque::(move _44) -> [return: bb8, unwind continue]; ++ _43 = opaque::(copy _1) -> [return: bb8, unwind continue]; + } + + bb8: { + StorageDead(_44); + StorageDead(_43); +- StorageLive(_46); ++ nop; + StorageLive(_47); + _47 = copy _1; +- _46 = [move _47]; ++ _46 = [copy _1]; + StorageDead(_47); + StorageLive(_48); + StorageLive(_49); + StorageLive(_50); + _50 = copy _46; +- _49 = move _50 as u16 (Transmute); ++ _49 = copy _1; + StorageDead(_50); +- _48 = opaque::(move _49) -> [return: bb9, unwind continue]; ++ _48 = opaque::(copy _1) -> [return: bb9, unwind continue]; + } + + bb9: { + StorageDead(_49); + StorageDead(_48); +- StorageLive(_51); ++ nop; + StorageLive(_52); + _52 = copy _2; + StorageLive(_53); +- _53 = (); +- _51 = *const i32 from (move _52, move _53); ++ _53 = const (); ++ _51 = *const i32 from (copy _2, const ()); + StorageDead(_53); + StorageDead(_52); + StorageLive(_54); + StorageLive(_55); + StorageLive(_56); + _56 = copy _51; +- _55 = move _56 as *const u8 (Transmute); ++ _55 = copy _2; + StorageDead(_56); +- _54 = opaque::<*const u8>(move _55) -> [return: bb10, unwind continue]; ++ _54 = opaque::<*const u8>(copy _2) -> [return: bb10, unwind continue]; + } + + bb10: { + StorageDead(_55); + StorageDead(_54); + _0 = const (); +- StorageDead(_51); +- StorageDead(_46); +- StorageDead(_41); ++ nop; ++ nop; ++ nop; + StorageDead(_35); +- StorageDead(_29); ++ nop; + StorageDead(_24); +- StorageDead(_19); +- StorageDead(_14); +- StorageDead(_8); +- StorageDead(_3); + nop; + nop; + nop; diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 17357fed5a59..c895a5792595 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -933,7 +933,7 @@ fn cast_pointer_eq(p1: *mut u8, p2: *mut u32, p3: *mut u32, p4: *mut [u32]) { // CHECK: _0 = const (); } -unsafe fn aggregate_struct_then_transmute(id: u16) { +unsafe fn aggregate_struct_then_transmute(id: u16, thin: *const u8) { // CHECK: opaque::(copy _1) let a = MyId(id); opaque(std::intrinsics::transmute::<_, u16>(a)); @@ -969,6 +969,18 @@ unsafe fn aggregate_struct_then_transmute(id: u16) { // CHECK: opaque::(move [[TEMP]]) let g = Pair(id, id); opaque(std::intrinsics::transmute_unchecked::<_, u16>(g)); + + // CHECK: opaque::(copy _1) + let h = (id,); + opaque(std::intrinsics::transmute::<_, u16>(h)); + + // CHECK: opaque::(copy _1) + let i = [id]; + opaque(std::intrinsics::transmute::<_, u16>(i)); + + // CHECK: opaque::<*const u8>(copy _2) + let j: *const i32 = std::intrinsics::aggregate_raw_ptr(thin, ()); + opaque(std::intrinsics::transmute::<_, *const u8>(j)); } unsafe fn transmute_then_transmute_again(a: u32, c: char) {