================
@@ -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

Reply via email to