Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,42 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
;
; void foo(float *A) {
; for (long i = 1;; i++) {
; A[i] += 1;
; if (i / 7 == 4)
; break;
; }
; }
;
; CHECK: Domain :=
; CHECK: { Stmt_for_body[i0] : 0 <= i0 <= 27 };
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @foo(float* %A) {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i64 [ 1, %entry ], [ %inc, %for.inc ]
br label %for.body
for.body: ; preds = %for.cond
%arrayidx0 = getelementptr inbounds float, float* %A, i64 %i.0
%tmp0 = load float, float* %arrayidx0, align 4
%add0 = fadd float %tmp0, 2.000000e+00
store float %add0, float* %arrayidx0, align 4
%rem1 = sdiv i64 %i.0, 7
%tobool = icmp eq i64 %rem1, 4
br i1 %tobool, label %for.end, label %if.end
if.end: ; preds = %for.body, %if.then
br label %for.inc
for.inc: ; preds = %if.end
%inc = add nuw nsw i64 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@@ -0,0 +1,68 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
;
; void foo(float *A) {
; for (long i = 0; i < 16; i++) {
; A[i] += 1;
; if (i / 2 == 3)
; A[i] += 2;
; }
; }
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_for_body
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_for_body[i0] : 0 <= i0 <= 15 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_for_body[i0] -> [i0, 0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Stmt_if_then
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_if_then[i0] : 6 <= i0 <= 7 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_if_then[i0] -> [i0, 1] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_if_then[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_if_then[i0] -> MemRef_A[i0] };
; CHECK-NEXT: }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @foo(float* %A) {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
%exitcond = icmp ne i64 %i.0, 16
br i1 %exitcond, label %for.body, label %for.end
for.body: ; preds = %for.cond
%arrayidx0 = getelementptr inbounds float, float* %A, i64 %i.0
%tmp0 = load float, float* %arrayidx0, align 4
%add0 = fadd float %tmp0, 2.000000e+00
store float %add0, float* %arrayidx0, align 4
%rem1 = sdiv i64 %i.0, 2
%tobool = icmp ne i64 %rem1, 3
br i1 %tobool, label %if.end, label %if.then
if.then: ; preds = %for.body
%arrayidx = getelementptr inbounds float, float* %A, i64 %i.0
%tmp = load float, float* %arrayidx, align 4
%add = fadd float %tmp, 2.000000e+00
store float %add, float* %arrayidx, align 4
br label %if.end
if.end: ; preds = %for.body, %if.then
br label %for.inc
for.inc: ; preds = %if.end
%inc = add nuw nsw i64 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@@ -0,0 +1,58 @@
; RUN: opt %loadPolly -polly-scops -analyze \
; RUN: -polly-invariant-load-hoisting=true < %s | FileCheck %s
;
; void f(int *A, int *B, int *C) {
; for (int i = 0; i < 1000; i++)
; if (A[i] == *B)
; A[i] = *C;
; }
;
; Check that only the access to *B is hoisted but not the one to *C.
;
; CHECK: Invariant Accesses: {
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: { Stmt_for_body__TO__if_end[i0] -> MemRef_B[0] };
; CHECK: Execution Context: { : }
; CHECK: }
;
; CHECK: Statements {
; CHECK: Stmt_for_body__TO__if_end
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: { Stmt_for_body__TO__if_end[i0] -> MemRef_C[0] };
; CHECK: }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A, i32* %B, i32* %C) {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
%exitcond = icmp ne i64 %indvars.iv, 1000
br i1 %exitcond, label %for.body, label %for.end
for.body: ; preds = %for.cond
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp = load i32, i32* %arrayidx, align 4
%tmp1 = load i32, i32* %B, align 4
%cmp1 = icmp eq i32 %tmp, %tmp1
br i1 %cmp1, label %if.then, label %if.end
if.then: ; preds = %for.body
%tmp2 = load i32, i32* %C, align 4
%arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
store i32 %tmp2, i32* %arrayidx3, align 4
br label %if.end
if.end: ; preds = %if.then, %for.body
br label %for.inc
for.inc: ; preds = %if.end
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@@ -0,0 +1,42 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
;
; CHECK: Domain :=
; CHECK: { Stmt_for_body[i0] : 0 <= i0 <= 6 };
;
; void foo(float *A) {
; for (long i = 1;; i++) {
; A[i] += 1;
; if (i % 7 == 0)
; break;
; }
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @foo(float* %A) {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i64 [ 1, %entry ], [ %inc, %for.inc ]
br label %for.body
for.body: ; preds = %for.cond
%arrayidx0 = getelementptr inbounds float, float* %A, i64 %i.0
%tmp0 = load float, float* %arrayidx0, align 4
%add0 = fadd float %tmp0, 2.000000e+00
store float %add0, float* %arrayidx0, align 4
%rem1 = srem i64 %i.0, 7
%tobool = icmp eq i64 %rem1, 0
br i1 %tobool, label %for.end, label %if.end
if.end: ; preds = %for.body, %if.then
br label %for.inc
for.inc: ; preds = %if.end
%inc = add nuw nsw i64 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@@ -0,0 +1,55 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
;
; TODO: The new domain generation cannot handle modulo domain constraints,
; hence modulo handling has been disabled completely. Once this is
; resolved this test should work again. Until then we approximate the
; whole loop body.
;
; CHECK: Domain :=
; CHECK: { Stmt_for_body[i0] : 0 <= i0 <= 15 };
;
; void foo(float *A) {
; for (long i = 0; i < 16; i++) {
; A[i] += 1;
; if (i % 2)
; A[i] += 2;
; }
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @foo(float* %A) {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
%exitcond = icmp ne i64 %i.0, 16
br i1 %exitcond, label %for.body, label %for.end
for.body: ; preds = %for.cond
%arrayidx0 = getelementptr inbounds float, float* %A, i64 %i.0
%tmp0 = load float, float* %arrayidx0, align 4
%add0 = fadd float %tmp0, 2.000000e+00
store float %add0, float* %arrayidx0, align 4
%rem1 = srem i64 %i.0, 2
%tobool = icmp eq i64 %rem1, 0
br i1 %tobool, label %if.end, label %if.then
if.then: ; preds = %for.body
%arrayidx = getelementptr inbounds float, float* %A, i64 %i.0
%tmp = load float, float* %arrayidx, align 4
%add = fadd float %tmp, 2.000000e+00
store float %add, float* %arrayidx, align 4
br label %if.end
if.end: ; preds = %for.body, %if.then
br label %for.inc
for.inc: ; preds = %if.end
%inc = add nuw nsw i64 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@@ -0,0 +1,94 @@
; RUN: opt %loadPolly -basicaa -polly-scops \
; RUN: -polly-allow-nonaffine -polly-allow-nonaffine-branches \
; RUN: -polly-allow-nonaffine-loops=true -analyze < %s | FileCheck %s \
; RUN: -check-prefix=SCALAR
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine \
; RUN: -polly-process-unprofitable=false \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s -check-prefix=PROFIT
;
; SCALAR: Function: f
; SCALAR-NEXT: Region: %bb1---%bb13
; SCALAR-NEXT: Max Loop Depth: 1
; SCALAR-NEXT: Invariant Accesses: {
; SCALAR-NEXT: }
; SCALAR-NEXT: Context:
; SCALAR-NEXT: { : }
; SCALAR-NEXT: Assumed Context:
; SCALAR-NEXT: { : }
; SCALAR-NEXT: Invalid Context:
; SCALAR-NEXT: { : 1 = 0 }
; SCALAR-NEXT: Arrays {
; SCALAR-NEXT: i32 MemRef_C[*]; // Element size 4
; SCALAR-NEXT: i32 MemRef_A[*]; // Element size 4
; SCALAR-NEXT: }
; SCALAR-NEXT: Arrays (Bounds as pw_affs) {
; SCALAR-NEXT: i32 MemRef_C[*]; // Element size 4
; SCALAR-NEXT: i32 MemRef_A[*]; // Element size 4
; SCALAR-NEXT: }
; SCALAR-NEXT: Alias Groups (0):
; SCALAR-NEXT: n/a
; SCALAR-NEXT: Statements {
; SCALAR-NEXT: Stmt_bb3__TO__bb11
; SCALAR-NEXT: Domain :=
; SCALAR-NEXT: { Stmt_bb3__TO__bb11[i0] : 0 <= i0 <= 1023 };
; SCALAR-NEXT: Schedule :=
; SCALAR-NEXT: { Stmt_bb3__TO__bb11[i0] -> [i0] };
; SCALAR-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; SCALAR-NEXT: { Stmt_bb3__TO__bb11[i0] -> MemRef_C[i0] };
; SCALAR-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; SCALAR-NEXT: { Stmt_bb3__TO__bb11[i0] -> MemRef_A[o0] };
; SCALAR-NEXT: MayWriteAccess := [Reduction Type: +] [Scalar: 0]
; SCALAR-NEXT: { Stmt_bb3__TO__bb11[i0] -> MemRef_A[o0] };
; SCALAR-NEXT: }
; PROFIT-NOT: Statements
;
; void f(int * restrict A, int * restrict C) {
; int j;
; for (int i = 0; i < 1024; i++) {
; while ((j = C[i++])) {
; A[j]++;
; if (true) break;
; }
; }
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* noalias %A, i32* noalias %C) {
bb:
br label %bb1
bb1: ; preds = %bb12, %bb
%indvars.iv = phi i64 [ %indvars.iv.next, %bb12 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %bb2, label %bb13
bb2: ; preds = %bb1
br label %bb3
bb3: ; preds = %bb6, %bb2
%tmp = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
%tmp4 = load i32, i32* %tmp, align 4
%tmp5 = icmp eq i32 %tmp4, 0
br i1 %tmp5, label %bb11, label %bb6
bb6: ; preds = %bb3
%tmp7 = sext i32 %tmp4 to i64
%tmp8 = getelementptr inbounds i32, i32* %A, i64 %tmp7
%tmp9 = load i32, i32* %tmp8, align 4
%tmp10 = add nsw i32 %tmp9, 1
store i32 %tmp10, i32* %tmp8, align 4
br i1 true, label %bb11, label %bb3
bb11: ; preds = %bb3
br label %bb12
bb12: ; preds = %bb11
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb1
bb13: ; preds = %bb1
ret void
}

View File

@@ -0,0 +1,174 @@
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-allow-nonaffine-loops=false \
; RUN: -analyze < %s | FileCheck %s --check-prefix=INNERMOST
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=INNERMOST
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s \
; RUN: --check-prefix=ALL
;
; Here we have a non-affine loop (in the context of the loop nest)
; and also a non-affine access (A[k]). While we can always model the
; innermost loop as a SCoP of depth 1, we can overapproximate the
; innermost loop in the whole loop nest and model A[k] as a non-affine
; access.
;
; INNERMOST: Function: f
; INNERMOST-NEXT: Region: %bb15---%bb13
; INNERMOST-NEXT: Max Loop Depth: 1
; INNERMOST-NEXT: Invariant Accesses: {
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Context:
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { : 0 <= p_0 <= 1048576 and 0 <= p_1 <= 1024 and 0 <= p_2 <= 1024 }
; INNERMOST-NEXT: Assumed Context:
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { : }
; INNERMOST-NEXT: Invalid Context:
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { : 1 = 0 }
; INNERMOST-NEXT: p0: {0,+,{0,+,1}<nuw><nsw><%bb11>}<nuw><nsw><%bb13>
; INNERMOST-NEXT: p1: {0,+,1}<nuw><nsw><%bb11>
; INNERMOST-NEXT: p2: {0,+,1}<nuw><nsw><%bb13>
; INNERMOST-NEXT: Arrays {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next6; // Element size 8
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next4; // Element size 8
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Arrays (Bounds as pw_affs) {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next6; // Element size 8
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next4; // Element size 8
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Alias Groups (0):
; INNERMOST-NEXT: n/a
; INNERMOST-NEXT: Statements {
; INNERMOST-NEXT: Stmt_bb16
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] : 0 <= i0 <= 1023 - p_0 };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> [0, i0] };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[p_1] };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[p_2] };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[p_0 + i0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[p_0 + i0] };
; INNERMOST-NEXT: Stmt_bb26
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] : p_0 <= 1024 };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] -> [1, 0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] -> MemRef_indvars_iv_next6[] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] -> MemRef_indvars_iv_next4[] };
; INNERMOST-NEXT: }
; ALL: Function: f
; ALL-NEXT: Region: %bb11---%bb29
; ALL-NEXT: Max Loop Depth: 2
; ALL-NEXT: Invariant Accesses: {
; ALL-NEXT: }
; ALL-NEXT: Context:
; ALL-NEXT: { : }
; ALL-NEXT: Assumed Context:
; ALL-NEXT: { : }
; ALL-NEXT: Invalid Context:
; ALL-NEXT: { : 1 = 0 }
; ALL-NEXT: Arrays {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Arrays (Bounds as pw_affs) {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Alias Groups (0):
; ALL-NEXT: n/a
; ALL-NEXT: Statements {
; ALL-NEXT: Stmt_bb15__TO__bb25
; ALL-NEXT: Domain :=
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023 };
; ALL-NEXT: Schedule :=
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> [i0, i1] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[i0] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[i1] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2305843009213693951 };
; ALL-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2305843009213693951 };
; ALL-NEXT: }
;
; void f(int *A) {
; for (int i = 0; i < 1024; i++)
; for (int j = 0; j < 1024; j++)
; for (int k = i *j; k < 1024; k++)
; A[k] += A[i] + A[j];
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A) {
bb:
br label %bb11
bb11: ; preds = %bb28, %bb
%indvars.iv8 = phi i64 [ %indvars.iv.next9, %bb28 ], [ 0, %bb ]
%indvars.iv1 = phi i64 [ %indvars.iv.next2, %bb28 ], [ 0, %bb ]
%exitcond10 = icmp ne i64 %indvars.iv8, 1024
br i1 %exitcond10, label %bb12, label %bb29
bb12: ; preds = %bb11
br label %bb13
bb13: ; preds = %bb26, %bb12
%indvars.iv5 = phi i64 [ %indvars.iv.next6, %bb26 ], [ 0, %bb12 ]
%indvars.iv3 = phi i64 [ %indvars.iv.next4, %bb26 ], [ 0, %bb12 ]
%exitcond7 = icmp ne i64 %indvars.iv5, 1024
br i1 %exitcond7, label %bb14, label %bb27
bb14: ; preds = %bb13
br label %bb15
bb15: ; preds = %bb24, %bb14
%indvars.iv = phi i64 [ %indvars.iv.next, %bb24 ], [ %indvars.iv3, %bb14 ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %bb16, label %bb25
bb16: ; preds = %bb15
%tmp = getelementptr inbounds i32, i32* %A, i64 %indvars.iv8
%tmp17 = load i32, i32* %tmp, align 4
%tmp18 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv5
%tmp19 = load i32, i32* %tmp18, align 4
%tmp20 = add nsw i32 %tmp17, %tmp19
%tmp21 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp22 = load i32, i32* %tmp21, align 4
%tmp23 = add nsw i32 %tmp22, %tmp20
store i32 %tmp23, i32* %tmp21, align 4
br label %bb24
bb24: ; preds = %bb16
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb15
bb25: ; preds = %bb15
br label %bb26
bb26: ; preds = %bb25
%indvars.iv.next6 = add nuw nsw i64 %indvars.iv5, 1
%indvars.iv.next4 = add nuw nsw i64 %indvars.iv3, %indvars.iv1
br label %bb13
bb27: ; preds = %bb13
br label %bb28
bb28: ; preds = %bb27
%indvars.iv.next9 = add nuw nsw i64 %indvars.iv8, 1
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
br label %bb11
bb29: ; preds = %bb11
ret void
}

View File

@@ -0,0 +1,174 @@
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-allow-nonaffine-loops=false \
; RUN: -analyze < %s | FileCheck %s --check-prefix=INNERMOST
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=INNERMOST
; RUN: opt %loadPolly -basicaa -polly-scops -polly-allow-nonaffine \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=ALL
;
; Here we have a non-affine loop (in the context of the loop nest)
; and also a non-affine access (A[k]). While we can always model the
; innermost loop as a SCoP of depth 1, we can overapproximate the
; innermost loop in the whole loop nest and model A[k] as a non-affine
; access.
;
; INNERMOST: Function: f
; INNERMOST-NEXT: Region: %bb15---%bb13
; INNERMOST-NEXT: Max Loop Depth: 1
; INNERMOST-NEXT: Invariant Accesses: {
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Context:
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { : 0 <= p_0 <= 2147483647 and 0 <= p_1 <= 1024 and 0 <= p_2 <= 1024 }
; INNERMOST-NEXT: Assumed Context:
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { : }
; INNERMOST-NEXT: Invalid Context:
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { : 1 = 0 }
; INNERMOST-NEXT: p0: {0,+,{0,+,1}<nuw><nsw><%bb11>}<nuw><nsw><%bb13>
; INNERMOST-NEXT: p1: {0,+,1}<nuw><nsw><%bb11>
; INNERMOST-NEXT: p2: {0,+,1}<nuw><nsw><%bb13>
; INNERMOST-NEXT: Arrays {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next6; // Element size 8
; INNERMOST-NEXT: i32 MemRef_indvars_iv_next4; // Element size 4
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Arrays (Bounds as pw_affs) {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next6; // Element size 8
; INNERMOST-NEXT: i32 MemRef_indvars_iv_next4; // Element size 4
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Alias Groups (0):
; INNERMOST-NEXT: n/a
; INNERMOST-NEXT: Statements {
; INNERMOST-NEXT: Stmt_bb16
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] : 0 <= i0 < p_0 };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> [0, i0] };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[p_1] };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[p_2] };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[i0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb16[i0] -> MemRef_A[i0] };
; INNERMOST-NEXT: Stmt_bb26
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] -> [1, 0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] -> MemRef_indvars_iv_next6[] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; INNERMOST-NEXT: [p_0, p_1, p_2] -> { Stmt_bb26[] -> MemRef_indvars_iv_next4[] };
; INNERMOST-NEXT: }
; ALL: Function: f
; ALL-NEXT: Region: %bb11---%bb29
; ALL-NEXT: Max Loop Depth: 2
; ALL-NEXT: Invariant Accesses: {
; ALL-NEXT: }
; ALL-NEXT: Context:
; ALL-NEXT: { : }
; ALL-NEXT: Assumed Context:
; ALL-NEXT: { : }
; ALL-NEXT: Invalid Context:
; ALL-NEXT: { : 1 = 0 }
; ALL-NEXT: Arrays {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Arrays (Bounds as pw_affs) {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Alias Groups (0):
; ALL-NEXT: n/a
; ALL-NEXT: Statements {
; ALL-NEXT: Stmt_bb15__TO__bb25
; ALL-NEXT: Domain :=
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 1023 };
; ALL-NEXT: Schedule :=
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> [i0, i1] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[i0] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[i1] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2147483647 };
; ALL-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb15__TO__bb25[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2147483647 };
; ALL-NEXT: }
;
; void f(int *A) {
; for (int i = 0; i < 1024; i++)
; for (int j = 0; j < 1024; j++)
; for (int k = 0; k < i * j; k++)
; A[k] += A[i] + A[j];
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A) {
bb:
br label %bb11
bb11: ; preds = %bb28, %bb
%indvars.iv8 = phi i64 [ %indvars.iv.next9, %bb28 ], [ 0, %bb ]
%indvars.iv1 = phi i32 [ %indvars.iv.next2, %bb28 ], [ 0, %bb ]
%exitcond10 = icmp ne i64 %indvars.iv8, 1024
br i1 %exitcond10, label %bb12, label %bb29
bb12: ; preds = %bb11
br label %bb13
bb13: ; preds = %bb26, %bb12
%indvars.iv5 = phi i64 [ %indvars.iv.next6, %bb26 ], [ 0, %bb12 ]
%indvars.iv3 = phi i32 [ %indvars.iv.next4, %bb26 ], [ 0, %bb12 ]
%exitcond7 = icmp ne i64 %indvars.iv5, 1024
br i1 %exitcond7, label %bb14, label %bb27
bb14: ; preds = %bb13
br label %bb15
bb15: ; preds = %bb24, %bb14
%indvars.iv = phi i64 [ %indvars.iv.next, %bb24 ], [ 0, %bb14 ]
%lftr.wideiv = trunc i64 %indvars.iv to i32
%exitcond = icmp ne i32 %lftr.wideiv, %indvars.iv3
br i1 %exitcond, label %bb16, label %bb25
bb16: ; preds = %bb15
%tmp = getelementptr inbounds i32, i32* %A, i64 %indvars.iv8
%tmp17 = load i32, i32* %tmp, align 4
%tmp18 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv5
%tmp19 = load i32, i32* %tmp18, align 4
%tmp20 = add nsw i32 %tmp17, %tmp19
%tmp21 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp22 = load i32, i32* %tmp21, align 4
%tmp23 = add nsw i32 %tmp22, %tmp20
store i32 %tmp23, i32* %tmp21, align 4
br label %bb24
bb24: ; preds = %bb16
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb15
bb25: ; preds = %bb15
br label %bb26
bb26: ; preds = %bb25
%indvars.iv.next6 = add nuw nsw i64 %indvars.iv5, 1
%indvars.iv.next4 = add nuw nsw i32 %indvars.iv3, %indvars.iv1
br label %bb13
bb27: ; preds = %bb13
br label %bb28
bb28: ; preds = %bb27
%indvars.iv.next9 = add nuw nsw i64 %indvars.iv8, 1
%indvars.iv.next2 = add nuw nsw i32 %indvars.iv1, 1
br label %bb11
bb29: ; preds = %bb11
ret void
}

