@@ -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 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+
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,22 @@ 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+ if (Inverted)
197+ return cast<Instruction>(CC)->getOperand (0 );
198+ return CC;
199+ }
200+
180201 // / Return the true value for the SelectLike instruction. Note this may not
181202 // / exist for all SelectLike instructions. For example, for `or(zext(c), x)`
182203 // / the true value would be `or(x,1)`. As this value does not exist, nullptr
183204 // / is returned.
184- Value *getTrueValue () const {
205+ Value *getTrueValue (bool HonorInverts = true ) const {
206+ if (Inverted && HonorInverts)
207+ return getFalseValue (false );
185208 if (auto *Sel = dyn_cast<SelectInst>(I))
186209 return Sel->getTrueValue ();
187210 // Or(zext) case - The true value is Or(X), so return nullptr as the value
@@ -195,7 +218,9 @@ class SelectOptimizeImpl {
195218 // / Return the false value for the SelectLike instruction. For example the
196219 // / getFalseValue of a select or `x` in `or(zext(c), x)` (which is
197220 // / `select(c, x|1, x)`)
198- Value *getFalseValue () const {
221+ Value *getFalseValue (bool HonorInverts = true ) const {
222+ if (Inverted && HonorInverts)
223+ return getTrueValue (false );
199224 if (auto *Sel = dyn_cast<SelectInst>(I))
200225 return Sel->getFalseValue ();
201226 // Or(zext) case - return the operand which is not the zext.
@@ -216,8 +241,8 @@ class SelectOptimizeImpl {
216241 // / InstCostMap. This may need to be generated for select-like instructions.
217242 Scaled64 getTrueOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
218243 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 ()))
221246 return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
222247 : Scaled64::getZero ();
223248
@@ -242,8 +267,8 @@ class SelectOptimizeImpl {
242267 Scaled64
243268 getFalseOpCost (DenseMap<const Instruction *, CostInfo> &InstCostMap,
244269 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 ()))
247272 return InstCostMap.contains (I) ? InstCostMap[I].NonPredCost
248273 : Scaled64::getZero ();
249274
@@ -510,9 +535,10 @@ getTrueOrFalseValue(SelectOptimizeImpl::SelectLike SI, bool isTrue,
510535 for (SelectInst *DefSI = dyn_cast<SelectInst>(SI.getI ());
511536 DefSI != nullptr && Selects.count (DefSI);
512537 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 ());
516542 }
517543
518544 if (isa<BinaryOperator>(SI.getI ())) {
@@ -634,16 +660,17 @@ void SelectOptimizeImpl::convertProfitableSIGroups(SelectGroups &ProfSIGroups) {
634660
635661 // Move any debug/pseudo instructions that were in-between the select
636662 // group to the newly-created end block.
637- SmallVector<Instruction *, 2 > DebugPseudoINS ;
663+ SmallVector<Instruction *, 2 > SinkInstrs ;
638664 auto DIt = SI.getI ()->getIterator ();
639665 while (&*DIt != LastSI.getI ()) {
640666 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);
642670 DIt++;
643671 }
644- for (auto *DI : DebugPseudoINS) {
672+ for (auto *DI : SinkInstrs)
645673 DI->moveBeforePreserving (&*EndBlock->getFirstInsertionPt ());
646- }
647674
648675 // Duplicate implementation for DbgRecords, the non-instruction debug-info
649676 // format. Helper lambda for moving DbgRecords to the end block.
@@ -765,6 +792,13 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
765792 ++BBIt;
766793 continue ;
767794 }
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+
768802 // We only allow selects in the same group, not other select-like
769803 // instructions.
770804 if (!isa<SelectInst>(NI))
@@ -773,6 +807,10 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
773807 SelectLike NSI = SelectLike::match (NI);
774808 if (NSI && SI.getCondition () == NSI.getCondition ()) {
775809 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);
776814 } else
777815 break ;
778816 ++BBIt;
@@ -783,6 +821,12 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
783821 if (!isSelectKindSupported (SI))
784822 continue ;
785823
824+ LLVM_DEBUG ({
825+ dbgs () << " New Select group with\n " ;
826+ for (auto SI : SIGroup)
827+ dbgs () << " " << *SI.getI () << " \n " ;
828+ });
829+
786830 SIGroups.push_back (SIGroup);
787831 }
788832 }
0 commit comments