[PATCH] D104238: [LoopDeletion] Check for irreducible cycles when deleting loops.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 15 04:56:45 PDT 2021


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf7fc8927c088: [LoopDeletion] Check for irreducible cycles when deleting loops. (authored by fhahn).

Changed prior to commit:
  https://reviews.llvm.org/D104238?vs=351901&id=352096#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D104238/new/

https://reviews.llvm.org/D104238

Files:
  llvm/lib/Transforms/Scalar/LoopDeletion.cpp
  llvm/test/Transforms/LoopDeletion/loops-with-irreducible-subloops.ll


Index: llvm/test/Transforms/LoopDeletion/loops-with-irreducible-subloops.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/loops-with-irreducible-subloops.ll
+++ llvm/test/Transforms/LoopDeletion/loops-with-irreducible-subloops.ll
@@ -3,12 +3,28 @@
 
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
 
+; loop1 contains an irreducible cycle, which may loop infinitely. Do not remove
+; the loop.
 define void @irreducible_subloop_no_mustprogress(i1 %c1, i1 %c2, i1 %c3) {
 ; CHECK-LABEL: @irreducible_subloop_no_mustprogress(
-; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP1:%.*]]
+; CHECK:       loop1:
+; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOOP1_BB1:%.*]], label [[IRR_BB1:%.*]]
+; CHECK:       loop1.bb1:
+; CHECK-NEXT:    br label [[IRR_BB2:%.*]]
+; CHECK:       irr.bb1:
+; CHECK-NEXT:    br i1 [[C2:%.*]], label [[LOOP1_LATCH:%.*]], label [[IRR_BB2]]
+; CHECK:       irr.bb2:
+; CHECK-NEXT:    br i1 [[C3:%.*]], label [[LOOP1_LATCH]], label [[IRR_BB1]]
+; CHECK:       loop1.latch:
+; CHECK-NEXT:    br i1 false, label [[LOOP1_LATCH_LOOP1_CRIT_EDGE:%.*]], label [[EXIT:%.*]]
+; CHECK:       loop1.latch.loop1_crit_edge:
+; CHECK-NEXT:    unreachable
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ;
+entry:
   br label %loop1
 
 loop1:
Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -16,11 +16,14 @@
 #include "llvm/Transforms/Scalar/LoopDeletion.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/CFG.h"
 #include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/LoopIterator.h"
 #include "llvm/Analysis/LoopPass.h"
 #include "llvm/Analysis/MemorySSA.h"
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/IR/Dominators.h"
+
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Transforms/Scalar.h"
@@ -54,7 +57,7 @@
 static bool isLoopDead(Loop *L, ScalarEvolution &SE,
                        SmallVectorImpl<BasicBlock *> &ExitingBlocks,
                        BasicBlock *ExitBlock, bool &Changed,
-                       BasicBlock *Preheader) {
+                       BasicBlock *Preheader, LoopInfo &LI) {
   // Make sure that all PHI entries coming from the loop are loop invariant.
   // Because the code is in LCSSA form, any values used outside of the loop
   // must pass through a PHI in the exit block, meaning that this check is
@@ -108,6 +111,12 @@
   if (L->getHeader()->getParent()->mustProgress())
     return true;
 
+  LoopBlocksRPO RPOT(L);
+  RPOT.perform(&LI);
+  // If the loop contains an irreducible cycle, it may loop infinitely.
+  if (containsIrreducibleCFG<const BasicBlock *>(RPOT, LI))
+    return false;
+
   SmallVector<Loop *, 8> WorkList;
   WorkList.push_back(L);
   while (!WorkList.empty()) {
@@ -248,7 +257,7 @@
   }
   // Finally, we have to check that the loop really is dead.
   bool Changed = false;
-  if (!isLoopDead(L, SE, ExitingBlocks, ExitBlock, Changed, Preheader)) {
+  if (!isLoopDead(L, SE, ExitingBlocks, ExitBlock, Changed, Preheader, LI)) {
     LLVM_DEBUG(dbgs() << "Loop is not invariant, cannot delete.\n");
     return Changed ? LoopDeletionResult::Modified
                    : LoopDeletionResult::Unmodified;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104238.352096.patch
Type: text/x-patch
Size: 3558 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210615/a3d0a4af/attachment.bin>


More information about the llvm-commits mailing list