View File

@@ -0,0 +1,61 @@
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s
;
; void f(int *A) {
; for (int i = 0; i < 128; i++)
; for (int j = 0; j < 16; j++)
; A[i * j]++;
; }
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_bb7
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_bb7[i0, i1] : 0 <= i0 <= 127 and 0 <= i1 <= 15 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_bb7[i0, i1] -> [i0, i1] };
; CHECK-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb7[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2048 };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: +] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb7[i0, i1] -> MemRef_A[o0] : 0 <= o0 <= 2048 };
; CHECK-NEXT: }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A) {
bb:
br label %bb4
bb4: ; preds = %bb13, %bb
%indvars.iv1 = phi i64 [ %indvars.iv.next2, %bb13 ], [ 0, %bb ]
%exitcond3 = icmp ne i64 %indvars.iv1, 128
br i1 %exitcond3, label %bb5, label %bb14
bb5: ; preds = %bb4
br label %bb6
bb6: ; preds = %bb11, %bb5
%indvars.iv = phi i64 [ %indvars.iv.next, %bb11 ], [ 0, %bb5 ]
%exitcond = icmp ne i64 %indvars.iv, 16
br i1 %exitcond, label %bb7, label %bb12
bb7: ; preds = %bb6
%tmp = mul nsw i64 %indvars.iv1, %indvars.iv
%tmp8 = getelementptr inbounds i32, i32* %A, i64 %tmp
%tmp9 = load i32, i32* %tmp8, align 4
%tmp10 = add nsw i32 %tmp9, 1
store i32 %tmp10, i32* %tmp8, align 4
br label %bb11
bb11: ; preds = %bb7
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb6
bb12: ; preds = %bb6
br label %bb13
bb13: ; preds = %bb12
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
br label %bb4
bb14: ; preds = %bb4
ret void
}

