@@ -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 an 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,24 @@ 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
+ // For inverted conditions the CC is checked when created to be a not
197
+ // (xor) instruction.
198
+ if (Inverted)
199
+ return cast<Instruction>(CC)->getOperand (0 );
200
+ return CC;
201
+ }
202
+
180
203
// / Return the true value for the SelectLike instruction. Note this may not
181
204
// / exist for all SelectLike instructions. For example, for `or(zext(c), x)`
182
205
// / the true value would be `or(x,1)`. As this value does not exist, nullptr
183
206
// / is returned.
184
- Value *getTrueValue () const {
207
+ Value *getTrueValue (bool HonorInverts = true ) const {
208
+ if (Inverted && HonorInverts)
209
+ return getFalseValue (/* HonorInverts=*/ false );
185
210
if (auto *Sel = dyn_cast<SelectInst>(I))
186
211
return Sel->getTrueValue ();
187
212
// Or(zext) case - The true value is Or(X), so return nullptr as the value
@@ -195,7 +220,9 @@ class SelectOptimizeImpl {
195
220
// / Return the false value for the SelectLike instruction. For example the
196
221
// / getFalseValue of a select or `x` in `or(zext(c), x)` (which is
197
222
// / `select(c, x|1, x)`)
198
- Value *getFalseValue () const {
223
+ Value *getFalseValue (bool HonorInverts = true ) const {
224
+ if (Inverted && HonorInverts)
225
+ return getTrueValue (/* HonorInverts=*/ false );
199
226
if (auto *Sel = dyn_cast<SelectInst>(I))
200
227
return Sel->getFalseValue ();
201
228
// Or(zext) case - return the operand which is not the zext.
@@ -216,8 +243,8 @@ class SelectOptimizeImpl {
216
243
// / InstCostMap. This may need to be generated for select-like instructions.
217
244
Scaled64 getTrueOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
218
245
const TargetTransformInfo *TTI) {
219
- if (auto *Sel = dyn_cast <SelectInst>(I))
220
- if (auto *I = dyn_cast<Instruction>(Sel-> getTrueValue ()))
246
+ if (isa <SelectInst>(I))
247
+ if (auto *I = dyn_cast<Instruction>(getTrueValue ()))
221
248
return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
222
249
: Scaled64::getZero ();
223
250
@@ -242,8 +269,8 @@ class SelectOptimizeImpl {
242
269
Scaled64
243
270
getFalseOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
244
271
const TargetTransformInfo *TTI) {
245
- if (auto *Sel = dyn_cast <SelectInst>(I))
246
- if (auto *I = dyn_cast<Instruction>(Sel-> getFalseValue ()))
272
+ if (isa <SelectInst>(I))
273
+ if (auto *I = dyn_cast<Instruction>(getFalseValue ()))
247
274
return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
248
275
: Scaled64::getZero ();
249
276
@@ -510,9 +537,10 @@ getTrueOrFalseValue(SelectOptimizeImpl::SelectLike SI, bool isTrue,
510
537
for (SelectInst *DefSI = dyn_cast<SelectInst>(SI.getI ());
511
538
DefSI != nullptr && Selects.count (DefSI);
512
539
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 ());
540
+ if (DefSI->getCondition () == SI.getCondition ())
541
+ V = (isTrue ? DefSI->getTrueValue () : DefSI->getFalseValue ());
542
+ else // Handle inverted SI
543
+ V = (!isTrue ? DefSI->getTrueValue () : DefSI->getFalseValue ());
516
544
}
517
545
518
546
if (isa<BinaryOperator>(SI.getI ())) {
@@ -632,18 +660,19 @@ void SelectOptimizeImpl::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
632
660
// Delete the unconditional branch that was just created by the split.
633
661
StartBlock->getTerminator ()->eraseFromParent ();
634
662
635
- // Move any debug/pseudo instructions that were in-between the select
636
- // group to the newly-created end block.
637
- SmallVector<Instruction *, 2 > DebugPseudoINS ;
663
+ // Move any debug/pseudo instructions and not's that were in-between the
664
+ // select group to the newly-created end block.
665
+ SmallVector<Instruction *, 2 > SinkInstrs ;
638
666
auto DIt = SI.getI ()->getIterator ();
639
667
while (&*DIt != LastSI.getI ()) {
640
668
if (DIt->isDebugOrPseudoInst ())
641
- DebugPseudoINS.push_back (&*DIt);
669
+ SinkInstrs.push_back (&*DIt);
670
+ if (match (&*DIt, m_Not (m_Specific (SI.getCondition ()))))
671
+ SinkInstrs.push_back (&*DIt);
642
672
DIt++;
643
673
}
644
- for (auto *DI : DebugPseudoINS) {
674
+ for (auto *DI : SinkInstrs)
645
675
DI->moveBeforePreserving (&*EndBlock->getFirstInsertionPt ());
646
- }
647
676
648
677
// Duplicate implementation for DbgRecords, the non-instruction debug-info
649
678
// format. Helper lambda for moving DbgRecords to the end block.
@@ -765,6 +794,13 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
765
794
++BBIt;
766
795
continue ;
767
796
}
797
+
798
+ // Skip not(select(..)), if the not is part of the same select group
799
+ if (match (NI, m_Not (m_Specific (SI.getCondition ())))) {
800
+ ++BBIt;
801
+ continue ;
802
+ }
803
+
768
804
// We only allow selects in the same group, not other select-like
769
805
// instructions.
770
806
if (!isa<SelectInst>(NI))
@@ -773,6 +809,10 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
773
809
SelectLike NSI = SelectLike::match (NI);
774
810
if (NSI && SI.getCondition () == NSI.getCondition ()) {
775
811
SIGroup.push_back (NSI);
812
+ } else if (NSI && match (NSI.getCondition (),
813
+ m_Not (m_Specific (SI.getCondition ())))) {
814
+ NSI.setInverted ();
815
+ SIGroup.push_back (NSI);
776
816
} else
777
817
break ;
778
818
++BBIt;
@@ -783,6 +823,12 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
783
823
if (!isSelectKindSupported (SI))
784
824
continue ;
785
825
826
+ LLVM_DEBUG ({
827
+ dbgs () << " New Select group with\n " ;
828
+ for (auto SI : SIGroup)
829
+ dbgs () << " " << *SI.getI () << " \n " ;
830
+ });
831
+
786
832
SIGroups.push_back (SIGroup);
787
833
}
788
834
}
0 commit comments