[polly] r286769 - [ScopDetect] Evaluate and verify branches at branch condition, not icmp

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 13 11:27:04 PST 2016


Author: grosser
Date: Sun Nov 13 13:27:04 2016
New Revision: 286769

URL: http://llvm.org/viewvc/llvm-project?rev=286769&view=rev
Log:
[ScopDetect] Evaluate and verify branches at branch condition, not icmp

The validity of a branch condition must be verified at the location of the
branch (the branch instruction), not the location of the icmp that is
used in the branch instruction. When verifying at the wrong location, we
may accept an icmp that is defined within a loop which itself dominates, but
does not contain the branch instruction. Such loops cannot be modeled as
we only introduce domain dimensions for surrounding loops. To address this
problem we change the scop detection to evaluate and verify SCEV expressions at
the right location.

This issue has been around since at least r179148 "scop detection: properly
instantiate SCEVs to the place where they are used", where we explicitly
set the scope to the wrong location. Before this commit the scope
was not explicitly set, which probably also resulted in the scope around the
ICmp to be choosen.

This resolves http://llvm.org/PR30989

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

Added:
    polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll
    polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll
    polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll
Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=286769&r1=286768&r2=286769&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Sun Nov 13 13:27:04 2016
@@ -388,7 +388,7 @@ bool ScopDetection::isValidBranch(BasicB
       isa<UndefValue>(ICmp->getOperand(1)))
     return invalid<ReportUndefOperand>(Context, /*Assert=*/true, &BB, ICmp);
 
-  Loop *L = LI->getLoopFor(ICmp->getParent());
+  Loop *L = LI->getLoopFor(&BB);
   const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
   const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
 

Added: polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll?rev=286769&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll (added)
+++ polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll Sun Nov 13 13:27:04 2016
@@ -0,0 +1,47 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | \
+; RUN:     FileCheck %s -check-prefix=DETECT
+
+; RUN: opt %loadPolly -polly-scops -analyze < %s | \
+; RUN:     FileCheck %s -check-prefix=SCOP
+
+; DETECT: Valid Region for Scop: loop => barrier
+; DETECT-NEXT: Valid Region for Scop: branch => end
+
+; SCOP: Statements {
+; SCOP-NEXT: 	Stmt_then
+; SCOP-NEXT:         Domain :=
+; SCOP-NEXT:             [p_0] -> { Stmt_then[] : p_0 <= -2 or p_0 >= 0 };
+; SCOP-NEXT:         Schedule :=
+; SCOP-NEXT:             [p_0] -> { Stmt_then[] -> [] };
+; SCOP-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; SCOP-NEXT:             [p_0] -> { Stmt_then[] -> MemRef_A[0] };
+; SCOP-NEXT: }
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-android"
+
+define void @f(i16 %event, float* %A) {
+entry:
+  br label %loop
+
+loop:
+  %indvar = phi i8 [ 0, %entry ], [ %indvar.next, %loop ]
+  %indvar.next = add i8 %indvar, -1
+  store float 1.0, float* %A
+  %cmp = icmp eq i8 %indvar.next, 0
+  br i1 false, label %barrier, label %loop
+
+barrier:
+  fence seq_cst
+  br label %branch
+
+branch:
+  br i1 %cmp, label %branch, label %then
+
+then:
+  store float 1.0, float* %A
+  br label %end
+
+end:
+  unreachable
+}

