1
2; RUN: opt %s -analyze -scalar-evolution -enable-new-pm=0 -scalar-evolution-classify-expressions=0 2>&1 | FileCheck %s
3
4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7; A collection of tests focused on exercising logic to prove no-unsigned wrap
8; from mustprogress semantics of loops.
9
10; CHECK: Determining loop execution counts for: @test
11; CHECK: Loop %for.body: Unpredictable backedge-taken count.
12; CHECK: Determining loop execution counts for: @test_preinc
13; CHECK: Loop %for.body: Unpredictable backedge-taken count.
14; CHECK: Determining loop execution counts for: @test_well_defined_infinite_st
15; CHECK: Loop %for.body: Unpredictable backedge-taken count.
16; CHECK: Determining loop execution counts for: @test_well_defined_infinite_ld
17; CHECK: Loop %for.body: Unpredictable backedge-taken count.
18; CHECK: Determining loop execution counts for: @test_no_mustprogress
19; CHECK: Loop %for.body: Unpredictable backedge-taken count.
20; CHECK: Determining loop execution counts for: @test_1024
21; CHECK: Loop %for.body: Unpredictable backedge-taken count.
22; CHECK: Determining loop execution counts for: @test_uneven_divide
23; CHECK: Loop %for.body: backedge-taken count is (-1 + (-1431655765 * %N))
24; CHECK: Determining loop execution counts for: @test_non_invariant_rhs
25; CHECK: Loop %for.body: Unpredictable backedge-taken count.
26; CHECK: Determining loop execution counts for: @test_abnormal_exit
27; CHECK: Loop %for.body: Unpredictable backedge-taken count.
28; CHECK: Determining loop execution counts for: @test_other_exit
29; CHECK: Loop %for.body: <multiple exits> Unpredictable backedge-taken count.
30
31define void @test(i32 %N) mustprogress {
32entry:
33  br label %for.body
34
35for.body:
36  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
37  %iv.next = add i32 %iv, 2
38  %cmp = icmp ne i32 %iv.next, %N
39  br i1 %cmp, label %for.body, label %for.cond.cleanup
40
41for.cond.cleanup:
42  ret void
43}
44
45define void @test_preinc(i32 %N) mustprogress {
46entry:
47  br label %for.body
48
49for.body:
50  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
51  %iv.next = add i32 %iv, 2
52  %cmp = icmp ne i32 %iv, %N
53  br i1 %cmp, label %for.body, label %for.cond.cleanup
54
55for.cond.cleanup:
56  ret void
57
58}
59
60@G = external global i32
61
62define void @test_well_defined_infinite_st(i32 %N) mustprogress {
63entry:
64  br label %for.body
65
66for.body:
67  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
68  %iv.next = add i32 %iv, 2
69  store volatile i32 0, i32* @G
70  %cmp = icmp ne i32 %iv.next, %N
71  br i1 %cmp, label %for.body, label %for.cond.cleanup
72
73for.cond.cleanup:
74  ret void
75}
76
77define void @test_well_defined_infinite_ld(i32 %N) mustprogress {
78entry:
79  br label %for.body
80
81for.body:
82  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
83  %iv.next = add i32 %iv, 2
84  %val = load volatile i32, i32* @G
85  %cmp = icmp ne i32 %iv.next, %N
86  br i1 %cmp, label %for.body, label %for.cond.cleanup
87
88for.cond.cleanup:
89  ret void
90}
91
92define void @test_no_mustprogress(i32 %N) {
93entry:
94  br label %for.body
95
96for.body:
97  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
98  %iv.next = add i32 %iv, 2
99  %cmp = icmp ne i32 %iv.next, %N
100  br i1 %cmp, label %for.body, label %for.cond.cleanup
101
102for.cond.cleanup:
103  ret void
104
105}
106
107
108define void @test_1024(i32 %N) mustprogress {
109entry:
110  br label %for.body
111
112for.body:
113  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
114  %iv.next = add i32 %iv, 1024
115  %cmp = icmp ne i32 %iv.next, %N
116  br i1 %cmp, label %for.body, label %for.cond.cleanup
117
118for.cond.cleanup:
119  ret void
120}
121
122define void @test_uneven_divide(i32 %N) mustprogress {
123entry:
124  br label %for.body
125
126for.body:
127  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
128  %iv.next = add i32 %iv, 3
129  %cmp = icmp ne i32 %iv.next, %N
130  br i1 %cmp, label %for.body, label %for.cond.cleanup
131
132for.cond.cleanup:
133  ret void
134}
135
136define void @test_non_invariant_rhs() mustprogress {
137entry:
138  br label %for.body
139
140for.body:
141  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
142  %iv.next = add i32 %iv, 2
143  %N = load i32, i32* @G
144  %cmp = icmp ne i32 %iv.next, %N
145  br i1 %cmp, label %for.body, label %for.cond.cleanup
146
147for.cond.cleanup:
148  ret void
149}
150
151declare void @mayexit()
152
153define void @test_abnormal_exit(i32 %N) mustprogress {
154entry:
155  br label %for.body
156
157for.body:
158  %iv = phi i32 [ %iv.next, %for.body ], [ 0, %entry ]
159  %iv.next = add i32 %iv, 2
160  call void @mayexit()
161  %cmp = icmp ne i32 %iv.next, %N
162  br i1 %cmp, label %for.body, label %for.cond.cleanup
163
164for.cond.cleanup:
165  ret void
166}
167
168
169define void @test_other_exit(i32 %N) mustprogress {
170entry:
171  br label %for.body
172
173for.body:
174  %iv = phi i32 [ %iv.next, %for.latch ], [ 0, %entry ]
175  %iv.next = add i32 %iv, 2
176  %cmp1 = icmp ne i32 %iv.next, 20
177  br i1 %cmp1, label %for.latch, label %for.cond.cleanup
178
179for.latch:
180  %cmp2 = icmp ne i32 %iv.next, %N
181  br i1 %cmp2, label %for.body, label %for.cond.cleanup
182
183for.cond.cleanup:
184  ret void
185}
186
187
188