[llvm] 703f6a6 - [ConstraintElimination] Support conditions from loop preheaders

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 4 05:58:52 PST 2021


Author: Florian Hahn
Date: 2021-02-04T13:58:32Z
New Revision: 703f6a6828b51cd2b475982a9de2af242dfba97c

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

LOG: [ConstraintElimination] Support conditions from loop preheaders

This patch extends the condition collection logic to allow adding
conditions from pre-headers to loop headers, by allowing cases where the
target block dominates some of its predecessors.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
    llvm/test/Transforms/ConstraintElimination/dom.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index a127f0b391d7..f6a6b4807adf 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -247,6 +247,15 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
     if (!Br || !Br->isConditional())
       continue;
 
+    // Returns true if we can add a known condition from BB to its successor
+    // block Succ. Each predecessor of Succ can either be BB or be dominated by
+    // Succ (e.g. the case when adding a condition from a pre-header to a loop
+    // header).
+    auto CanAdd = [&BB, &DT](BasicBlock *Succ) {
+      return all_of(predecessors(Succ), [&BB, &DT, Succ](BasicBlock *Pred) {
+        return Pred == &BB || DT.dominates(Succ, Pred);
+      });
+    };
     // If the condition is an OR of 2 compares and the false successor only has
     // the current block as predecessor, queue both negated conditions for the
     // false successor.
@@ -254,7 +263,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
     if (match(Br->getCondition(), m_LogicalOr(m_Value(Op0), m_Value(Op1))) &&
         match(Op0, m_Cmp()) && match(Op1, m_Cmp())) {
       BasicBlock *FalseSuccessor = Br->getSuccessor(1);
-      if (FalseSuccessor->getSinglePredecessor()) {
+      if (CanAdd(FalseSuccessor)) {
         WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<CmpInst>(Op0),
                               true);
         WorkList.emplace_back(DT.getNode(FalseSuccessor), cast<CmpInst>(Op1),
@@ -269,7 +278,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
     if (match(Br->getCondition(), m_LogicalAnd(m_Value(Op0), m_Value(Op1))) &&
         match(Op0, m_Cmp()) && match(Op1, m_Cmp())) {
       BasicBlock *TrueSuccessor = Br->getSuccessor(0);
-      if (TrueSuccessor->getSinglePredecessor()) {
+      if (CanAdd(TrueSuccessor)) {
         WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<CmpInst>(Op0),
                               false);
         WorkList.emplace_back(DT.getNode(TrueSuccessor), cast<CmpInst>(Op1),
@@ -281,9 +290,9 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT) {
     auto *CmpI = dyn_cast<CmpInst>(Br->getCondition());
     if (!CmpI)
       continue;
-    if (Br->getSuccessor(0)->getSinglePredecessor())
+    if (CanAdd(Br->getSuccessor(0)))
       WorkList.emplace_back(DT.getNode(Br->getSuccessor(0)), CmpI, false);
-    if (Br->getSuccessor(1)->getSinglePredecessor())
+    if (CanAdd(Br->getSuccessor(1)))
       WorkList.emplace_back(DT.getNode(Br->getSuccessor(1)), CmpI, true);
   }
 

diff  --git a/llvm/test/Transforms/ConstraintElimination/dom.ll b/llvm/test/Transforms/ConstraintElimination/dom.ll
index 424e98742289..1c3e120a8962 100644
--- a/llvm/test/Transforms/ConstraintElimination/dom.ll
+++ b/llvm/test/Transforms/ConstraintElimination/dom.ll
@@ -146,9 +146,9 @@ define void @test_cond_from_preheader(i32 %x, i1 %c) {
 ; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP:%.*]], label [[BB2]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 9
 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[X]], 9
@@ -156,7 +156,7 @@ define void @test_cond_from_preheader(i32 %x, i1 %c) {
 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    ret void
 ; CHECK:       bb2:
 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[X]], 10
@@ -203,9 +203,9 @@ define void @test_cond_from_preheader_successors_flipped(i32 %x, i1 %c) {
 ; CHECK-NEXT:    br i1 [[C_1]], label [[BB2]], label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 11
 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[X]], 11
@@ -213,7 +213,7 @@ define void @test_cond_from_preheader_successors_flipped(i32 %x, i1 %c) {
 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    ret void
 ; CHECK:       bb2:
 ; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[X]], 10
@@ -266,17 +266,17 @@ define void @test_cond_from_preheader_and(i32 %x, i32 %y, i1 %c) {
 ; CHECK-NEXT:    br i1 [[AND]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 9
 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 9
 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ugt i32 [[Y]], 99
-; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i32 [[Y]], 99
-; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[Y]], 100
 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y]], 100
@@ -425,17 +425,17 @@ define void @test_cond_from_preheader_or(i32 %x, i32 %y, i1 %c) {
 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i32 [[X]], 10
-; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i32 [[X]], 11
 ; CHECK-NEXT:    call void @use(i1 [[C_1]])
 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 11
 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i32 [[Y]], 99
-; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    [[F_2:%.*]] = icmp ugt i32 [[Y]], 99
-; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[Y]], 98
 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i32 [[Y]], 98


        


More information about the llvm-commits mailing list