@@ -1368,7 +1368,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1368
1368
1369
1369
let mut was_updated = false ;
1370
1370
1371
- // If that cast just casts away the metadata again,
1371
+ // Transmuting `*const T` <=> `*mut T` is just a pointer cast,
1372
+ // which we might be able to merge with other ones later.
1373
+ if let Transmute = kind
1374
+ && let ty:: RawPtr ( from_pointee, _) = from. kind ( )
1375
+ && let ty:: RawPtr ( to_pointee, _) = to. kind ( )
1376
+ && from_pointee == to_pointee
1377
+ {
1378
+ * kind = PtrToPtr ;
1379
+ was_updated = true ;
1380
+ }
1381
+
1382
+ // If a cast just casts away the metadata again, then we can get it by
1383
+ // casting the original thin pointer passed to `from_raw_parts`
1372
1384
if let PtrToPtr = kind
1373
1385
&& let Value :: Aggregate ( AggregateTy :: RawPtr { data_pointer_ty, .. } , _, fields) =
1374
1386
self . get ( value)
@@ -1397,6 +1409,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1397
1409
}
1398
1410
}
1399
1411
1412
+ // Aggregate-then-Transmute can just transmute the original field value,
1413
+ // so long as the type is transparent over only that one single field.
1414
+ if let Transmute = kind
1415
+ && let Value :: Aggregate (
1416
+ AggregateTy :: Def ( aggregate_did, aggregate_args) ,
1417
+ FIRST_VARIANT ,
1418
+ field_values,
1419
+ ) = self . get ( value)
1420
+ && let [ single_field_value] = * * field_values
1421
+ && let adt = self . tcx . adt_def ( aggregate_did)
1422
+ && adt. is_struct ( )
1423
+ && adt. repr ( ) . transparent ( )
1424
+ {
1425
+ let field_ty = adt. non_enum_variant ( ) . single_field ( ) . ty ( self . tcx , aggregate_args) ;
1426
+ from = field_ty;
1427
+ value = single_field_value;
1428
+ was_updated = true ;
1429
+ if field_ty == to {
1430
+ return Some ( single_field_value) ;
1431
+ }
1432
+ }
1433
+
1400
1434
// PtrToPtr-then-Transmute can just transmute the original, so long as the
1401
1435
// PtrToPtr didn't change metadata (and thus the size of the pointer)
1402
1436
if let Transmute = kind
@@ -1416,6 +1450,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1416
1450
}
1417
1451
}
1418
1452
1453
+ // PtrToPtr-then-Transmute can just transmute the original, so long as the
1454
+ // PtrToPtr didn't change metadata (and thus the size of the pointer)
1455
+ if let PtrToPtr = kind
1456
+ && let Value :: Cast {
1457
+ kind : Transmute ,
1458
+ value : inner_value,
1459
+ from : inner_from,
1460
+ to : _inner_to,
1461
+ } = * self . get ( value)
1462
+ && self . pointers_have_same_metadata ( from, to)
1463
+ {
1464
+ * kind = Transmute ;
1465
+ from = inner_from;
1466
+ value = inner_value;
1467
+ was_updated = true ;
1468
+ if inner_from == to {
1469
+ return Some ( inner_value) ;
1470
+ }
1471
+ }
1472
+
1419
1473
if was_updated && let Some ( op) = self . try_as_operand ( value, location) {
1420
1474
* operand = op;
1421
1475
}
0 commit comments