[llvm] d3f1f7b - [EarlyCSE] Use m_LogicalAnd/Or matchers to handle branch conditions

Juneyoung Lee via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 27 12:36:46 PST 2020


Author: Juneyoung Lee
Date: 2020-12-28T05:36:26+09:00
New Revision: d3f1f7b6bca585b76d40422e8076d59113e3bb80

URL: https://github.com/llvm/llvm-project/commit/d3f1f7b6bca585b76d40422e8076d59113e3bb80
DIFF: https://github.com/llvm/llvm-project/commit/d3f1f7b6bca585b76d40422e8076d59113e3bb80.diff

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

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 for more context

Proof:
and: https://alive2.llvm.org/ce/z/MQWodU
or: https://alive2.llvm.org/ce/z/9GLbB_

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D93842

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index be2860960500..f005f69519f7 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -1033,9 +1033,14 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst,
   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,8 +1071,9 @@ bool EarlyCSE::handleBranchCondition(Instruction *CondInst,
       }
     }
 
-    if (MatchBinOp(Curr, PropagateOpcode))
-      for (auto &Op : cast<BinaryOperator>(Curr)->operands())
+    Value *LHS, *RHS;
+    if (MatchBinOp(Curr, PropagateOpcode, LHS, RHS))
+      for (auto &Op : { LHS, RHS })
         if (Instruction *OPI = dyn_cast<Instruction>(Op))
           if (SimpleValue::canHandle(OPI) && Visited.insert(OPI).second)
             WorkList.push_back(OPI);

diff  --git a/llvm/test/Transforms/EarlyCSE/and_or.ll b/llvm/test/Transforms/EarlyCSE/and_or.ll
index 4a63e28b5ffa..2c04e7e3cf90 100644
--- a/llvm/test/Transforms/EarlyCSE/and_or.ll
+++ b/llvm/test/Transforms/EarlyCSE/and_or.ll
@@ -62,8 +62,7 @@ define i32 @test_02_select(i32 %a, i32 %b, i1 %c) {
 ; 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 @@ define i32 @test_03_select(i32 %a, i32 %b, i1 %c) {
 ; 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 @@ define i32 @test_04_select(i32 %a, i32 %b, i1 %c1, i1 %c2) {
 ; 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 @@ define i32 @test_05_select(i32 %a, i32 %b, i1 %c1, i1 %c2) {
 ; 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


        


More information about the llvm-commits mailing list