@@ -130,7 +130,11 @@ class SelectOptimizeImpl {
130
130
class SelectLike {
131
131
SelectLike (Instruction *I) : I(I) {}
132
132
133
+ // / The select (/or) instruction.
133
134
Instruction *I;
135
+ // / Whether this select is inverted, "not(cond), FalseVal, TrueVal", as
136
+ // / opposed to the original condition.
137
+ bool Inverted = false ;
134
138
135
139
public:
136
140
// / Match a select or select-like instruction, returning a SelectLike.
@@ -153,14 +157,22 @@ class SelectOptimizeImpl {
153
157
bool isValid () { return I; }
154
158
operator bool () { return isValid (); }
155
159
160
+ // / Invert the select by inverting the condition and switching the operands.
161
+ void setInverted () {
162
+ assert (!Inverted && " Trying to invert and inverted SelectLike" );
163
+ assert (isa<Instruction>(getCondition ()) &&
164
+ cast<Instruction>(getCondition ())->getOpcode () ==
165
+ Instruction::Xor);
166
+ Inverted = true ;
167
+ }
168
+ bool isInverted () const { return Inverted; }
169
+
156
170
Instruction *getI () { return I; }
157
171
const Instruction *getI () const { return I; }
158
172
159
173
Type *getType () const { return I->getType (); }
160
174
161
- // / Return the condition for the SelectLike instruction. For example the
162
- // / condition of a select or c in `or(zext(c), x)`
163
- Value *getCondition () const {
175
+ Value *getNonInvertedCondition () const {
164
176
if (auto *Sel = dyn_cast<SelectInst>(I))
165
177
return Sel->getCondition ();
166
178
// Or(zext) case
@@ -177,11 +189,22 @@ class SelectOptimizeImpl {
177
189
llvm_unreachable (" Unhandled case in getCondition" );
178
190
}
179
191
192
+ // / Return the condition for the SelectLike instruction. For example the
193
+ // / condition of a select or c in `or(zext(c), x)`
194
+ Value *getCondition () const {
195
+ Value *CC = getNonInvertedCondition ();
196
+ if (Inverted)
197
+ return cast<Instruction>(CC)->getOperand (0 );
198
+ return CC;
199
+ }
200
+
180
201
// / Return the true value for the SelectLike instruction. Note this may not
181
202
// / exist for all SelectLike instructions. For example, for `or(zext(c), x)`
182
203
// / the true value would be `or(x,1)`. As this value does not exist, nullptr
183
204
// / is returned.
184
- Value *getTrueValue () const {
205
+ Value *getTrueValue (bool HonorInverts = true ) const {
206
+ if (Inverted && HonorInverts)
207
+ return getFalseValue (false );
185
208
if (auto *Sel = dyn_cast<SelectInst>(I))
186
209
return Sel->getTrueValue ();
187
210
// Or(zext) case - The true value is Or(X), so return nullptr as the value
@@ -195,7 +218,9 @@ class SelectOptimizeImpl {
195
218
// / Return the false value for the SelectLike instruction. For example the
196
219
// / getFalseValue of a select or `x` in `or(zext(c), x)` (which is
197
220
// / `select(c, x|1, x)`)
198
- Value *getFalseValue () const {
221
+ Value *getFalseValue (bool HonorInverts = true ) const {
222
+ if (Inverted && HonorInverts)
223
+ return getTrueValue (false );
199
224
if (auto *Sel = dyn_cast<SelectInst>(I))
200
225
return Sel->getFalseValue ();
201
226
// Or(zext) case - return the operand which is not the zext.
@@ -216,8 +241,8 @@ class SelectOptimizeImpl {
216
241
// / InstCostMap. This may need to be generated for select-like instructions.
217
242
Scaled64 getTrueOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
218
243
const TargetTransformInfo *TTI) {
219
- if (auto *Sel = dyn_cast <SelectInst>(I))
220
- if (auto *I = dyn_cast<Instruction>(Sel-> getTrueValue ()))
244
+ if (isa <SelectInst>(I))
245
+ if (auto *I = dyn_cast<Instruction>(getTrueValue ()))
221
246
return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
222
247
: Scaled64::getZero ();
223
248
@@ -242,8 +267,8 @@ class SelectOptimizeImpl {
242
267
Scaled64
243
268
getFalseOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
244
269
const TargetTransformInfo *TTI) {
245
- if (auto *Sel = dyn_cast <SelectInst>(I))
246
- if (auto *I = dyn_cast<Instruction>(Sel-> getFalseValue ()))
270
+ if (isa <SelectInst>(I))
271
+ if (auto *I = dyn_cast<Instruction>(getFalseValue ()))
247
272
return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
248
273
: Scaled64::getZero ();
249
274
@@ -510,9 +535,10 @@ getTrueOrFalseValue(SelectOptimizeImpl::SelectLike SI, bool isTrue,
510
535
for (SelectInst *DefSI = dyn_cast<SelectInst>(SI.getI ());
511
536
DefSI != nullptr && Selects.count (DefSI);
512
537
DefSI = dyn_cast<SelectInst>(V)) {
513
- assert (DefSI->getCondition () == SI.getCondition () &&
514
- " The condition of DefSI does not match with SI" );
515
- V = (isTrue ? DefSI->getTrueValue () : DefSI->getFalseValue ());
538
+ if (DefSI->getCondition () == SI.getCondition ())
539
+ V = (isTrue ? DefSI->getTrueValue () : DefSI->getFalseValue ());
540
+ else // Handle inverted SI
541
+ V = (!isTrue ? DefSI->getTrueValue () : DefSI->getFalseValue ());
516
542
}
517
543
518
544
if (isa<BinaryOperator>(SI.getI ())) {
@@ -634,16 +660,17 @@ void SelectOptimizeImpl::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
634
660
635
661
// Move any debug/pseudo instructions that were in-between the select
636
662
// group to the newly-created end block.
637
- SmallVector<Instruction *, 2 > DebugPseudoINS ;
663
+ SmallVector<Instruction *, 2 > SinkInstrs ;
638
664
auto DIt = SI.getI ()->getIterator ();
639
665
while (&*DIt != LastSI.getI ()) {
640
666
if (DIt->isDebugOrPseudoInst ())
641
- DebugPseudoINS.push_back (&*DIt);
667
+ SinkInstrs.push_back (&*DIt);
668
+ if (match (&*DIt, m_Not (m_Specific (SI.getCondition ()))))
669
+ SinkInstrs.push_back (&*DIt);
642
670
DIt++;
643
671
}
644
- for (auto *DI : DebugPseudoINS) {
672
+ for (auto *DI : SinkInstrs)
645
673
DI->moveBeforePreserving (&*EndBlock->getFirstInsertionPt ());
646
- }
647
674
648
675
// Duplicate implementation for DbgRecords, the non-instruction debug-info
649
676
// format. Helper lambda for moving DbgRecords to the end block.
@@ -765,6 +792,13 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
765
792
++BBIt;
766
793
continue ;
767
794
}
795
+
796
+ // Skip not(select, if the not is part of the same select group
797
+ if (match (NI, m_Not (m_Specific (SI.getCondition ())))) {
798
+ ++BBIt;
799
+ continue ;
800
+ }
801
+
768
802
// We only allow selects in the same group, not other select-like
769
803
// instructions.
770
804
if (!isa<SelectInst>(NI))
@@ -773,6 +807,10 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
773
807
SelectLike NSI = SelectLike::match (NI);
774
808
if (NSI && SI.getCondition () == NSI.getCondition ()) {
775
809
SIGroup.push_back (NSI);
810
+ } else if (NSI && match (NSI.getCondition (),
811
+ m_Not (m_Specific (SI.getCondition ())))) {
812
+ NSI.setInverted ();
813
+ SIGroup.push_back (NSI);
776
814
} else
777
815
break ;
778
816
++BBIt;
@@ -783,6 +821,12 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
783
821
if (!isSelectKindSupported (SI))
784
822
continue ;
785
823
824
+ LLVM_DEBUG ({
825
+ dbgs () << " New Select group with\n " ;
826
+ for (auto SI : SIGroup)
827
+ dbgs () << " " << *SI.getI () << " \n " ;
828
+ });
829
+
786
830
SIGroups.push_back (SIGroup);
787
831
}
788
832
}
0 commit comments