View File

@@ -0,0 +1,58 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_for_body
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] : 0 <= i0 < N };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] -> [i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] -> MemRef_A[o0] : -4 + N + 5i0 <= 5o0 <= N + 5i0 };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] -> MemRef_A[o0] : -N + 5i0 <= 5o0 <= 4 - N + 5i0 };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_for_body[i0] -> MemRef_A[i0] };
; CHECK-NEXT: }
;
; void f(int *A, int N) {
; for (int i = 0; i < N; i++)
; A[i] = A[i + (N / 5)] + A[i + (N / -5)];
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A, i32 %N) {
entry:
%tmp = sext i32 %N to i64
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
%cmp = icmp slt i64 %indvars.iv, %tmp
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%div = sdiv i32 %N, 5
%tmp1 = trunc i64 %indvars.iv to i32
%add = add nsw i32 %tmp1, %div
%idxprom = sext i32 %add to i64
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
%tmp2 = load i32, i32* %arrayidx, align 4
%div1 = sdiv i32 %N, -5
%tmp3 = trunc i64 %indvars.iv to i32
%add2 = add nsw i32 %tmp3, %div1
%idxprom3 = sext i32 %add2 to i64
%arrayidx4 = getelementptr inbounds i32, i32* %A, i64 %idxprom3
%tmp4 = load i32, i32* %arrayidx4, align 4
%add5 = add nsw i32 %tmp2, %tmp4
%arrayidx7 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
store i32 %add5, i32* %arrayidx7, align 4
br label %for.inc
for.inc: ; preds = %for.body
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}

