diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 8700ae2745a4..a34c4edcae27 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -388,7 +388,7 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI, isa(ICmp->getOperand(1))) return invalid(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); diff --git a/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll b/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll new file mode 100644 index 000000000000..dc2139fd7b0f --- /dev/null +++ b/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-2.ll @@ -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 +} diff --git a/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll b/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll new file mode 100644 index 000000000000..ab4e12bf29b7 --- /dev/null +++ b/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations-3.ll @@ -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 +} diff --git a/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll b/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll new file mode 100644 index 000000000000..21ceca462bd0 --- /dev/null +++ b/polly/test/ScopInfo/branch-references-loop-scev-with-unknown-iterations.ll @@ -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 => ' 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 +}