Added: polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll?rev=286769&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll (added)
+++ polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll Sun Nov 13 13:27:04 2016
@@ -0,0 +1,83 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | \
+; RUN:     FileCheck %s -check-prefix=NONAFFINE
+; RUN: opt %loadPolly -polly-scops -analyze \
+; RUN:     -polly-allow-nonaffine-branches=false < %s | \
+; RUN:     FileCheck %s -check-prefix=NO-NONEAFFINE
+
+; NONAFFINE:      Statements {
+; NONAFFINE-NEXT: 	Stmt_loop
+; NONAFFINE-NEXT:         Domain :=
+; NONAFFINE-NEXT:             [p] -> { Stmt_loop[0] : p = 100 };
+; NONAFFINE-NEXT:         Schedule :=
+; NONAFFINE-NEXT:             [p] -> { Stmt_loop[i0] -> [0, 0] };
+; NONAFFINE-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; NONAFFINE-NEXT:             [p] -> { Stmt_loop[i0] -> MemRef_A[0] };
+; NONAFFINE-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 1]
+; NONAFFINE-NEXT:             [p] -> { Stmt_loop[i0] -> MemRef_cmp[] };
+; NONAFFINE-NEXT: 	Stmt_branch__TO__end
+; NONAFFINE-NEXT:         Domain :=
+; NONAFFINE-NEXT:             [p] -> { Stmt_branch__TO__end[] : p = 100 };
+; NONAFFINE-NEXT:         Schedule :=
+; NONAFFINE-NEXT:             [p] -> { Stmt_branch__TO__end[] -> [1, 0] };
+; NONAFFINE-NEXT:         ReadAccess :=	[Reduction Type: NONE] [Scalar: 1]
+; NONAFFINE-NEXT:             [p] -> { Stmt_branch__TO__end[] -> MemRef_cmp[] };
+; NONAFFINE-NEXT:         MayWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; NONAFFINE-NEXT:             [p] -> { Stmt_branch__TO__end[] -> MemRef_A[0] };
+; NONAFFINE-NEXT: }
+
+; NO-NONEAFFINE:      Statements {
+; NO-NONEAFFINE-NEXT:    	Stmt_then
+; NO-NONEAFFINE-NEXT:            Domain :=
+; NO-NONEAFFINE-NEXT:                [p_0, p] -> { Stmt_then[] : p >= 2 + p_0 or p <= p_0 };
+; NO-NONEAFFINE-NEXT:            Schedule :=
+; NO-NONEAFFINE-NEXT:                [p_0, p] -> { Stmt_then[] -> [] };
+; NO-NONEAFFINE-NEXT:            MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; NO-NONEAFFINE-NEXT:                [p_0, p] -> { Stmt_then[] -> MemRef_A[0] };
+; NO-NONEAFFINE-NEXT:    }
+
+; NO-NONEAFFINE:      Statements {
+; NO-NONEAFFINE-NEXT: 	Stmt_loop
+; NO-NONEAFFINE-NEXT:         Domain :=
+; NO-NONEAFFINE-NEXT:             [p] -> { Stmt_loop[0] : p = 100 };
+; NO-NONEAFFINE-NEXT:         Schedule :=
+; NO-NONEAFFINE-NEXT:             [p] -> { Stmt_loop[i0] -> [0] };
+; NO-NONEAFFINE-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; NO-NONEAFFINE-NEXT:             [p] -> { Stmt_loop[i0] -> MemRef_A[0] };
+; NO-NONEAFFINE-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 1]
+; NO-NONEAFFINE-NEXT:             [p] -> { Stmt_loop[i0] -> MemRef_cmp[] };
+; NO-NONEAFFINE-NEXT: }
+
+; Verify that this test case does not crash -polly-scops. The problem in
+; this test case is that the branch instruction in %branch references
+; a scalar evolution expression for which no useful value can be computed at the
+; location %branch, as the loop %loop does not terminate. At some point, we
+; did not identify the branch condition as non-affine during scop detection.
+; This test verifies that we either model the branch condition as non-affine
+; region or only detect a smaller region if non-affine conditions are not
+; allowed.
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-android"
+
+define void @f(i16 %event, i8 %p, float* %A) {
+entry:
+  br label %loop
+
+loop:
+  %indvar = phi i8 [ 0, %entry ], [ %indvar.next, %loop ]
+  %indvar.next = add i8 %indvar, 1
+  store float 1.0, float* %A
+  %cmp = icmp eq i8 %indvar.next, %p
+  %possibly_infinite = icmp eq i8 100, %p
+  br i1 %possibly_infinite, label %branch, label %loop
+
+branch:
+  br i1 %cmp, label %end, label %then
+
+then:
+  store float 1.0, float* %A
+  br label %end
+
+end:
+  unreachable
+}

Added: polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll?rev=286769&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll (added)
+++ polly/trunk/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll Sun Nov 13 13:27:04 2016
@@ -0,0 +1,57 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | \
+; RUN:     FileCheck %s -check-prefix=NONAFFINE
+; RUN: opt %loadPolly -polly-scops -analyze \
+; RUN:     -polly-allow-nonaffine-branches=false < %s | \
+; RUN:     FileCheck %s -check-prefix=NO-NONEAFFINE
+
+; NONAFFINE:      Printing analysis 'Polly - Create polyhedral description of Scops' for region: 'branch => end' in function 'f':
+; NONAFFINE-NEXT: Invalid Scop!
+; NONAFFINE-NEXT: Printing analysis 'Polly - Create polyhedral description of Scops' for region: 'loop => branch' in function 'f':
+; NONAFFINE-NEXT: Invalid Scop!
+; NONAFFINE-NEXT: Printing analysis 'Polly - Create polyhedral description of Scops' for region: 'loop => end' in function 'f':
+; NONAFFINE-NEXT: Invalid Scop!
+; NONAFFINE-NEXT: Printing analysis 'Polly - Create polyhedral description of Scops' for region: 'entry => <Function Return>' in function 'f':
+; NONAFFINE-NEXT: Invalid Scop!
+
+; NO-NONEAFFINE: Statements {
+; NO-NONEAFFINE-NEXT: 	Stmt_then
+; NO-NONEAFFINE-NEXT:         Domain :=
+; NO-NONEAFFINE-NEXT:             [p_0] -> { Stmt_then[] : p_0 <= -2 or p_0 >= 0 };
+; NO-NONEAFFINE-NEXT:         Schedule :=
+; NO-NONEAFFINE-NEXT:             [p_0] -> { Stmt_then[] -> [] };
+; NO-NONEAFFINE-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; NO-NONEAFFINE-NEXT:             [p_0] -> { Stmt_then[] -> MemRef_A[0] };
+; NO-NONEAFFINE-NEXT: }
+
+; Verify that this test case does not crash -polly-scops. The problem in
+; this test case is that the branch instruction in %branch references
+; a scalar evolution expression for which no useful value can be computed at the
+; location %branch, as the loop %loop does not terminate. At some point, we
+; did not identify the branch condition as non-affine during scop detection.
+; This test verifies that we either model the branch condition as non-affine
+; region (and return an empty scop) or only detect a smaller region if
+; non-affine conditions are not allowed.
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-android"
+
+define void @f(i16 %event, float* %A) {
+entry:
+  br label %loop
+
+loop:
+  %indvar = phi i8 [ 0, %entry ], [ %indvar.next, %loop ]
+  %indvar.next = add i8 %indvar, 1
+  %cmp = icmp eq i8 %indvar.next, 0
+  br i1 false, label %branch, label %loop
+
+branch:
+  br i1 %cmp, label %end, label %then
+
+then:
+  store float 1.0, float* %A
+  br label %end
+
+end:
+  unreachable
+}




More information about the llvm-commits mailing list