================
@@ -3612,6 +3612,48 @@ Value *InstCombinerImpl::foldBooleanAndOr(Value *LHS,
Value *RHS,
if (Value *Res = foldEqOfParts(LHS, RHS, IsAnd))
return Res;
+ // Handle reassociation-like folding: (A op B) op C --> A op (B op C)
+ // where B and C are ICmps and can be folded.
+ // This handles patterns like:
+ // select (and %cond, icmp1), icmp2, false -> select %cond, folded_icmp,
false
+ // (A & icmp1) & icmp2 -> A & folded_icmp
+ auto TryFold = [&](Value *L, Value *R) -> Value * {
+ Value *A, *B;
+ Instruction::BinaryOps Opcode = IsAnd ? Instruction::And : Instruction::Or;
+
+ // Look through (Op A, B)
+ if (match(L, m_BinOp(Opcode, m_Value(A), m_Value(B))) ||
+ (IsLogical && (IsAnd ? match(L, m_LogicalAnd(m_Value(A), m_Value(B)))
+ : match(L, m_LogicalOr(m_Value(A),
m_Value(B)))))) {
+ for (int i = 0; i < 2; ++i) {
+ Value *InnerCmp = i == 0 ? B : A;
+ Value *Other = i == 0 ? A : B;
+ auto *ICmpInner = dyn_cast<ICmpInst>(InnerCmp);
+ auto *ICmpR = dyn_cast<ICmpInst>(R);
+ if (ICmpInner && ICmpR) {
+ if (Value *Res = foldAndOrOfICmps(ICmpInner, ICmpR, I, IsAnd,
IsLogical)) {
+ if (IsLogical) {
+ if (IsAnd)
+ return Builder.CreateSelect(Other, Res,
+
ConstantInt::getFalse(LHS->getType()));
+ else
+ return Builder.CreateSelect(Other,
ConstantInt::getTrue(LHS->getType()),
+ Res);
+ } else {
+ return Builder.CreateBinOp(Opcode, Other, Res);
+ }
----------------
shiltian wrote:
This level of nesting is insane. Can you use early return or continue instead?
https://github.com/llvm/llvm-project/pull/176590
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits