1; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
2; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s --check-prefix=IR
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; Check that we do not crash and generate valid IR.
11;
12; CHECK:      Assumed Context:
13; CHECK-NEXT:   [count1, dobreak, count2] -> {  :  }
14; CHECK-NEXT: Invalid Context:
15; CHECK-NEXT:   [count1, dobreak, count2] -> {  : (count1 > 0 and dobreak > 0) or count1 <= 0 or (count1 > 0 and dobreak <= 0 and count2 > 0) }
16;
17; CHECK:      Stmt_loop_enter
18; CHECK-NEXT:     Domain :=
19; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_enter[] : count1 > 0 };
20
21; CHECK:      Stmt_loop_break
22; CHECK-NEXT:     Domain :=
23; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_break[] : count1 > 0 and dobreak > 0 };
24
25; CHECK:      Stmt_loop_finish
26; CHECK-NEXT:     Domain :=
27; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_finish[] : count1 > 0 and dobreak <= 0 and count2 > 0 };
28
29; CHECK:      Stmt_loop_skip
30; CHECK-NEXT:     Domain :=
31; CHECK-NEXT:         [count1, dobreak, count2] -> { Stmt_loop_skip[] : count1 <= 0 };
32
33; IR:      polly.merge_new_and_old:
34; IR-NEXT:   %phi.ph.merge = phi float [ %phi.ph.final_reload, %polly.exiting ], [ %phi.ph, %return.region_exiting ]
35; IR-NEXT:   br label %return
36;
37; IR:      return:
38; IR-NEXT:   %phi = phi float [ %phi.ph.merge, %polly.merge_new_and_old ]
39
40declare void @g();
41
42define void @func(i64 %count1, i64 %count2, i32 %dobreak, float* %A) {
43entry:
44  %fadd = fadd float undef, undef
45  br label %loopguard
46
47loopguard:
48  %cmp6 = icmp sgt i64 %count1, 0
49  br i1 %cmp6, label %loop_enter, label %loop_skip
50
51
52loop_enter:
53  store float 1.0, float* %A
54  br label %loop_header
55
56loop_header:
57  %indvars.iv63 = phi i64 [ %indvars.iv.next64, %loop_continue ], [ 0, %loop_enter ]
58  %indvars.iv.next64 = add nuw nsw i64 %indvars.iv63, 1
59  %add8 = add i64 undef, undef
60  %cmp_break = icmp sge i32 %dobreak, 1
61  br i1 %cmp_break, label %loop_break, label %loop_continue
62
63loop_continue:
64  %cmp9 = icmp eq i64 %indvars.iv.next64, %count2
65  br i1 %cmp9, label %loop_finish, label %loop_header
66
67
68loop_break:
69  store float 2.0, float* %A
70  br label %loop_break_error
71
72loop_break_error:
73  %cmp_loop_break = fcmp oeq float %fadd, 2.
74  br i1 %cmp_loop_break, label %loop_break_g, label %return
75
76loop_break_g:
77  call void @g()
78  br label %return
79
80
81loop_finish:
82    store float 3.0, float* %A
83  br label %loop_finish_error
84
85loop_finish_error:
86  call void @g()
87  br label %return
88
89
90loop_skip:
91  store float 4.0, float* %A
92  br label %loop_skip_error
93
94loop_skip_error:
95  call void @g()
96  br label %return
97
98
99return:
100  %phi = phi float [ 0.0, %loop_finish_error ], [ 0.0, %loop_break_error ], [ 2.0, %loop_break_g ], [ 3.0, %loop_skip_error ]
101  store float 1.0, float* %A
102  ret void
103}
104