[PATCH] D93842: [EarlyCSE] Use m_LogicalAnd/Or matchers to handle branch conditions

Juneyoung Lee via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 27 11:28:15 PST 2020


aqjune created this revision.
aqjune added reviewers: nikic, spatel, lebedev.ri.
Herald added a subscriber: hiraditya.
aqjune requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

EarlyCSE's handleBranchCondition says:

  // If the condition is AND operation, we can propagate its operands into the
  // true branch. If it is OR operation, we can propagate them into the false
  // branch.

This holds for the corresponding select patterns as well.

This is a part of an ongoing work for disabling buggy select->and/or transformations.
See llvm.org/pr48353 and D93065 <https://reviews.llvm.org/D93065> for more context


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D93842

Files:
  llvm/lib/Transforms/Scalar/EarlyCSE.cpp
  llvm/test/Transforms/EarlyCSE/and_or.ll


Index: llvm/test/Transforms/EarlyCSE/and_or.ll
===================================================================
--- llvm/test/Transforms/EarlyCSE/and_or.ll
+++ llvm/test/Transforms/EarlyCSE/and_or.ll
@@ -62,8 +62,7 @@
 ; CHECK-NEXT:    [[AND_COND:%.*]] = select i1 [[COND]], i1 [[C:%.*]], i1 false
 ; CHECK-NEXT:    br i1 [[AND_COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
 ; CHECK:       if.true:
-; CHECK-NEXT:    [[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT:    ret i32 [[X]]
+; CHECK-NEXT:    ret i32 [[A]]
 ; CHECK:       if.false:
 ; CHECK-NEXT:    [[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
 ; CHECK-NEXT:    ret i32 [[Y]]
@@ -122,8 +121,7 @@
 ; CHECK-NEXT:    [[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
 ; CHECK-NEXT:    ret i32 [[X]]
 ; CHECK:       if.false:
-; CHECK-NEXT:    [[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT:    ret i32 [[Y]]
+; CHECK-NEXT:    ret i32 [[B]]
 ;
 entry:
   %cond = icmp slt i32 %a, %b
@@ -179,8 +177,7 @@
 ; CHECK-NEXT:    [[AND_COND2:%.*]] = select i1 [[AND_COND1]], i1 [[C2:%.*]], i1 false
 ; CHECK-NEXT:    br i1 [[AND_COND2]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
 ; CHECK:       if.true:
-; CHECK-NEXT:    [[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT:    ret i32 [[X]]
+; CHECK-NEXT:    ret i32 [[A]]
 ; CHECK:       if.false:
 ; CHECK-NEXT:    [[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
 ; CHECK-NEXT:    ret i32 [[Y]]
@@ -243,8 +240,7 @@
 ; CHECK-NEXT:    [[X:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
 ; CHECK-NEXT:    ret i32 [[X]]
 ; CHECK:       if.false:
-; CHECK-NEXT:    [[Y:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT:    ret i32 [[Y]]
+; CHECK-NEXT:    ret i32 [[B]]
 ;
 entry:
   %cond = icmp slt i32 %a, %b
Index: llvm/lib/Transforms/Scalar/EarlyCSE.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -1033,9 +1033,14 @@
   auto *TorF = (BI->getSuccessor(0) == BB)
                    ? ConstantInt::getTrue(BB->getContext())
                    : ConstantInt::getFalse(BB->getContext());
-  auto MatchBinOp = [](Instruction *I, unsigned Opcode) {
-    if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(I))
-      return BOp->getOpcode() == Opcode;
+  auto MatchBinOp = [](Instruction *I, unsigned Opcode, Value *&LHS,
+                       Value *&RHS) {
+    if (Opcode == Instruction::And &&
+        match(I, m_LogicalAnd(m_Value(LHS), m_Value(RHS))))
+      return true;
+    else if (Opcode == Instruction::Or &&
+             match(I, m_LogicalOr(m_Value(LHS), m_Value(RHS))))
+      return true;
     return false;
   };
   // If the condition is AND operation, we can propagate its operands into the
@@ -1066,9 +1071,10 @@
       }
     }
 
-    if (MatchBinOp(Curr, PropagateOpcode))
-      for (auto &Op : cast<BinaryOperator>(Curr)->operands())
-        if (Instruction *OPI = dyn_cast<Instruction>(Op))
+    Value *LHS = nullptr, *RHS = nullptr;
+    if (MatchBinOp(Curr, PropagateOpcode, LHS, RHS)) {}
+      for (auto &Op : { LHS, RHS })
+        if (Instruction *OPI = dyn_cast_or_null<Instruction>(Op))
           if (SimpleValue::canHandle(OPI) && Visited.insert(OPI).second)
             WorkList.push_back(OPI);
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93842.313795.patch
Type: text/x-patch
Size: 3352 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201227/a27576ff/attachment.bin>


More information about the llvm-commits mailing list