@@ -978,12 +978,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
978978 // we can't always know exactly what the metadata are.
979979 // To allow things like `*mut (?A, ?T)` <-> `*mut (?B, ?T)`,
980980 // it's fine to get a projection as the type.
981- // FIXME: Would it be worth trying to normalize, rather than
982- // just accepting the projection? Or are the types in the
983- // Cast realistically about as normalized as we can get anyway?
984981 Value :: Cast { kind : CastKind :: PtrToPtr , value : inner, from, to }
985- if from. pointee_metadata_ty_or_projection ( self . tcx )
986- == to. pointee_metadata_ty_or_projection ( self . tcx ) =>
982+ if self . pointers_have_same_metadata ( * from, * to) =>
987983 {
988984 arg_index = * inner;
989985 was_updated = true ;
@@ -1054,7 +1050,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10541050 rhs_operand : & mut Operand < ' tcx > ,
10551051 location : Location ,
10561052 ) -> Option < VnIndex > {
1057-
10581053 let lhs = self . simplify_operand ( lhs_operand, location) ;
10591054 let rhs = self . simplify_operand ( rhs_operand, location) ;
10601055 // Only short-circuit options after we called `simplify_operand`
@@ -1068,13 +1063,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10681063 // types of both casts and the metadata all match.
10691064 if let BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge = op
10701065 && lhs_ty. is_any_ptr ( )
1071- && let Value :: Cast { kind : CastKind :: PtrToPtr , value : lhs_value, from : lhs_from, .. } =
1072- self . get ( lhs)
1073- && let Value :: Cast { kind : CastKind :: PtrToPtr , value : rhs_value, from : rhs_from, .. } =
1074- self . get ( rhs)
1066+ && let Value :: Cast {
1067+ kind : CastKind :: PtrToPtr , value : lhs_value, from : lhs_from, ..
1068+ } = self . get ( lhs)
1069+ && let Value :: Cast {
1070+ kind : CastKind :: PtrToPtr , value : rhs_value, from : rhs_from, ..
1071+ } = self . get ( rhs)
10751072 && lhs_from == rhs_from
1076- && lhs_from. pointee_metadata_ty_or_projection ( self . tcx )
1077- == lhs_ty. pointee_metadata_ty_or_projection ( self . tcx )
1073+ && self . pointers_have_same_metadata ( * lhs_from, lhs_ty)
10781074 {
10791075 lhs = * lhs_value;
10801076 rhs = * rhs_value;
@@ -1254,14 +1250,33 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
12541250 }
12551251 }
12561252
1253+ // PtrToPtr-then-PtrToPtr can skip the intermediate step
12571254 if let PtrToPtr = kind
12581255 && let Value :: Cast { kind : inner_kind, value : inner_value, from : inner_from, to : _ } =
12591256 * self . get ( value)
12601257 && let PtrToPtr = inner_kind
12611258 {
12621259 from = inner_from;
12631260 value = inner_value;
1264- * kind = PtrToPtr ;
1261+ was_updated = true ;
1262+ if inner_from == to {
1263+ return Some ( inner_value) ;
1264+ }
1265+ }
1266+
1267+ // PtrToPtr-then-Transmute can just transmute the original, so long as the
1268+ // PtrToPtr didn't change metadata (and thus the size of the pointer)
1269+ if let Transmute = kind
1270+ && let Value :: Cast {
1271+ kind : PtrToPtr ,
1272+ value : inner_value,
1273+ from : inner_from,
1274+ to : inner_to,
1275+ } = * self . get ( value)
1276+ && self . pointers_have_same_metadata ( inner_from, inner_to)
1277+ {
1278+ from = inner_from;
1279+ value = inner_value;
12651280 was_updated = true ;
12661281 if inner_from == to {
12671282 return Some ( inner_value) ;
@@ -1315,6 +1330,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
13151330 // Fallback: a symbolic `Len`.
13161331 Some ( self . insert ( Value :: Len ( inner) ) )
13171332 }
1333+
1334+ fn pointers_have_same_metadata ( & self , left_ptr_ty : Ty < ' tcx > , right_ptr_ty : Ty < ' tcx > ) -> bool {
1335+ let left_meta_ty = left_ptr_ty. pointee_metadata_ty_or_projection ( self . tcx ) ;
1336+ let right_meta_ty = right_ptr_ty. pointee_metadata_ty_or_projection ( self . tcx ) ;
1337+ if left_meta_ty == right_meta_ty {
1338+ true
1339+ } else if let Ok ( left) =
1340+ self . tcx . try_normalize_erasing_regions ( self . param_env , left_meta_ty)
1341+ && let Ok ( right) = self . tcx . try_normalize_erasing_regions ( self . param_env , right_meta_ty)
1342+ {
1343+ left == right
1344+ } else {
1345+ false
1346+ }
1347+ }
13181348}
13191349
13201350fn op_to_prop_const < ' tcx > (
0 commit comments