[llvm-branch-commits] [llvm] 40cd262 - Loop peeling: check that latch is conditional branch

Joseph Tremoulet via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 20 08:06:49 PST 2021


Author: Joseph Tremoulet
Date: 2021-01-20T11:01:16-05:00
New Revision: 40cd262c4339c8cbd67bf5c96c4a052ae02a8660

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

LOG: Loop peeling: check that latch is conditional branch

Loop peeling assumes that the loop's latch is a conditional branch.  Add
a check to canPeel that explicitly checks for this, and testcases that
otherwise fail an assertion when trying to peel a loop whose back-edge
is a switch case or the non-unwind edge of an invoke.

Reviewed By: skatkov, fhahn

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/LoopPeel.cpp
    llvm/test/Transforms/LoopUnroll/peel-loop-conditions.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp
index 27a61a207868..cb5fee7d28e6 100644
--- a/llvm/lib/Transforms/Utils/LoopPeel.cpp
+++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp
@@ -115,7 +115,12 @@ bool llvm::canPeel(Loop *L) {
   // This can be an indication of two 
diff erent things:
   // 1) The loop is not rotated.
   // 2) The loop contains irreducible control flow that involves the latch.
-  if (L->getLoopLatch() != L->getExitingBlock())
+  const BasicBlock *Latch = L->getLoopLatch();
+  if (Latch != L->getExitingBlock())
+    return false;
+
+  // Peeling is only supported if the latch is a branch.
+  if (!isa<BranchInst>(Latch->getTerminator()))
     return false;
 
   return true;

diff  --git a/llvm/test/Transforms/LoopUnroll/peel-loop-conditions.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-conditions.ll
index f0fbf3d6d49b..fa7e13397e25 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-conditions.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-conditions.ll
@@ -1140,5 +1140,69 @@ for.end:
   ret void
 }
 
+; Invoke is not a conditional branch that we can optimize,
+; so this shouldn't be peeled at all.  This is a reproducer
+; for a bug where evaluating the loop would fail an assertion.
+define void @test17() personality i8* undef{
+; CHECK-LABEL: @test17(
+; CHECK-NEXT:  body:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[CONST:%.*]] = phi i64 [ -33, [[LOOP]] ], [ -20, [[BODY:%.*]] ]
+; CHECK-NEXT:    invoke void @f1()
+; CHECK-NEXT:    to label [[LOOP]] unwind label [[EH_UNW_LOOPEXIT:%.*]]
+; CHECK:       eh.Unw.loopexit:
+; CHECK-NEXT:    [[LPAD_LOOPEXIT:%.*]] = landingpad { i8*, i32 }
+; CHECK-NEXT:    catch i8* null
+; CHECK-NEXT:    ret void
+;
+body:
+  br label %loop
+
+loop:
+  %const = phi i64 [ -33, %loop ], [ -20, %body ]
+  invoke void @f1()
+  to label %loop unwind label %eh.Unw.loopexit
+
+eh.Unw.loopexit:
+  %lpad.loopexit = landingpad { i8*, i32 }
+  catch i8* null
+  ret void
+}
+
+; Testcase reduced from PR48812.  We expect no peeling
+; because the latch terminator is a switch.
+define void @test18(i32* %p) {
+; CHECK-LABEL: @test18(
+; CHECK-NEXT:  init:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[CONST:%.*]] = phi i32 [ 40, [[INIT:%.*]] ], [ 0, [[LATCH:%.*]] ]
+; CHECK-NEXT:    br label [[LATCH]]
+; CHECK:       latch:
+; CHECK-NEXT:    [[CONTROL:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
+; CHECK-NEXT:    switch i32 [[CONTROL]], label [[EXIT:%.*]] [
+; CHECK-NEXT:    i32 2, label [[LOOP]]
+; CHECK-NEXT:    ]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+init:
+  br label %loop
+
+loop:
+  %const = phi i32 [ 40, %init ], [ 0, %latch ]
+  br label %latch
+
+latch:
+  %control = load volatile i32, i32* %p
+  switch i32 %control, label %exit [
+  i32 2, label %loop
+  ]
+
+exit:
+  ret void
+}
+
 declare void @init()
 declare void @sink()


        


More information about the llvm-branch-commits mailing list