View File

@@ -0,0 +1,89 @@
; RUN: opt %loadPolly -polly-scops \
; RUN: -analyze < %s | FileCheck %s
;
; void pos(float *A, long n) {
; for (long i = 0; i < 100; i++)
; A[n % 42] += 1;
; }
;
;
; void neg(float *A, long n) {
; for (long i = 0; i < 100; i++)
; A[n % (-42)] += 1;
; }
; CHECK: Statements {
; CHECK-NEXT: Stmt_bb2
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] : 0 <= i0 <= 99 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] -> [i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] : 42*floor((-n + o0)/42) = -n + o0 and -41 <= o0 <= 41 and ((n < 0 and o0 <= 0) or (n >= 0 and o0 >= 0)) }
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] : 42*floor((-n + o0)/42) = -n + o0 and -41 <= o0 <= 41 and ((n < 0 and o0 <= 0) or (n >= 0 and o0 >= 0)) }
; CHECK-NEXT: }
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_bb2
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] : 0 <= i0 <= 99 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] -> [i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] : 42*floor((-n + o0)/42) = -n + o0 and -41 <= o0 <= 41 and ((n > 0 and o0 >= 0) or (n <= 0 and o0 <= 0)) }
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] : 42*floor((-n + o0)/42) = -n + o0 and -41 <= o0 <= 41 and ((n > 0 and o0 >= 0) or (n <= 0 and o0 <= 0)) }
; CHECK-NEXT: }
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @pos(float* %A, i64 %n) {
bb:
br label %bb1
bb1: ; preds = %bb6, %bb
%i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
%exitcond = icmp ne i64 %i.0, 100
br i1 %exitcond, label %bb2, label %bb8
bb2: ; preds = %bb1
%tmp = srem i64 %n, 42
%tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
%tmp4 = load float, float* %tmp3, align 4
%tmp5 = fadd float %tmp4, 1.000000e+00
store float %tmp5, float* %tmp3, align 4
br label %bb6
bb6: ; preds = %bb2
%tmp7 = add nsw i64 %i.0, 1
br label %bb1
bb8: ; preds = %bb1
ret void
}
define void @neg(float* %A, i64 %n) {
bb:
br label %bb1
bb1: ; preds = %bb6, %bb
%i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
%exitcond = icmp ne i64 %i.0, 100
br i1 %exitcond, label %bb2, label %bb8
bb2: ; preds = %bb1
%tmp = srem i64 %n, -42
%tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
%tmp4 = load float, float* %tmp3, align 4
%tmp5 = fadd float %tmp4, 1.000000e+00
store float %tmp5, float* %tmp3, align 4
br label %bb6
bb6: ; preds = %bb2
%tmp7 = add nsw i64 %i.0, 1
br label %bb1
bb8: ; preds = %bb1
ret void
}

View File

