[polly] r286426 - Do not allow switch statements in loop latches

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 9 21:20:29 PST 2016


Author: grosser
Date: Wed Nov  9 23:20:29 2016
New Revision: 286426

URL: http://llvm.org/viewvc/llvm-project?rev=286426&view=rev
Log:
Do not allow switch statements in loop latches

In r248701 "Allow switch instructions in SCoPs" support for switch statements
has been introduced, but support for switch statements in loop latches was
incomplete. This change completely disables switch statements in loop latches.

The original commit changed addLoopBoundsToHeaderDomain to support non-branch
terminator instructions, but this change was incorrect: it added a check for
BI != null to the if-branch of a condition, but BI was used in the else branch
es well. As a result, when a non-branch terminator instruction is encounted a
nullptr dereference is triggered. Due to missing test coverage, this bug was
overlooked.

r249273 "[FIX] Approximate non-affine loops correctly" added code to disallow
switch statements for non-affine loops, if they appear in either a loop latch
or a loop exit. We adapt this code to now prohibit switch statements in
loop latches even if the control condition is affine.

We could possibly add support for switch statements in loop latches, but such
support should be evaluated and tested separately.

This fixes llvm.org/PR30952

Reported-by: Eli Friedman <efriedma at codeaurora.org>

Added:
    polly/trunk/test/ScopDetect/switch-in-loop-patch.ll
Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Analysis/ScopInfo.cpp

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=286426&r1=286425&r2=286426&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Wed Nov  9 23:20:29 2016
@@ -341,16 +341,16 @@ bool ScopDetection::isValidSwitch(BasicB
   Loop *L = LI->getLoopFor(&BB);
   const SCEV *ConditionSCEV = SE->getSCEVAtScope(Condition, L);
 
+  if (IsLoopBranch && L->isLoopLatch(&BB))
+    return false;
+
   if (isAffine(ConditionSCEV, L, Context))
     return true;
 
-  if (!IsLoopBranch && AllowNonAffineSubRegions &&
+  if (AllowNonAffineSubRegions &&
       addOverApproximatedRegion(RI->getRegionFor(&BB), Context))
     return true;
 
-  if (IsLoopBranch)
-    return false;
-
   return invalid<ReportNonAffBranch>(Context, /*Assert=*/true, &BB,
                                      ConditionSCEV, ConditionSCEV, SI);
 }
@@ -359,6 +359,10 @@ bool ScopDetection::isValidBranch(BasicB
                                   Value *Condition, bool IsLoopBranch,
                                   DetectionContext &Context) const {
 
+  // Constant integer conditions are always affine.
+  if (isa<ConstantInt>(Condition))
+    return true;
+
   if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Condition)) {
     auto Opcode = BinOp->getOpcode();
     if (Opcode == Instruction::And || Opcode == Instruction::Or) {
@@ -425,10 +429,6 @@ bool ScopDetection::isValidCFG(BasicBloc
   if (isa<UndefValue>(Condition))
     return invalid<ReportUndefCond>(Context, /*Assert=*/true, TI, &BB);
 
-  // Constant integer conditions are always affine.
-  if (isa<ConstantInt>(Condition))
-    return true;
-
   if (BranchInst *BI = dyn_cast<BranchInst>(TI))
     return isValidBranch(BB, BI, Condition, IsLoopBranch, Context);
 

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=286426&r1=286425&r2=286426&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Wed Nov  9 23:20:29 2016
@@ -2792,7 +2792,9 @@ bool Scop::addLoopBoundsToHeaderDomain(L
 
     TerminatorInst *TI = LatchBB->getTerminator();
     BranchInst *BI = dyn_cast<BranchInst>(TI);
-    if (BI && BI->isUnconditional())
+    assert(BI && "Only branch instructions allowed in loop latches");
+
+    if (BI->isUnconditional())
       BackedgeCondition = isl_set_copy(LatchBBDom);
     else {
       SmallVector<isl_set *, 8> ConditionSets;

Added: polly/trunk/test/ScopDetect/switch-in-loop-patch.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/switch-in-loop-patch.ll?rev=286426&view=auto
==============================================================================
--- polly/trunk/test/ScopDetect/switch-in-loop-patch.ll (added)
+++ polly/trunk/test/ScopDetect/switch-in-loop-patch.ll Wed Nov  9 23:20:29 2016
@@ -0,0 +1,21 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+
+; CHECK-NOT: Valid
+
+; Verify that we do not detect loops where the loop latch is a switch statement.
+; Such loops are not yet supported by Polly.
+
+define void @f() {
+b:
+  br label %d
+
+d:
+  switch i8 0, label %e [
+    i8 71, label %d
+    i8 56, label %d
+  ]
+
+e:
+ ret void
+}
+




More information about the llvm-commits mailing list