[PATCH] D100792: [LoopInterchange] Handle lcssa PHIs with multiple predecessors

Congzhe Cao via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 19 13:38:55 PDT 2021


congzhe created this revision.
congzhe added reviewers: bmahjour, fhahn, Whitney.
congzhe added a project: LLVM.
Herald added a subscriber: hiraditya.
congzhe requested review of this revision.
Herald added a subscriber: llvm-commits.

This is a bugfix in the transformation phase.

If the original outer loop header branches to both the inner loop and the outer loop latch, and if there is an lcssa PHI node outside the loop nest, then after interchange the new outer latch will have an lcssa PHI node inserted which has two predecessors. Currently the transformation assumes it has only one predecessor and crashes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100792

Files:
  llvm/lib/Transforms/Scalar/LoopInterchange.cpp
  llvm/test/Transforms/LoopInterchange/lcssa.ll


Index: llvm/test/Transforms/LoopInterchange/lcssa.ll
===================================================================
--- llvm/test/Transforms/LoopInterchange/lcssa.ll
+++ llvm/test/Transforms/LoopInterchange/lcssa.ll
@@ -298,3 +298,35 @@
 for.end16:                                        ; preds = %for.exit
   ret void
 }
+
+; Should not crash when the outer header branches to
+; both the inner loop and the outer latch, and there
+; is an lcssa phi node outside the loopnest.
+; REMARK: Interchanged
+; REMARK-NEXT: lcssa_08
+define i64 @lcssa_08([100 x [100 x i64]]* %Arr) {
+entry:
+  br label %for1.header
+
+for1.header:                                         ; preds = %for1.inc, %entry
+  %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for1.inc ]
+  br i1 undef, label %for2, label %for1.inc
+
+for2:                                        ; preds = %for2, %for1.header
+  %indvars.iv = phi i64 [ 0, %for1.header ], [ %indvars.iv.next.3, %for2 ]
+  %arrayidx = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* %Arr, i64 0, i64 %indvars.iv, i64 %indvars.iv23
+  %lv = load i64, i64* %arrayidx, align 4
+  %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 1
+  %exit1 = icmp eq i64 %indvars.iv.next.3, 100
+  br i1 %exit1, label %for1.inc, label %for2
+
+for1.inc:                                ; preds = %for2, %for1.header
+  %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
+  %exit2 = icmp eq i64 %indvars.iv.next24, 100
+  br i1 %exit2, label %for1.loopexit, label %for1.header
+
+for1.loopexit:                                 ; preds = %for1.inc
+  %sum.outer.lcssa = phi i64 [ %indvars.iv23, %for1.inc ]
+  ret i64 %sum.outer.lcssa
+}
+
Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -1470,6 +1470,14 @@
       PHINode *NewPhi = dyn_cast<PHINode>(P.clone());
       NewPhi->setIncomingValue(0, P.getIncomingValue(0));
       NewPhi->setIncomingBlock(0, OuterLatch);
+      // We might have incoming edges from other BBs, i.e., the original outer
+      // header.
+      for (pred_iterator PI = pred_begin(InnerLatch), E = pred_end(InnerLatch);
+           PI != E; ++PI) {
+        if (*PI == OuterLatch)
+          continue;
+        NewPhi->addIncoming(P.getIncomingValue(0), *PI);
+      }
       NewPhi->insertBefore(InnerLatch->getFirstNonPHI());
       P.setIncomingValue(0, NewPhi);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100792.338626.patch
Type: text/x-patch
Size: 2536 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210419/03a913b0/attachment.bin>


More information about the llvm-commits mailing list