@@ -6,7 +6,7 @@ use rustc_hir::Mutability;
6
6
use rustc_index:: vec:: Idx ;
7
7
use rustc_middle:: mir:: visit:: { MutVisitor , Visitor } ;
8
8
use rustc_middle:: mir:: {
9
- Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
9
+ BinOp , Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
10
10
} ;
11
11
use rustc_middle:: ty:: { self , TyCtxt } ;
12
12
use std:: mem;
@@ -66,6 +66,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
66
66
* rvalue = Rvalue :: Use ( Operand :: Constant ( box constant) ) ;
67
67
}
68
68
69
+ if let Some ( operand) = self . optimizations . unneeded_not_equal . remove ( & location) {
70
+ debug ! ( "replacing {:?} with {:?}" , rvalue, operand) ;
71
+ * rvalue = Rvalue :: Use ( operand) ;
72
+ }
73
+
69
74
self . super_rvalue ( rvalue, location)
70
75
}
71
76
}
@@ -81,6 +86,23 @@ impl OptimizationFinder<'b, 'tcx> {
81
86
fn new ( body : & ' b Body < ' tcx > , tcx : TyCtxt < ' tcx > ) -> OptimizationFinder < ' b , ' tcx > {
82
87
OptimizationFinder { body, tcx, optimizations : OptimizationList :: default ( ) }
83
88
}
89
+
90
+ fn find_operand_in_ne_false_pattern (
91
+ & self ,
92
+ l : & Operand < ' tcx > ,
93
+ r : & ' a Operand < ' tcx > ,
94
+ ) -> Option < & ' a Operand < ' tcx > > {
95
+ let const_ = l. constant ( ) ?;
96
+ if const_. literal . ty == self . tcx . types . bool
97
+ && const_. literal . val . try_to_bool ( ) == Some ( false )
98
+ {
99
+ if r. place ( ) . is_some ( ) {
100
+ return Some ( r) ;
101
+ }
102
+ }
103
+
104
+ return None ;
105
+ }
84
106
}
85
107
86
108
impl Visitor < ' tcx > for OptimizationFinder < ' b , ' tcx > {
@@ -106,6 +128,18 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
106
128
}
107
129
}
108
130
131
+ // find Ne(_place, false) or Ne(false, _place)
132
+ if let Rvalue :: BinaryOp ( BinOp :: Ne , l, r) = rvalue {
133
+ // (false, _place)
134
+ if let Some ( o) = self . find_operand_in_ne_false_pattern ( l, r) {
135
+ self . optimizations . unneeded_not_equal . insert ( location, o. clone ( ) ) ;
136
+ }
137
+ // (_place, false)
138
+ else if let Some ( o) = self . find_operand_in_ne_false_pattern ( r, l) {
139
+ self . optimizations . unneeded_not_equal . insert ( location, o. clone ( ) ) ;
140
+ }
141
+ }
142
+
109
143
self . super_rvalue ( rvalue, location)
110
144
}
111
145
}
@@ -114,4 +148,5 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
114
148
struct OptimizationList < ' tcx > {
115
149
and_stars : FxHashSet < Location > ,
116
150
arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
151
+ unneeded_not_equal : FxHashMap < Location , Operand < ' tcx > > ,
117
152
}
0 commit comments