[PATCH] D103959: [LoopDeletion] Handle Phis with similar inputs from different block

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 9 05:46:31 PDT 2021


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

This patch lifts the requirement to have the only incoming live blocks for Phis. There can be multiple live blocks
if hte same value comes to phi from all of them.


https://reviews.llvm.org/D103959

Files:
  llvm/lib/Transforms/Scalar/LoopDeletion.cpp
  llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll


Index: llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
+++ llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
@@ -667,14 +667,14 @@
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 4, [[SUM]]
 ; CHECK-NEXT:    [[IS_POSITIVE:%.*]] = icmp sgt i32 [[SUB]], 0
 ; CHECK-NEXT:    br i1 [[IS_POSITIVE]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
 ; CHECK:       if.true:
 ; CHECK-NEXT:    br i1 undef, label [[IF_TRUE_1:%.*]], label [[IF_TRUE_2:%.*]]
 ; CHECK:       if.true.1:
-; CHECK-NEXT:    br label [[BACKEDGE]]
+; CHECK-NEXT:    br label [[BACKEDGE:%.*]]
 ; CHECK:       if.true.2:
 ; CHECK-NEXT:    br label [[BACKEDGE]]
 ; CHECK:       if.false:
@@ -685,9 +685,11 @@
 ; CHECK-NEXT:    br label [[BACKEDGE]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[MERGE_PHI:%.*]] = phi i32 [ 0, [[IF_FALSE_1]] ], [ 0, [[IF_FALSE_2]] ], [ [[SUB]], [[IF_TRUE_1]] ], [ [[SUB]], [[IF_TRUE_2]] ]
-; CHECK-NEXT:    [[SUM_NEXT]] = add i32 [[SUM]], [[MERGE_PHI]]
+; CHECK-NEXT:    [[SUM_NEXT:%.*]] = add i32 [[SUM]], [[MERGE_PHI]]
 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[SUM_NEXT]], 4
-; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[BACKEDGE_LOOP_CRIT_EDGE:%.*]], label [[DONE:%.*]]
+; CHECK:       backedge.loop_crit_edge:
+; CHECK-NEXT:    unreachable
 ; CHECK:       done:
 ; CHECK-NEXT:    [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
 ; CHECK-NEXT:    ret i32 [[SUM_NEXT_LCSSA]]
Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -248,20 +248,22 @@
   // Check if there is only one predecessor on 1st iteration. Note that because
   // we iterate in RPOT, we have already visited all its (non-latch)
   // predecessors.
-  auto GetSolePredecessorOnFirstIteration = [&](BasicBlock * BB)->BasicBlock * {
+  auto GetSoleInputOnFirstIteration = [&](PHINode & PN)->Value * {
+    BasicBlock *BB = PN.getParent();
     if (BB == Header)
-      return L->getLoopPredecessor();
-    BasicBlock *OnlyPred = nullptr;
+      return PN.getIncomingValueForBlock(L->getLoopPredecessor());
+    Value *OnlyInput = nullptr;
     for (auto *Pred : predecessors(BB))
-      if (OnlyPred != Pred && LiveEdges.count({ Pred, BB })) {
-        // 2 live preds.
-        if (OnlyPred)
+      if (LiveEdges.count({ Pred, BB })) {
+        Value *Incoming = PN.getIncomingValueForBlock(Pred);
+        // Two inputs.
+        if (OnlyInput && OnlyInput != Incoming)
           return nullptr;
-        OnlyPred = Pred;
+        OnlyInput = Incoming;
       }
 
-    assert(OnlyPred && "No live predecessors?");
-    return OnlyPred;
+    assert(OnlyInput && "No live predecessors?");
+    return OnlyInput;
   };
   DenseMap<Value *, const SCEV *> FirstIterSCEV;
 
@@ -289,17 +291,16 @@
     }
 
     // If this block has only one live pred, map its phis onto their SCEVs.
-    if (auto *OnlyPred = GetSolePredecessorOnFirstIteration(BB))
-      for (auto &PN : BB->phis()) {
-        if (!SE.isSCEVable(PN.getType()))
-          continue;
-        auto *Incoming = PN.getIncomingValueForBlock(OnlyPred);
-        if (DT.dominates(Incoming, BB->getTerminator())) {
-          const SCEV *IncSCEV =
-              getSCEVOnFirstIteration(Incoming, L, SE, FirstIterSCEV);
-          FirstIterSCEV[&PN] = IncSCEV;
-        }
+    for (auto &PN : BB->phis()) {
+      if (!SE.isSCEVable(PN.getType()))
+        continue;
+      auto *Incoming = GetSoleInputOnFirstIteration(PN);
+      if (Incoming && DT.dominates(Incoming, BB->getTerminator())) {
+        const SCEV *IncSCEV =
+            getSCEVOnFirstIteration(Incoming, L, SE, FirstIterSCEV);
+        FirstIterSCEV[&PN] = IncSCEV;
       }
+    }
 
     using namespace PatternMatch;
     ICmpInst::Predicate Pred;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103959.350868.patch
Type: text/x-patch
Size: 4292 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210609/3a415a2f/attachment.bin>


More information about the llvm-commits mailing list