1; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s --check-prefix=AFFINE
2; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s --check-prefix=NONAFFINE
3
4; The SCoP contains a loop with multiple exit blocks (BBs after leaving
5; the loop). The current implementation of deriving their domain derives
6; only a common domain for all of the exit blocks. We disabled loops with
7; multiple exit blocks until this is fixed.
8; XFAIL: *
9
10; The loop for.body => for.inc has an unpredictable iteration count could due to
11; the undef start value that it is compared to. Therefore the array element
12; %arrayidx101 that depends on that exit value cannot be affine.
13; Derived from test-suite/MultiSource/Benchmarks/BitBench/uuencode/uuencode.c
14
15define void @encode_line(i8* nocapture readonly %input, i32 %octets, i64 %p, i32 %n) {
16entry:
17  br label %outer.for
18
19outer.for:
20  %j = phi i32 [0, %entry], [%j.inc, %for.end]
21  %j.cmp = icmp slt i32 %j, %n
22  br i1 %j.cmp, label %for.body, label %exit
23
24
25
26for.body:
27  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ %p, %outer.for ]
28  %octets.addr.02 = phi i32 [ undef, %for.inc ], [ %octets, %outer.for ]
29  br i1 false, label %for.inc, label %if.else
30
31if.else:
32  %cond = icmp eq i32 %octets.addr.02, 2
33  br i1 %cond, label %if.then84, label %for.end
34
35if.then84:
36  %0 = add nsw i64 %indvars.iv, 1
37  %arrayidx101 = getelementptr inbounds i8, i8* %input, i64 %0
38  store i8 42, i8* %arrayidx101, align 1
39  br label %for.end
40
41for.inc:
42  %cmp = icmp sgt i32 %octets.addr.02, 3
43  %indvars.iv.next = add nsw i64 %indvars.iv, 3
44  br i1 %cmp, label %for.body, label %for.end
45
46
47
48for.end:
49  %j.inc = add nuw nsw i32 %j, 1
50  br label %outer.for
51
52exit:
53  br label %return
54
55return:
56  ret void
57}
58
59
60; AFFINE:       Region: %if.else---%for.end
61
62; AFFINE:       Statements {
63; AFFINE-NEXT:  	Stmt_if_then84
64; AFFINE-NEXT:          Domain :=
65; AFFINE-NEXT:              [octets, p_1, p] -> { Stmt_if_then84[] : octets = 2 };
66; AFFINE-NEXT:          Schedule :=
67; AFFINE-NEXT:              [octets, p_1, p] -> { Stmt_if_then84[] -> [] };
68; AFFINE-NEXT:          MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
69; AFFINE-NEXT:              [octets, p_1, p] -> { Stmt_if_then84[] -> MemRef_input[1 + p] };
70; AFFINE-NEXT:  }
71
72
73; NONAFFINE:      Region: %outer.for---%return
74
75; NONAFFINE:      Statements {
76; NONAFFINE-NEXT: 	Stmt_for_body
77; NONAFFINE-NEXT:         Domain :=
78; NONAFFINE-NEXT:             [n, octets] -> { Stmt_for_body[i0, 0] : 0 <= i0 < n };
79; NONAFFINE-NEXT:         Schedule :=
80; NONAFFINE-NEXT:             [n, octets] -> { Stmt_for_body[i0, i1] -> [i0, 0, 0] };
81; NONAFFINE-NEXT:         MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 1]
82; NONAFFINE-NEXT:             [n, octets] -> { Stmt_for_body[i0, i1] -> MemRef_indvars_iv[] };
83; NONAFFINE-NEXT: 	Stmt_if_then84
84; NONAFFINE-NEXT:         Domain :=
85; NONAFFINE-NEXT:             [n, octets] -> { Stmt_if_then84[i0] : octets = 2 and 0 <= i0 < n };
86; NONAFFINE-NEXT:         Schedule :=
87; NONAFFINE-NEXT:             [n, octets] -> { Stmt_if_then84[i0] -> [i0, 1, 0] };
88; NONAFFINE-NEXT:         ReadAccess :=	[Reduction Type: NONE] [Scalar: 1]
89; NONAFFINE-NEXT:             [n, octets] -> { Stmt_if_then84[i0] -> MemRef_indvars_iv[] };
90; NONAFFINE-NEXT:         MayWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
91; NONAFFINE-NEXT:             [n, octets] -> { Stmt_if_then84[i0] -> MemRef_input[o0] };
92; NONAFFINE-NEXT: }
93