@@ -130,7 +130,11 @@ class SelectOptimizeImpl {
130130 class SelectLike {
131131 SelectLike (Instruction *I) : I(I) {}
132132
133+ // / The select (/or) instruction.
133134 Instruction *I;
135+ // / Whether this select is inverted, "not(cond), FalseVal, TrueVal", as
136+ // / opposed to the original condition.
137+ bool Inverted = false ;
134138
135139 public:
136140 // / Match a select or select-like instruction, returning a SelectLike.
@@ -153,14 +157,22 @@ class SelectOptimizeImpl {
153157 bool isValid () { return I; }
154158 operator bool () { return isValid (); }
155159
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+
156170 Instruction *getI () { return I; }
157171 const Instruction *getI () const { return I; }
158172
159173 Type *getType () const { return I->getType (); }
160174
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 {
164176 if (auto *Sel = dyn_cast<SelectInst>(I))
165177 return Sel->getCondition ();
166178 // Or(zext) case
@@ -177,11 +189,24 @@ class SelectOptimizeImpl {
177189 llvm_unreachable (" Unhandled case in getCondition" );
178190 }
179191
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+
180203 // / Return the true value for the SelectLike instruction. Note this may not
181204 // / exist for all SelectLike instructions. For example, for `or(zext(c), x)`
182205 // / the true value would be `or(x,1)`. As this value does not exist, nullptr
183206 // / is returned.
184- Value *getTrueValue () const {
207+ Value *getTrueValue (bool HonorInverts = true ) const {
208+ if (Inverted && HonorInverts)
209+ return getFalseValue (/* HonorInverts=*/ false );
185210 if (auto *Sel = dyn_cast<SelectInst>(I))
186211 return Sel->getTrueValue ();
187212 // Or(zext) case - The true value is Or(X), so return nullptr as the value
@@ -195,7 +220,9 @@ class SelectOptimizeImpl {
195220 // / Return the false value for the SelectLike instruction. For example the
196221 // / getFalseValue of a select or `x` in `or(zext(c), x)` (which is
197222 // / `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 );
199226 if (auto *Sel = dyn_cast<SelectInst>(I))
200227 return Sel->getFalseValue ();
201228 // Or(zext) case - return the operand which is not the zext.
@@ -216,8 +243,8 @@ class SelectOptimizeImpl {
216243 // / InstCostMap. This may need to be generated for select-like instructions.
217244 Scaled64 getTrueOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
218245 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 ()))
221248 return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
222249 : Scaled64::getZero ();
223250
@@ -242,8 +269,8 @@ class SelectOptimizeImpl {
242269 Scaled64
243270 getFalseOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
244271 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 ()))
247274 return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
248275 : Scaled64::getZero ();
249276
@@ -510,9 +537,10 @@ getTrueOrFalseValue(SelectOptimizeImpl::SelectLike SI, bool isTrue,
510537 for (SelectInst *DefSI = dyn_cast<SelectInst>(SI.getI ());
511538 DefSI != nullptr && Selects.count (DefSI);
512539 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 ());
516544 }
517545
518546 if (isa<BinaryOperator>(SI.getI ())) {
@@ -632,18 +660,19 @@ void SelectOptimizeImpl::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
632660 // Delete the unconditional branch that was just created by the split.
633661 StartBlock->getTerminator ()->eraseFromParent ();
634662
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 ;
638666 auto DIt = SI.getI ()->getIterator ();
639667 while (&*DIt != LastSI.getI ()) {
640668 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);
642672 DIt++;
643673 }
644- for (auto *DI : DebugPseudoINS) {
674+ for (auto *DI : SinkInstrs)
645675 DI->moveBeforePreserving (&*EndBlock->getFirstInsertionPt ());
646- }
647676
648677 // Duplicate implementation for DbgRecords, the non-instruction debug-info
649678 // format. Helper lambda for moving DbgRecords to the end block.
@@ -765,6 +794,13 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
765794 ++BBIt;
766795 continue ;
767796 }
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+
768804 // We only allow selects in the same group, not other select-like
769805 // instructions.
770806 if (!isa<SelectInst>(NI))
@@ -773,6 +809,10 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
773809 SelectLike NSI = SelectLike::match (NI);
774810 if (NSI && SI.getCondition () == NSI.getCondition ()) {
775811 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);
776816 } else
777817 break ;
778818 ++BBIt;
@@ -783,6 +823,12 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
783823 if (!isSelectKindSupported (SI))
784824 continue ;
785825
826+ LLVM_DEBUG ({
827+ dbgs () << " New Select group with\n " ;
828+ for (auto SI : SIGroup)
829+ dbgs () << " " << *SI.getI () << " \n " ;
830+ });
831+
786832 SIGroups.push_back (SIGroup);
787833 }
788834 }
0 commit comments