@@ -0,0 +1,71 @@
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine-branches \
; RUN: -analyze < %s | FileCheck %s
;
; void f(int *A) {
; for (int i = 0; i < 1024; i++)
; if (A[i])
; if (A[i - 1])
; A[i] = A[i - 2];
; }
;
; CHECK: Region: %bb1---%bb18
; CHECK: Max Loop Depth: 1
; CHECK: Statements {
; CHECK: Stmt_bb2__TO__bb16
; CHECK: Schedule :=
; CHECK: { Stmt_bb2__TO__bb16[i0] -> [i0] };
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: { Stmt_bb2__TO__bb16[i0] -> MemRef_A[i0] };
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: { Stmt_bb2__TO__bb16[i0] -> MemRef_A[-1 + i0] };
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: { Stmt_bb2__TO__bb16[i0] -> MemRef_A[-2 + i0] };
; CHECK: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: { Stmt_bb2__TO__bb16[i0] -> MemRef_A[i0] };
; CHECK: }
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A) {
bb:
br label %bb1
bb1: ; preds = %bb17, %bb
%indvars.iv = phi i64 [ %indvars.iv.next, %bb17 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %bb2, label %bb18
bb2: ; preds = %bb1
%tmp = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp3 = load i32, i32* %tmp, align 4
%tmp4 = icmp eq i32 %tmp3, 0
br i1 %tmp4, label %bb16, label %bb5
bb5: ; preds = %bb2
%tmp6 = add nsw i64 %indvars.iv, -1
%tmp7 = getelementptr inbounds i32, i32* %A, i64 %tmp6
%tmp8 = load i32, i32* %tmp7, align 4
%tmp9 = icmp eq i32 %tmp8, 0
br i1 %tmp9, label %bb15, label %bb10
bb10: ; preds = %bb5
%tmp11 = add nsw i64 %indvars.iv, -2
%tmp12 = getelementptr inbounds i32, i32* %A, i64 %tmp11
%tmp13 = load i32, i32* %tmp12, align 4
%tmp14 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
store i32 %tmp13, i32* %tmp14, align 4
br label %bb15
bb15: ; preds = %bb5, %bb10
br label %bb16
bb16: ; preds = %bb2, %bb15
br label %bb17
bb17: ; preds = %bb16
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb1
bb18: ; preds = %bb1
ret void
}

View File

@@ -0,0 +1,157 @@
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-invariant-load-hoisting=true \
; RUN: -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=INNERMOST
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine \
; RUN: -polly-invariant-load-hoisting=true \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s \
; RUN: --check-prefix=ALL
;
; Negative test for INNERMOST.
; At the moment we will optimistically assume A[i] in the conditional before the inner
; loop might be invariant and expand the SCoP from the loop to include the conditional. However,
; during SCoP generation we will realize that A[i] is in not always invariant.
;
; Possible solutions could be:
; - Do not optimistically assume it to be invariant (as before this commit), however we would loose
; a lot of invariant cases due to possible aliasing.
; - Reduce the size of the SCoP if an assumed invariant access is in fact not invariant instead of
; rejecting the whole region.
;
; INNERMOST: Function: f
; INNERMOST-NEXT: Region: %bb4---%bb3
; INNERMOST-NEXT: Max Loop Depth: 1
; INNERMOST-NEXT: Invariant Accesses: {
; INNERMOST-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb4[] -> MemRef_A[p_2] };
; INNERMOST-NEXT: Execution Context: [tmp6, N, p_2] -> { : (tmp6 > 0 and p_2 >= N) or (tmp6 < 0 and p_2 >= N) or tmp6 = 0 }
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Context:
; INNERMOST-NEXT: [tmp6, N, p_2] -> { : -2147483648 <= tmp6 <= 2147483647 and -2147483648 <= N <= 2147483647 and 0 <= p_2 <= 1024 }
; INNERMOST-NEXT: Assumed Context:
; INNERMOST-NEXT: [tmp6, N, p_2] -> { : }
; INNERMOST-NEXT: Invalid Context:
; INNERMOST-NEXT: [tmp6, N, p_2] -> { : p_2 < N and (tmp6 < 0 or tmp6 > 0) }
; INNERMOST-NEXT: p0: %tmp6
; INNERMOST-NEXT: p1: %N
; INNERMOST-NEXT: p2: {0,+,1}<nuw><nsw><%bb3>
; INNERMOST-NEXT: Arrays {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next2; // Element size 8
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Arrays (Bounds as pw_affs) {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next2; // Element size 8
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Alias Groups (0):
; INNERMOST-NEXT: n/a
; INNERMOST-NEXT: Statements {
; INNERMOST-NEXT: Stmt_bb11
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb11[i0] : 0 <= i0 < N and (tmp6 < 0 or tmp6 > 0) };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb11[i0] -> [0, i0] : tmp6 < 0 or tmp6 > 0 };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb11[i0] -> MemRef_A[i0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb11[i0] -> MemRef_A[i0] };
; INNERMOST-NEXT: Stmt_bb18
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb18[] };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb18[] -> [1, 0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; INNERMOST-NEXT: [tmp6, N, p_2] -> { Stmt_bb18[] -> MemRef_indvars_iv_next2[] };
; INNERMOST-NEXT: }
;
; ALL: Function: f
; ALL-NEXT: Region: %bb3---%bb19
; ALL-NEXT: Max Loop Depth: 1
; ALL-NEXT: Invariant Accesses: {
; ALL-NEXT: }
; ALL-NEXT: Context:
; ALL-NEXT: { : }
; ALL-NEXT: Assumed Context:
; ALL-NEXT: { : }
; ALL-NEXT: Invalid Context:
; ALL-NEXT: { : 1 = 0 }
; ALL-NEXT: Arrays {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Arrays (Bounds as pw_affs) {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Alias Groups (0):
; ALL-NEXT: n/a
; ALL-NEXT: Statements {
; ALL-NEXT: Stmt_bb4__TO__bb17
; ALL-NEXT: Domain :=
; ALL-NEXT: { Stmt_bb4__TO__bb17[i0] : 0 <= i0 <= 1023 };
; ALL-NEXT: Schedule :=
; ALL-NEXT: { Stmt_bb4__TO__bb17[i0] -> [i0] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb4__TO__bb17[i0] -> MemRef_A[i0] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb4__TO__bb17[i0] -> MemRef_A[o0] : 0 <= o0 <= 2147483647 };
; ALL-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb4__TO__bb17[i0] -> MemRef_A[o0] : 0 <= o0 <= 2147483647 };
; ALL-NEXT: }
;
; void f(int *A, int N) {
; for (int i = 0; i < 1024; i++)
; if (A[i])
; for (int j = 0; j < N; j++)
; A[j]++;
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A, i32 %N) {
bb:
%tmp = sext i32 %N to i64
br label %bb3
bb3: ; preds = %bb18, %bb
%indvars.iv1 = phi i64 [ %indvars.iv.next2, %bb18 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv1, 1024
br i1 %exitcond, label %bb4, label %bb19
bb4: ; preds = %bb3
%tmp5 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
%tmp6 = load i32, i32* %tmp5, align 4
%tmp7 = icmp eq i32 %tmp6, 0
br i1 %tmp7, label %bb17, label %bb8
bb8: ; preds = %bb4
br label %bb9
bb9: ; preds = %bb15, %bb8
%indvars.iv = phi i64 [ %indvars.iv.next, %bb15 ], [ 0, %bb8 ]
%tmp10 = icmp slt i64 %indvars.iv, %tmp
br i1 %tmp10, label %bb11, label %bb16
bb11: ; preds = %bb9
%tmp12 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp13 = load i32, i32* %tmp12, align 4
%tmp14 = add nsw i32 %tmp13, 1
store i32 %tmp14, i32* %tmp12, align 4
br label %bb15
bb15: ; preds = %bb11
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb9
bb16: ; preds = %bb9
br label %bb17
bb17: ; preds = %bb4, %bb16
br label %bb18
bb18: ; preds = %bb17
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
br label %bb3
bb19: ; preds = %bb3
ret void
}

View File

@@ -0,0 +1,164 @@
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-invariant-load-hoisting=true \
; RUN: -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=INNERMOST
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine \
; RUN: -polly-invariant-load-hoisting=true \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=ALL
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine \
; RUN: -polly-invariant-load-hoisting=true \
; RUN: -polly-process-unprofitable=false \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops=true \
; RUN: -analyze < %s | FileCheck %s --check-prefix=PROFIT
;
; Negative test for INNERMOST.
; At the moment we will optimistically assume A[i] in the conditional before the inner
; loop might be invariant and expand the SCoP from the loop to include the conditional. However,
; during SCoP generation we will realize that A[i] is only sometimes invariant.
;
; Possible solutions could be:
; - Do not optimistically assume it to be invariant (as before this commit), however we would loose
; a lot of invariant cases due to possible aliasing.
; - Reduce the size of the SCoP if an assumed invariant access is in fact not invariant instead of
; rejecting the whole region.
;
; INNERMOST: Function: f
; INNERMOST-NEXT: Region: %bb4---%bb3
; INNERMOST-NEXT: Max Loop Depth: 1
; INNERMOST-NEXT: Invariant Accesses: {
; INNERMOST-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb4[] -> MemRef_A[p_2] };
; INNERMOST-NEXT: Execution Context: [tmp6, p_1, p_2] -> { : (tmp6 > 0 and p_2 >= p_1) or (tmp6 < 0 and p_2 >= p_1) or tmp6 = 0 }
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Context:
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { : -2147483648 <= tmp6 <= 2147483647 and -2199023255552 <= p_1 <= 2199023254528 and 0 <= p_2 <= 1024 }
; INNERMOST-NEXT: Assumed Context:
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { : }
; INNERMOST-NEXT: Invalid Context:
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { : p_2 < p_1 and (tmp6 < 0 or tmp6 > 0) }
; INNERMOST-NEXT: p0: %tmp6
; INNERMOST-NEXT: p1: {0,+,(sext i32 %N to i64)}<%bb3>
; INNERMOST-NEXT: p2: {0,+,1}<nuw><nsw><%bb3>
; INNERMOST-NEXT: Arrays {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next2; // Element size 8
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Arrays (Bounds as pw_affs) {
; INNERMOST-NEXT: i32 MemRef_A[*]; // Element size 4
; INNERMOST-NEXT: i64 MemRef_indvars_iv_next2; // Element size 8
; INNERMOST-NEXT: }
; INNERMOST-NEXT: Alias Groups (0):
; INNERMOST-NEXT: n/a
; INNERMOST-NEXT: Statements {
; INNERMOST-NEXT: Stmt_bb12
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb12[i0] : 0 <= i0 < p_1 and (tmp6 < 0 or tmp6 > 0) };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb12[i0] -> [0, i0] : tmp6 < 0 or tmp6 > 0 };
; INNERMOST-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb12[i0] -> MemRef_A[i0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0]
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb12[i0] -> MemRef_A[i0] };
; INNERMOST-NEXT: Stmt_bb19
; INNERMOST-NEXT: Domain :=
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb19[] };
; INNERMOST-NEXT: Schedule :=
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb19[] -> [1, 0] };
; INNERMOST-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; INNERMOST-NEXT: [tmp6, p_1, p_2] -> { Stmt_bb19[] -> MemRef_indvars_iv_next2[] };
; INNERMOST-NEXT: }
;
; ALL: Function: f
; ALL-NEXT: Region: %bb3---%bb20
; ALL-NEXT: Max Loop Depth: 1
; ALL-NEXT: Invariant Accesses: {
; ALL-NEXT: }
; ALL-NEXT: Context:
; ALL-NEXT: { : }
; ALL-NEXT: Assumed Context:
; ALL-NEXT: { : }
; ALL-NEXT: Invalid Context:
; ALL-NEXT: { : 1 = 0 }
; ALL-NEXT: Arrays {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Arrays (Bounds as pw_affs) {
; ALL-NEXT: i32 MemRef_A[*]; // Element size 4
; ALL-NEXT: }
; ALL-NEXT: Alias Groups (0):
; ALL-NEXT: n/a
; ALL-NEXT: Statements {
; ALL-NEXT: Stmt_bb4__TO__bb18
; ALL-NEXT: Domain :=
; ALL-NEXT: { Stmt_bb4__TO__bb18[i0] : 0 <= i0 <= 1023 };
; ALL-NEXT: Schedule :=
; ALL-NEXT: { Stmt_bb4__TO__bb18[i0] -> [i0] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb4__TO__bb18[i0] -> MemRef_A[i0] };
; ALL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb4__TO__bb18[i0] -> MemRef_A[o0] : 0 <= o0 <= 2199023254528 };
; ALL-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; ALL-NEXT: { Stmt_bb4__TO__bb18[i0] -> MemRef_A[o0] : 0 <= o0 <= 2199023254528 };
; ALL-NEXT: }
;
; PROFIT-NOT: Statements
;
; void f(int *A, int N) {
; for (int i = 0; i < 1024; i++)
; if (A[i])
; for (int j = 0; j < N * i; j++)
; A[j]++;
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A, i32 %N) {
bb:
%tmp = sext i32 %N to i64
br label %bb3
bb3: ; preds = %bb19, %bb
%indvars.iv1 = phi i64 [ %indvars.iv.next2, %bb19 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv1, 1024
br i1 %exitcond, label %bb4, label %bb20
bb4: ; preds = %bb3
%tmp5 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv1
%tmp6 = load i32, i32* %tmp5, align 4
%tmp7 = icmp eq i32 %tmp6, 0
br i1 %tmp7, label %bb18, label %bb8
bb8: ; preds = %bb4
br label %bb9
bb9: ; preds = %bb16, %bb8
%indvars.iv = phi i64 [ %indvars.iv.next, %bb16 ], [ 0, %bb8 ]
%tmp10 = mul nsw i64 %indvars.iv1, %tmp
%tmp11 = icmp slt i64 %indvars.iv, %tmp10
br i1 %tmp11, label %bb12, label %bb17
bb12: ; preds = %bb9
%tmp13 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp14 = load i32, i32* %tmp13, align 4
%tmp15 = add nsw i32 %tmp14, 1
store i32 %tmp15, i32* %tmp13, align 4
br label %bb16
bb16: ; preds = %bb12
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb9
bb17: ; preds = %bb9
br label %bb18
bb18: ; preds = %bb4, %bb17
br label %bb19
bb19: ; preds = %bb18
%indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
br label %bb3
bb20: ; preds = %bb3
ret void
}

View File

@@ -0,0 +1,80 @@
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine-branches \
; RUN: -analyze < %s | FileCheck %s
;
; void f(float *A) {
; for (int i = 0; i < 1024; i++)
; if (A[i] == A[i - 1])
; A[i]++;
; }
;
; CHECK: Function: f
; CHECK-NEXT: Region: %bb1---%bb14
; CHECK-NEXT: Max Loop Depth: 1
; CHECK-NEXT: Invariant Accesses: {
; CHECK-NEXT: }
; CHECK-NEXT: Context:
; CHECK-NEXT: { : }
; CHECK-NEXT: Assumed Context:
; CHECK-NEXT: { : }
; CHECK-NEXT: Invalid Context:
; CHECK-NEXT: { : 1 = 0 }
; CHECK-NEXT: Arrays {
; CHECK-NEXT: float MemRef_A[*]; // Element size 4
; CHECK-NEXT: }
; CHECK-NEXT: Arrays (Bounds as pw_affs) {
; CHECK-NEXT: float MemRef_A[*]; // Element size 4
; CHECK-NEXT: }
; CHECK-NEXT: Alias Groups (0):
; CHECK-NEXT: n/a
; CHECK-NEXT: Statements {
; CHECK-NEXT: Stmt_bb2__TO__bb12
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_bb2__TO__bb12[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_bb2__TO__bb12[i0] -> [i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb2__TO__bb12[i0] -> MemRef_A[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb2__TO__bb12[i0] -> MemRef_A[-1 + i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb2__TO__bb12[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb2__TO__bb12[i0] -> MemRef_A[i0] };
; CHECK-NEXT: }
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(float* %A) {
bb:
br label %bb1
bb1: ; preds = %bb13, %bb
%indvars.iv = phi i64 [ %indvars.iv.next, %bb13 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %bb2, label %bb14
bb2: ; preds = %bb1
%tmp = getelementptr inbounds float, float* %A, i64 %indvars.iv
%tmp3 = load float, float* %tmp, align 4
%tmp4 = add nsw i64 %indvars.iv, -1
%tmp5 = getelementptr inbounds float, float* %A, i64 %tmp4
%tmp6 = load float, float* %tmp5, align 4
%tmp7 = fcmp oeq float %tmp3, %tmp6
br i1 %tmp7, label %bb8, label %bb12
bb8: ; preds = %bb2
%tmp9 = getelementptr inbounds float, float* %A, i64 %indvars.iv
%tmp10 = load float, float* %tmp9, align 4
%tmp11 = fadd float %tmp10, 1.000000e+00
store float %tmp11, float* %tmp9, align 4
br label %bb12
bb12: ; preds = %bb8, %bb2
br label %bb13
bb13: ; preds = %bb12
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb1
bb14: ; preds = %bb1
ret void
}

View File

@@ -0,0 +1,99 @@
; RUN: opt %loadPolly -polly-scops \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops \
; RUN: -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine-branches \
; RUN: -polly-process-unprofitable=false \
; RUN: -polly-allow-nonaffine-loops -analyze < %s | FileCheck %s \
; RUN: --check-prefix=PROFIT
; RUN: opt %loadPolly -polly-scops -polly-detect-reductions \
; RUN: -polly-allow-nonaffine-branches \
; RUN: \
; RUN: -polly-allow-nonaffine-loops -analyze < %s \
; RUN: -polly-detect-reductions=false \
; RUN: | FileCheck %s -check-prefix=NO-REDUCTION
;
; void f(int *A, int *C) {
; for (int i = 0; i < 1024; i++) {
; while (C[i])
; A[i]++;
; }
; }
;
; CHECK: Function: f
; CHECK-NEXT: Region: %bb1---%bb12
; CHECK-NEXT: Max Loop Depth: 1
; CHECK-NEXT: Invariant Accesses: {
; CHECK-NEXT: }
; CHECK-NEXT: Context:
; CHECK-NEXT: { : }
; CHECK-NEXT: Assumed Context:
; CHECK-NEXT: { : }
; CHECK-NEXT: Invalid Context:
; CHECK-NEXT: { : 1 = 0 }
; CHECK-NEXT: Arrays {
; CHECK-NEXT: i32 MemRef_C[*]; // Element size 4
; CHECK-NEXT: i32 MemRef_A[*]; // Element size 4
; CHECK-NEXT: }
; CHECK-NEXT: Arrays (Bounds as pw_affs) {
; CHECK-NEXT: i32 MemRef_C[*]; // Element size 4
; CHECK-NEXT: i32 MemRef_A[*]; // Element size 4
; CHECK-NEXT: }
; CHECK-NEXT: Alias Groups (1):
; CHECK-NEXT: {{\[\[}} <{ MemRef_C[(0)] }, { MemRef_C[(1024)] }> <{ MemRef_A[(0)] }, { MemRef_A[(1024)] }> {{\]\]}}
; CHECK-NEXT: Statements {
; CHECK-NEXT: Stmt_bb3__TO__bb10
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_bb3__TO__bb10[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_bb3__TO__bb10[i0] -> [i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb3__TO__bb10[i0] -> MemRef_C[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb3__TO__bb10[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: +] [Scalar: 0]
; CHECK-NEXT: { Stmt_bb3__TO__bb10[i0] -> MemRef_A[i0] };
; CHECK-NEXT: }
; PROFIT-NOT: Statements
; NO-REDUCTION-NOT: Reduction Type: +
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A, i32* %C) {
bb:
br label %bb1
bb1: ; preds = %bb11, %bb
%indvars.iv = phi i64 [ %indvars.iv.next, %bb11 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %bb2, label %bb12
bb2: ; preds = %bb1
br label %bb3
bb3: ; preds = %bb6, %bb2
%tmp = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
%tmp4 = load i32, i32* %tmp, align 4
%tmp5 = icmp eq i32 %tmp4, 0
br i1 %tmp5, label %bb10, label %bb6
bb6: ; preds = %bb3
%tmp7 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp8 = load i32, i32* %tmp7, align 4
%tmp9 = add nsw i32 %tmp8, 1
store i32 %tmp9, i32* %tmp7, align 4
br label %bb3
bb10: ; preds = %bb3
br label %bb11
bb11: ; preds = %bb10
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb1
bb12: ; preds = %bb1
ret void
}

View File

@@ -0,0 +1,162 @@
; RUN: opt %loadPolly -polly-scops \
; RUN: -polly-allow-nonaffine -polly-allow-nonaffine-branches \
; RUN: -polly-allow-nonaffine-loops -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine \
; RUN: -polly-unprofitable-scalar-accs=true \
; RUN: -polly-process-unprofitable=false \
; RUN: -polly-allow-nonaffine-branches -polly-allow-nonaffine-loops \
; RUN: -analyze < %s | FileCheck %s --check-prefix=PROFIT
;
; Verify that we over approximate the read acces of A[j] in the last statement as j is
; computed in a non-affine loop we do not model.
;
; CHECK: Function: f
; CHECK-NEXT: Region: %bb2---%bb24
; CHECK-NEXT: Max Loop Depth: 1
; CHECK-NEXT: Invariant Accesses: {
; CHECK-NEXT: }
; CHECK-NEXT: Context:
; CHECK-NEXT: [N] -> { : -2147483648 <= N <= 2147483647 }
; CHECK-NEXT: Assumed Context:
; CHECK-NEXT: [N] -> { : }
; CHECK-NEXT: Invalid Context:
; CHECK-NEXT: [N] -> { : 1 = 0 }
; CHECK-NEXT: p0: %N
; CHECK-NEXT: Arrays {
; CHECK-NEXT: i32 MemRef_j_0__phi; // Element size 4
; CHECK-NEXT: i32 MemRef_j_0; // Element size 4
; CHECK-NEXT: i32 MemRef_A[*]; // Element size 4
; CHECK-NEXT: i32 MemRef_j_2__phi; // Element size 4
; CHECK-NEXT: i32 MemRef_j_2; // Element size 4
; CHECK-NEXT: }
; CHECK-NEXT: Arrays (Bounds as pw_affs) {
; CHECK-NEXT: i32 MemRef_j_0__phi; // Element size 4
; CHECK-NEXT: i32 MemRef_j_0; // Element size 4
; CHECK-NEXT: i32 MemRef_A[*]; // Element size 4
; CHECK-NEXT: i32 MemRef_j_2__phi; // Element size 4
; CHECK-NEXT: i32 MemRef_j_2; // Element size 4
; CHECK-NEXT: }
; CHECK-NEXT: Alias Groups (0):
; CHECK-NEXT: n/a
; CHECK-NEXT: Statements {
; CHECK-NEXT: Stmt_bb2
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [N] -> { Stmt_bb2[i0] : 0 <= i0 <= N; Stmt_bb2[0] : N < 0 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [N] -> { Stmt_bb2[i0] -> [i0, 0] : i0 <= N; Stmt_bb2[0] -> [0, 0] : N < 0 };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb2[i0] -> MemRef_j_0__phi[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb2[i0] -> MemRef_j_0[] };
; CHECK-NEXT: Stmt_bb4__TO__bb18
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] : 0 <= i0 < N };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> [i0, 1] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_A[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_j_2__phi[] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb4__TO__bb18[i0] -> MemRef_j_0[] };
; CHECK-NEXT: Stmt_bb18
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [N] -> { Stmt_bb18[i0] : 0 <= i0 < N };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [N] -> { Stmt_bb18[i0] -> [i0, 2] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb18[i0] -> MemRef_j_2[] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb18[i0] -> MemRef_j_2__phi[] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_bb18[i0] -> MemRef_A[o0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [N] -> { Stmt_bb18[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Stmt_bb23
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [N] -> { Stmt_bb23[i0] : 0 <= i0 < N };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [N] -> { Stmt_bb23[i0] -> [i0, 3] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb23[i0] -> MemRef_j_2[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [N] -> { Stmt_bb23[i0] -> MemRef_j_0__phi[] };
; CHECK-NEXT: }
;
; Due to the scalar accesses we are not able to distribute the outer loop, thus we do not consider the region profitable.
;
; PROFIT-NOT: Statements
;
; void f(int *A, int N, int M) {
; int i = 0, j = 0;
; for (i = 0; i < N; i++) {
; if (A[i])
; for (j = 0; j < M; j++)
; A[i]++;
; A[i] = A[j];
; }
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32* %A, i32 %N, i32 %M) {
bb:
%tmp = icmp sgt i32 %M, 0
%smax = select i1 %tmp, i32 %M, i32 0
%tmp1 = sext i32 %N to i64
br label %bb2
bb2: ; preds = %bb23, %bb
%indvars.iv = phi i64 [ %indvars.iv.next, %bb23 ], [ 0, %bb ]
%j.0 = phi i32 [ 0, %bb ], [ %j.2, %bb23 ]
%tmp3 = icmp slt i64 %indvars.iv, %tmp1
br i1 %tmp3, label %bb4, label %bb24
bb4: ; preds = %bb2
%tmp5 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp6 = load i32, i32* %tmp5, align 4
%tmp7 = icmp eq i32 %tmp6, 0
br i1 %tmp7, label %bb18, label %bb8
bb8: ; preds = %bb4
br label %bb9
bb9: ; preds = %bb15, %bb8
%j.1 = phi i32 [ 0, %bb8 ], [ %tmp16, %bb15 ]
%tmp10 = icmp slt i32 %j.1, %M
br i1 %tmp10, label %bb11, label %bb17
bb11: ; preds = %bb9
%tmp12 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%tmp13 = load i32, i32* %tmp12, align 4
%tmp14 = add nsw i32 %tmp13, 1
store i32 %tmp14, i32* %tmp12, align 4
br label %bb15
bb15: ; preds = %bb11
%tmp16 = add nuw nsw i32 %j.1, 1
br label %bb9
bb17: ; preds = %bb9
br label %bb18
bb18: ; preds = %bb4, %bb17
%j.2 = phi i32 [ %smax, %bb17 ], [ %j.0, %bb4 ]
%tmp19 = sext i32 %j.2 to i64
%tmp20 = getelementptr inbounds i32, i32* %A, i64 %tmp19
%tmp21 = load i32, i32* %tmp20, align 4
%tmp22 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
store i32 %tmp21, i32* %tmp22, align 4
br label %bb23
bb23: ; preds = %bb18
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb2
bb24: ; preds = %bb2
ret void
}

View File

@@ -0,0 +1,39 @@
; RUN: opt %loadPolly -basicaa -polly-scops -analyze -polly-allow-nonaffine < %s | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
; void foo(long n, double A[], int INDEX[]) {
; for (long i = 0; i < n; i++)
; A[INDEX[i]] = i;
; }
define void @foo(i64 %n, double* noalias %A, i64* noalias %INDEX) {
entry:
br label %for.body
for.body:
%i = phi i64 [ %inc, %for.body ], [ 0, %entry ]
%arrayidx = getelementptr inbounds i64, i64* %INDEX, i64 %i
%val = load i64, i64* %arrayidx
%arrayidx1 = getelementptr inbounds double, double* %A, i64 %val
store double 1.0, double* %arrayidx1
%inc = add nsw i64 %i, 1
%exitcond = icmp eq i64 %inc, %n
br i1 %exitcond, label %for.end, label %for.body
for.end:
ret void
}
; CHECK: p0: %n
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_for_body
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [n] -> { Stmt_for_body[i0] : 0 <= i0 < n };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [n] -> { Stmt_for_body[i0] -> [i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_for_body[i0] -> MemRef_INDEX[i0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_for_body[i0] -> MemRef_A[o0] };
; CHECK-NEXT: }

View File

@@ -0,0 +1,57 @@
; RUN: opt %loadPolly -polly-detect -polly-scops -analyze \
; RUN: -polly-allow-nonaffine-loops < %s | FileCheck %s
; The BasicBlock "guaranteed" is always executed inside the non-affine subregion
; region_entry->region_exit. As such, writes accesses in blocks that always
; execute are MustWriteAccesses. Before Polly commit r255473, we only assumed
; that the subregion's entry block is guaranteed to execute.
; CHECK-NOT: MayWriteAccess
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] };
; CHECK-NOT: MayWriteAccess
define void @f(i32* %A, i32* %B, i32* %C, float %b) {
entry:
br label %for.cond
for.cond:
%indvar = phi i32 [ %indvar.next, %for.inc ], [ 0, %entry ]
%exitcond = icmp ne i32 %indvar, 1024
br i1 %exitcond, label %region_entry, label %return
region_entry:
br label %bb2
bb2:
br label %guaranteed
bb3:
br label %bb3
guaranteed:
%ptr = getelementptr i32, i32* %B, i32 %indvar
%val = load i32, i32* %ptr
%cmp = icmp eq i32 %val, 0
store i32 0, i32* %A
br i1 %cmp, label %bb5, label %bb6
bb5:
br label %region_exit
bb6:
%ptr2 = getelementptr i32, i32* %C, i32 %indvar
%val2 = load i32, i32* %ptr2
%cmp2 = icmp eq i32 %val2, 0
br i1 %cmp2, label %region_exit, label %region_entry
region_exit:
br label %for.inc
for.inc:
%indvar.next = add i32 %indvar, 1
br label %for.cond
return:
ret void
}

View File

@@ -0,0 +1,30 @@
; RUN: opt %loadPolly -polly-scops -analyze < %s
;
; Regression test that triggered a memory leak at some point (24947).
;
define void @snrm2() {
entry:
br label %for.body.56.lr.ph
for.body.56.lr.ph: ; preds = %entry
br label %for.body.56
for.body.56: ; preds = %for.inc.106, %for.body.56.lr.ph
br label %if.end.73
if.end.73: ; preds = %for.body.56
%cmp82 = fcmp ogt float undef, undef
br i1 %cmp82, label %if.then.84, label %if.end.100
if.then.84: ; preds = %if.end.73
br label %for.inc.106
if.end.100: ; preds = %if.end.73
br label %for.inc.106
for.inc.106: ; preds = %if.end.100, %if.then.84
br i1 undef, label %for.body.56, label %for.end.110
for.end.110: ; preds = %for.inc.106
ret void
}