1 ; RUN: opt -S -correlated-propagation < %s | FileCheck %s
3 ; Check that debug locations are preserved. For more info see:
4 ; https://llvm.org/docs/SourceLevelDebugging.html#fixing-errors
5 ; RUN: opt < %s -enable-debugify -correlated-propagation -S 2>&1 | \
6 ; RUN: FileCheck %s -check-prefix=DEBUG
7 ; DEBUG: CheckModuleDebugify: PASS
9 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
11 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
13 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
15 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
17 declare void @llvm.trap()
20 define i32 @signed_add(i32 %x, i32 %y) {
21 ; CHECK-LABEL: @signed_add(
22 ; CHECK-NOT: @llvm.ssub.with.overflow.i32
23 ; CHECK: @llvm.sadd.with.overflow.i32
25 %cmp = icmp sgt i32 %y, 0
26 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
28 land.lhs.true: ; preds = %entry
29 %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 2147483647, i32 %y)
30 %1 = extractvalue { i32, i1 } %0, 1
31 br i1 %1, label %trap, label %cont
33 trap: ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
34 tail call void @llvm.trap()
37 cont: ; preds = %land.lhs.true
38 %2 = extractvalue { i32, i1 } %0, 0
39 %cmp1 = icmp slt i32 %2, %x
40 br i1 %cmp1, label %cond.end, label %cond.false
42 lor.lhs.false: ; preds = %entry
43 %cmp2 = icmp slt i32 %y, 0
44 br i1 %cmp2, label %land.lhs.true3, label %cond.false
46 land.lhs.true3: ; preds = %lor.lhs.false
47 %3 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 -2147483648, i32 %y)
48 %4 = extractvalue { i32, i1 } %3, 1
49 br i1 %4, label %trap, label %cont4
51 cont4: ; preds = %land.lhs.true3
52 %5 = extractvalue { i32, i1 } %3, 0
53 %cmp5 = icmp sgt i32 %5, %x
54 br i1 %cmp5, label %cond.end, label %cond.false
56 cond.false: ; preds = %cont, %cont4, %lor.lhs.false
57 %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
58 %7 = extractvalue { i32, i1 } %6, 0
59 %8 = extractvalue { i32, i1 } %6, 1
60 br i1 %8, label %trap, label %cond.end
62 cond.end: ; preds = %cond.false, %cont, %cont4
63 %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
67 define i32 @unsigned_add(i32 %x, i32 %y) {
68 ; CHECK-LABEL: @unsigned_add(
69 ; CHECK-NOT: @llvm.usub.with.overflow.i32
70 ; CHECK: @llvm.uadd.with.overflow.i32
72 %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
73 %1 = extractvalue { i32, i1 } %0, 1
74 br i1 %1, label %trap, label %cont
76 trap: ; preds = %cond.false, %entry
77 tail call void @llvm.trap()
80 cont: ; preds = %entry
81 %2 = extractvalue { i32, i1 } %0, 0
82 %cmp1 = icmp ult i32 %2, %x
83 br i1 %cmp1, label %cond.end, label %cond.false
85 cond.false: ; preds = %cont
86 %3 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
87 %4 = extractvalue { i32, i1 } %3, 0
88 %5 = extractvalue { i32, i1 } %3, 1
89 br i1 %5, label %trap, label %cond.end
91 cond.end: ; preds = %cond.false, %cont
92 %cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
96 define i32 @signed_sub(i32 %x, i32 %y) {
97 ; CHECK-LABEL: @signed_sub(
98 ; CHECK-NOT: @llvm.sadd.with.overflow.i32
99 ; CHECK: @llvm.ssub.with.overflow.i32
101 %cmp = icmp slt i32 %y, 0
102 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
104 land.lhs.true: ; preds = %entry
105 %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 2147483647)
106 %1 = extractvalue { i32, i1 } %0, 1
107 br i1 %1, label %trap, label %cont
109 trap: ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
110 tail call void @llvm.trap()
113 cont: ; preds = %land.lhs.true
114 %2 = extractvalue { i32, i1 } %0, 0
115 %cmp1 = icmp slt i32 %2, %x
116 br i1 %cmp1, label %cond.end, label %cond.false
118 lor.lhs.false: ; preds = %entry
119 %cmp2 = icmp eq i32 %y, 0
120 br i1 %cmp2, label %cond.false, label %land.lhs.true3
122 land.lhs.true3: ; preds = %lor.lhs.false
123 %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 -2147483648)
124 %4 = extractvalue { i32, i1 } %3, 1
125 br i1 %4, label %trap, label %cont4
127 cont4: ; preds = %land.lhs.true3
128 %5 = extractvalue { i32, i1 } %3, 0
129 %cmp5 = icmp sgt i32 %5, %x
130 br i1 %cmp5, label %cond.end, label %cond.false
132 cond.false: ; preds = %lor.lhs.false, %cont, %cont4
133 %6 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
134 %7 = extractvalue { i32, i1 } %6, 0
135 %8 = extractvalue { i32, i1 } %6, 1
136 br i1 %8, label %trap, label %cond.end
138 cond.end: ; preds = %cond.false, %cont, %cont4
139 %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
143 define i32 @unsigned_sub(i32 %x, i32 %y) {
144 ; CHECK-LABEL: @unsigned_sub(
145 ; CHECK: @llvm.usub.with.overflow.i32
147 %cmp = icmp ult i32 %x, %y
148 br i1 %cmp, label %cond.end, label %cond.false
150 cond.false: ; preds = %entry
151 %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
152 %1 = extractvalue { i32, i1 } %0, 0
153 %2 = extractvalue { i32, i1 } %0, 1
154 br i1 %2, label %trap, label %cond.end
156 trap: ; preds = %cond.false
157 tail call void @llvm.trap()
160 cond.end: ; preds = %cond.false, %entry
161 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
165 define i32 @signed_add_r1(i32 %x) {
166 ; CHECK-LABEL: @signed_add_r1(
167 ; CHECK-NOT: @llvm.sadd.with.overflow.i32
169 %cmp = icmp eq i32 %x, 2147483647
170 br i1 %cmp, label %cond.end, label %cond.false
172 cond.false: ; preds = %entry
173 %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
174 %1 = extractvalue { i32, i1 } %0, 0
175 %2 = extractvalue { i32, i1 } %0, 1
176 br i1 %2, label %trap, label %cond.end
178 trap: ; preds = %cond.false
179 tail call void @llvm.trap()
182 cond.end: ; preds = %cond.false, %entry
183 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
187 define i32 @unsigned_add_r1(i32 %x) {
188 ; CHECK-LABEL: @unsigned_add_r1(
189 ; CHECK-NOT: @llvm.uadd.with.overflow.i32
191 %cmp = icmp eq i32 %x, -1
192 br i1 %cmp, label %cond.end, label %cond.false
194 cond.false: ; preds = %entry
195 %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 1)
196 %1 = extractvalue { i32, i1 } %0, 0
197 %2 = extractvalue { i32, i1 } %0, 1
198 br i1 %2, label %trap, label %cond.end
200 trap: ; preds = %cond.false
201 tail call void @llvm.trap()
204 cond.end: ; preds = %cond.false, %entry
205 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
209 define i32 @signed_sub_r1(i32 %x) {
210 ; CHECK-LABEL: @signed_sub_r1(
211 ; CHECK-NOT: @llvm.ssub.with.overflow.i32
213 %cmp = icmp eq i32 %x, -2147483648
214 br i1 %cmp, label %cond.end, label %cond.false
216 cond.false: ; preds = %entry
217 %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
218 %1 = extractvalue { i32, i1 } %0, 0
219 %2 = extractvalue { i32, i1 } %0, 1
220 br i1 %2, label %trap, label %cond.end
222 trap: ; preds = %cond.false
223 tail call void @llvm.trap()
226 cond.end: ; preds = %cond.false, %entry
227 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
231 define i32 @unsigned_sub_r1(i32 %x) {
232 ; CHECK-LABEL: @unsigned_sub_r1(
233 ; CHECK-NOT: @llvm.usub.with.overflow.i32
235 %cmp = icmp eq i32 %x, 0
236 br i1 %cmp, label %cond.end, label %cond.false
238 cond.false: ; preds = %entry
239 %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 1)
240 %1 = extractvalue { i32, i1 } %0, 0
241 %2 = extractvalue { i32, i1 } %0, 1
242 br i1 %2, label %trap, label %cond.end
244 trap: ; preds = %cond.false
245 tail call void @llvm.trap()
248 cond.end: ; preds = %cond.false, %entry
249 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
253 define i32 @signed_add_rn1(i32 %x) {
254 ; CHECK-LABEL: @signed_add_rn1(
255 ; CHECK-NOT: @llvm.sadd.with.overflow.i32
257 %cmp = icmp eq i32 %x, -2147483648
258 br i1 %cmp, label %cond.end, label %cond.false
260 cond.false: ; preds = %entry
261 %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 -1)
262 %1 = extractvalue { i32, i1 } %0, 0
263 %2 = extractvalue { i32, i1 } %0, 1
264 br i1 %2, label %trap, label %cond.end
266 trap: ; preds = %cond.false
267 tail call void @llvm.trap()
270 cond.end: ; preds = %cond.false, %entry
271 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
275 define i32 @signed_sub_rn1(i32 %x) {
276 ; CHECK-LABEL: @signed_sub_rn1(
277 ; CHECK-NOT: @llvm.ssub.with.overflow.i32
279 %cmp = icmp eq i32 %x, 2147483647
280 br i1 %cmp, label %cond.end, label %cond.false
282 cond.false: ; preds = %entry
283 %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 -1)
284 %1 = extractvalue { i32, i1 } %0, 0
285 %2 = extractvalue { i32, i1 } %0, 1
286 br i1 %2, label %trap, label %cond.end
288 trap: ; preds = %cond.false
289 tail call void @llvm.trap()
292 cond.end: ; preds = %cond.false, %entry
293 %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
297 declare i32 @bar(i32)
299 define void @unsigned_loop(i32 %i) {
300 ; CHECK-LABEL: @unsigned_loop(
301 ; CHECK-NOT: @llvm.usub.with.overflow.i32
303 %cmp3 = icmp eq i32 %i, 0
304 br i1 %cmp3, label %while.end, label %while.body.preheader
306 while.body.preheader: ; preds = %entry
309 while.body: ; preds = %while.body.preheader, %cont
310 %i.addr.04 = phi i32 [ %2, %cont ], [ %i, %while.body.preheader ]
311 %call = tail call i32 @bar(i32 %i.addr.04)
312 %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.addr.04, i32 1)
313 %1 = extractvalue { i32, i1 } %0, 1
314 br i1 %1, label %trap, label %cont
316 trap: ; preds = %while.body
317 tail call void @llvm.trap()
320 cont: ; preds = %while.body
321 %2 = extractvalue { i32, i1 } %0, 0
322 %cmp = icmp eq i32 %2, 0
323 br i1 %cmp, label %while.end, label %while.body
325 while.end: ; preds = %cont, %entry
329 define void @intrinsic_into_phi(i32 %n) {
330 ; CHECK-LABEL: @intrinsic_into_phi(
331 ; CHECK: @llvm.sadd.with.overflow.i32
332 ; CHECK-NOT: @llvm.sadd.with.overflow.i32
336 for.cond: ; preds = %while.end
337 %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %.lcssa, i32 1)
338 %1 = extractvalue { i32, i1 } %0, 1
339 br i1 %1, label %trap, label %cont
341 trap: ; preds = %for.cond, %while.body
342 tail call void @llvm.trap()
345 cont: ; preds = %entry, %for.cond
346 %2 = phi { i32, i1 } [ zeroinitializer, %entry ], [ %0, %for.cond ]
347 %3 = extractvalue { i32, i1 } %2, 0
348 %call9 = tail call i32 @bar(i32 %3)
349 %tobool10 = icmp eq i32 %call9, 0
350 br i1 %tobool10, label %while.end, label %while.body.preheader
352 while.body.preheader: ; preds = %cont
355 while.cond: ; preds = %while.body
356 %4 = extractvalue { i32, i1 } %6, 0
357 %call = tail call i32 @bar(i32 %4)
358 %tobool = icmp eq i32 %call, 0
359 br i1 %tobool, label %while.end, label %while.body
361 while.body: ; preds = %while.body.preheader, %while.cond
362 %5 = phi i32 [ %4, %while.cond ], [ %3, %while.body.preheader ]
363 %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1)
364 %7 = extractvalue { i32, i1 } %6, 1
365 br i1 %7, label %trap, label %while.cond
367 while.end: ; preds = %while.cond, %cont
368 %.lcssa = phi i32 [ %3, %cont ], [ %4, %while.cond ]
369 %cmp = icmp slt i32 %.lcssa, %n
370 br i1 %cmp, label %for.cond, label %cleanup2
372 cleanup2: ; preds = %while.end