@@ -544,6 +544,12 @@ pub struct SimplifyBranchSame;
544
544
545
545
impl < ' tcx > MirPass < ' tcx > for SimplifyBranchSame {
546
546
fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
547
+ // This optimization is disabled by default for now due to
548
+ // soundness concerns; see issue #89485 and PR #89489.
549
+ if !tcx. sess . opts . debugging_opts . unsound_mir_opts {
550
+ return ;
551
+ }
552
+
547
553
trace ! ( "Running SimplifyBranchSame on {:?}" , body. source) ;
548
554
let finder = SimplifyBranchSameOptimizationFinder { body, tcx } ;
549
555
let opts = finder. find ( ) ;
@@ -706,12 +712,24 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
706
712
let helper = |rhs : & Rvalue < ' tcx > ,
707
713
place : & Place < ' tcx > ,
708
714
variant_index : & VariantIdx ,
715
+ switch_value : u128 ,
709
716
side_to_choose| {
710
717
let place_type = place. ty ( self . body , self . tcx ) . ty ;
711
718
let adt = match * place_type. kind ( ) {
712
719
ty:: Adt ( adt, _) if adt. is_enum ( ) => adt,
713
720
_ => return StatementEquality :: NotEqual ,
714
721
} ;
722
+ // We need to make sure that the switch value that targets the bb with
723
+ // SetDiscriminant is the same as the variant discriminant.
724
+ let variant_discr = adt. discriminant_for_variant ( self . tcx , * variant_index) . val ;
725
+ if variant_discr != switch_value {
726
+ trace ! (
727
+ "NO: variant discriminant {} does not equal switch value {}" ,
728
+ variant_discr,
729
+ switch_value
730
+ ) ;
731
+ return StatementEquality :: NotEqual ;
732
+ }
715
733
let variant_is_fieldless = adt. variants [ * variant_index] . fields . is_empty ( ) ;
716
734
if !variant_is_fieldless {
717
735
trace ! ( "NO: variant {:?} was not fieldless" , variant_index) ;
@@ -740,20 +758,28 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
740
758
(
741
759
StatementKind :: Assign ( box ( _, rhs) ) ,
742
760
StatementKind :: SetDiscriminant { place, variant_index } ,
743
- )
744
- // we need to make sure that the switch value that targets the bb with SetDiscriminant (y), is the same as the variant index
745
- if Some ( variant_index. index ( ) as u128 ) == y_target_and_value. value => {
761
+ ) if y_target_and_value. value . is_some ( ) => {
746
762
// choose basic block of x, as that has the assign
747
- helper ( rhs, place, variant_index, x_target_and_value. target )
763
+ helper (
764
+ rhs,
765
+ place,
766
+ variant_index,
767
+ y_target_and_value. value . unwrap ( ) ,
768
+ x_target_and_value. target ,
769
+ )
748
770
}
749
771
(
750
772
StatementKind :: SetDiscriminant { place, variant_index } ,
751
773
StatementKind :: Assign ( box ( _, rhs) ) ,
752
- )
753
- // we need to make sure that the switch value that targets the bb with SetDiscriminant (x), is the same as the variant index
754
- if Some ( variant_index. index ( ) as u128 ) == x_target_and_value. value => {
774
+ ) if x_target_and_value. value . is_some ( ) => {
755
775
// choose basic block of y, as that has the assign
756
- helper ( rhs, place, variant_index, y_target_and_value. target )
776
+ helper (
777
+ rhs,
778
+ place,
779
+ variant_index,
780
+ x_target_and_value. value . unwrap ( ) ,
781
+ y_target_and_value. target ,
782
+ )
757
783
}
758
784
_ => {
759
785
trace ! ( "NO: statements `{:?}` and `{:?}` not considered equal" , x, y) ;
0 commit comments