[llvm] [InstCombine] Simplify select if it combinated and/or/xor (PR #73362)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 28 11:25:28 PDT 2024
================
@@ -1687,6 +1687,120 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI,
return nullptr;
}
+static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
+ InstCombinerImpl &IC) {
+ ICmpInst::Predicate Pred = ICI->getPredicate();
+ if (!ICmpInst::isEquality(Pred))
+ return nullptr;
+
+ Value *TrueVal = SI.getTrueValue();
+ Value *FalseVal = SI.getFalseValue();
+ Value *CmpLHS = ICI->getOperand(0);
+ Value *CmpRHS = ICI->getOperand(1);
+
+ if (Pred == ICmpInst::ICMP_NE)
+ std::swap(TrueVal, FalseVal);
+
+ // Transform (X == C) ? X : Y -> (X == C) ? C : Y
+ // specific handling for Bitwise operation.
+ // https://alive2.llvm.org/ce/z/mW3eYR
+ // x&y -> (x|y) ^ (x^y) or (x|y) & ~(x^y)
+ // x|y -> (x&y) | (x^y) or (x&y) ^ (x^y)
+ // x^y -> (x|y) ^ (x&y) or (x|y) & ~(x&y)
+ Value *X, *Y;
+ if (!(match(CmpLHS, m_BitwiseLogic(m_Value(X), m_Value(Y)))) ||
+ !(match(TrueVal, m_c_BitwiseLogic(m_Specific(X), m_Specific(Y)))))
+ return nullptr;
+
+ Value *AllOnes = Constant::getAllOnesValue(TrueVal->getType());
+ Value *Null = Constant::getNullValue(TrueVal->getType());
+ Instruction *ISI = &cast<Instruction>(SI);
+ const unsigned AndOps = Instruction::And, OrOps = Instruction::Or,
+ XorOps = Instruction::Xor, NoOps = 0;
+ enum NotMask { None = 0, NotInner, NotRHS };
+
+ auto matchFalseVal = [&](unsigned OuterOpc, unsigned InnerOpc,
+ unsigned NotMask) {
+ auto matchInner = m_c_BinOp(InnerOpc, m_Specific(X), m_Specific(Y));
+ if (OuterOpc == NoOps) {
+ if (match(CmpRHS, m_Zero()))
+ return match(FalseVal, matchInner);
+ else
+ return false;
+ }
----------------
dtcxzyw wrote:
```suggestion
if (OuterOpc == NoOps)
return match(CmpRHS, m_Zero()) &&
return match(FalseVal, matchInner);
```
https://github.com/llvm/llvm-project/pull/73362
More information about the llvm-commits
mailing list