@@ -1378,7 +1378,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1378
1378
1379
1379
let mut was_updated = false ;
1380
1380
1381
- // If that cast just casts away the metadata again,
1381
+ // Transmuting `*const T` <=> `*mut T` is just a pointer cast,
1382
+ // which we might be able to merge with other ones later.
1383
+ if let Transmute = kind
1384
+ && let ty:: RawPtr ( from_pointee, _) = from. kind ( )
1385
+ && let ty:: RawPtr ( to_pointee, _) = to. kind ( )
1386
+ && from_pointee == to_pointee
1387
+ {
1388
+ * kind = PtrToPtr ;
1389
+ was_updated = true ;
1390
+ }
1391
+
1392
+ // If a cast just casts away the metadata again, then we can get it by
1393
+ // casting the original thin pointer passed to `from_raw_parts`
1382
1394
if let PtrToPtr = kind
1383
1395
&& let Value :: Aggregate ( AggregateTy :: RawPtr { data_pointer_ty, .. } , _, fields) =
1384
1396
self . get ( value)
@@ -1407,6 +1419,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1407
1419
}
1408
1420
}
1409
1421
1422
+ // Aggregate-then-Transmute can just transmute the original field value,
1423
+ // so long as the type is transparent over only that one single field.
1424
+ if let Transmute = kind
1425
+ && let Value :: Aggregate (
1426
+ AggregateTy :: Def ( aggregate_did, aggregate_args) ,
1427
+ FIRST_VARIANT ,
1428
+ field_values,
1429
+ ) = self . get ( value)
1430
+ && let [ single_field_value] = * * field_values
1431
+ && let adt = self . tcx . adt_def ( aggregate_did)
1432
+ && adt. is_struct ( )
1433
+ && adt. repr ( ) . transparent ( )
1434
+ {
1435
+ let field_ty = adt. non_enum_variant ( ) . single_field ( ) . ty ( self . tcx , aggregate_args) ;
1436
+ from = field_ty;
1437
+ value = single_field_value;
1438
+ was_updated = true ;
1439
+ if field_ty == to {
1440
+ return Some ( single_field_value) ;
1441
+ }
1442
+ }
1443
+
1410
1444
// PtrToPtr-then-Transmute can just transmute the original, so long as the
1411
1445
// PtrToPtr didn't change metadata (and thus the size of the pointer)
1412
1446
if let Transmute = kind
@@ -1426,6 +1460,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1426
1460
}
1427
1461
}
1428
1462
1463
+ // PtrToPtr-then-Transmute can just transmute the original, so long as the
1464
+ // PtrToPtr didn't change metadata (and thus the size of the pointer)
1465
+ if let PtrToPtr = kind
1466
+ && let Value :: Cast {
1467
+ kind : Transmute ,
1468
+ value : inner_value,
1469
+ from : inner_from,
1470
+ to : _inner_to,
1471
+ } = * self . get ( value)
1472
+ && self . pointers_have_same_metadata ( from, to)
1473
+ {
1474
+ * kind = Transmute ;
1475
+ from = inner_from;
1476
+ value = inner_value;
1477
+ was_updated = true ;
1478
+ if inner_from == to {
1479
+ return Some ( inner_value) ;
1480
+ }
1481
+ }
1482
+
1429
1483
if was_updated && let Some ( op) = self . try_as_operand ( value, location) {
1430
1484
* operand = op;
1431
1485
}
0 commit comments