Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / Transforms / CorrelatedValuePropagation / overflows.ll
blobeccc72d45dd7291172a1588074d917329382a089
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
24 entry:
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()
35   unreachable
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 ]
64   ret i32 %cond
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
71 entry:
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()
78   unreachable
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 ]
93   ret i32 %cond
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
100 entry:
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()
111   unreachable
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 ]
140   ret i32 %cond
143 define i32 @unsigned_sub(i32 %x, i32 %y) {
144 ; CHECK-LABEL: @unsigned_sub(
145 ; CHECK: @llvm.usub.with.overflow.i32
146 entry:
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()
158   unreachable
160 cond.end:                                         ; preds = %cond.false, %entry
161   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
162   ret i32 %cond
165 define i32 @signed_add_r1(i32 %x) {
166 ; CHECK-LABEL: @signed_add_r1(
167 ; CHECK-NOT: @llvm.sadd.with.overflow.i32
168 entry:
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()
180   unreachable
182 cond.end:                                         ; preds = %cond.false, %entry
183   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
184   ret i32 %cond
187 define i32 @unsigned_add_r1(i32 %x) {
188 ; CHECK-LABEL: @unsigned_add_r1(
189 ; CHECK-NOT: @llvm.uadd.with.overflow.i32
190 entry:
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()
202   unreachable
204 cond.end:                                         ; preds = %cond.false, %entry
205   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
206   ret i32 %cond
209 define i32 @signed_sub_r1(i32 %x) {
210 ; CHECK-LABEL: @signed_sub_r1(
211 ; CHECK-NOT: @llvm.ssub.with.overflow.i32
212 entry:
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()
224   unreachable
226 cond.end:                                         ; preds = %cond.false, %entry
227   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
228   ret i32 %cond
231 define i32 @unsigned_sub_r1(i32 %x) {
232 ; CHECK-LABEL: @unsigned_sub_r1(
233 ; CHECK-NOT: @llvm.usub.with.overflow.i32
234 entry:
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()
246   unreachable
248 cond.end:                                         ; preds = %cond.false, %entry
249   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
250   ret i32 %cond
253 define i32 @signed_add_rn1(i32 %x) {
254 ; CHECK-LABEL: @signed_add_rn1(
255 ; CHECK-NOT: @llvm.sadd.with.overflow.i32
256 entry:
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()
268   unreachable
270 cond.end:                                         ; preds = %cond.false, %entry
271   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
272   ret i32 %cond
275 define i32 @signed_sub_rn1(i32 %x) {
276 ; CHECK-LABEL: @signed_sub_rn1(
277 ; CHECK-NOT: @llvm.ssub.with.overflow.i32
278 entry:
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()
290   unreachable
292 cond.end:                                         ; preds = %cond.false, %entry
293   %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
294   ret i32 %cond
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
302 entry:
303   %cmp3 = icmp eq i32 %i, 0
304   br i1 %cmp3, label %while.end, label %while.body.preheader
306 while.body.preheader:                             ; preds = %entry
307   br label %while.body
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()
318   unreachable
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
326   ret void
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
333 entry:
334   br label %cont
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()
343   unreachable
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
353   br label %while.body
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
373   ret void