1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -debugify-and-strip-all-safe < %s -mtriple=aarch64-linux-gnu | FileCheck %s
4 ; marked as external to prevent possible optimizations
5 @a = external global i32
6 @b = external global i32
7 @c = external global i32
8 @d = external global i32
10 ; (a > 10 && b == c) || (a >= 10 && b == d)
11 define i32 @combine_gt_ge_10() #0 {
12 ; CHECK-LABEL: combine_gt_ge_10:
13 ; CHECK: // %bb.0: // %entry
14 ; CHECK-NEXT: adrp x8, :got:a
15 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
16 ; CHECK-NEXT: ldr w8, [x8]
17 ; CHECK-NEXT: cmp w8, #10
18 ; CHECK-NEXT: adrp x8, :got:b
19 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
20 ; CHECK-NEXT: b.le .LBB0_3
21 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
22 ; CHECK-NEXT: adrp x9, :got:c
23 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
24 ; CHECK-NEXT: ldr w10, [x8]
25 ; CHECK-NEXT: ldr w9, [x9]
26 ; CHECK-NEXT: cmp w10, w9
27 ; CHECK-NEXT: b.ne .LBB0_4
28 ; CHECK-NEXT: // %bb.2:
29 ; CHECK-NEXT: mov w0, #1 // =0x1
31 ; CHECK-NEXT: .LBB0_3: // %lor.lhs.false
32 ; CHECK-NEXT: b.lt .LBB0_6
33 ; CHECK-NEXT: .LBB0_4: // %land.lhs.true3
34 ; CHECK-NEXT: adrp x9, :got:d
35 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
36 ; CHECK-NEXT: ldr w8, [x8]
37 ; CHECK-NEXT: ldr w9, [x9]
38 ; CHECK-NEXT: cmp w8, w9
39 ; CHECK-NEXT: b.ne .LBB0_6
40 ; CHECK-NEXT: // %bb.5:
41 ; CHECK-NEXT: mov w0, #1 // =0x1
43 ; CHECK-NEXT: .LBB0_6: // %if.end
44 ; CHECK-NEXT: mov w0, wzr
47 %0 = load i32, ptr @a, align 4
48 %cmp = icmp sgt i32 %0, 10
49 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
51 land.lhs.true: ; preds = %entry
52 %1 = load i32, ptr @b, align 4
53 %2 = load i32, ptr @c, align 4
54 %cmp1 = icmp eq i32 %1, %2
55 br i1 %cmp1, label %return, label %land.lhs.true3
57 lor.lhs.false: ; preds = %entry
58 %cmp2 = icmp sgt i32 %0, 9
59 br i1 %cmp2, label %land.lhs.true3, label %if.end
61 land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
62 %3 = load i32, ptr @b, align 4
63 %4 = load i32, ptr @d, align 4
64 %cmp4 = icmp eq i32 %3, %4
65 br i1 %cmp4, label %return, label %if.end
67 if.end: ; preds = %land.lhs.true3, %lor.lhs.false
70 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
71 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
75 ; (a > 5 && b == c) || (a < 5 && b == d)
76 define i32 @combine_gt_lt_5() #0 {
77 ; CHECK-LABEL: combine_gt_lt_5:
78 ; CHECK: // %bb.0: // %entry
79 ; CHECK-NEXT: adrp x8, :got:a
80 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
81 ; CHECK-NEXT: ldr w8, [x8]
82 ; CHECK-NEXT: cmp w8, #5
83 ; CHECK-NEXT: b.le .LBB1_3
84 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
85 ; CHECK-NEXT: adrp x8, :got:b
86 ; CHECK-NEXT: adrp x9, :got:c
87 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
88 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
89 ; CHECK-NEXT: ldr w8, [x8]
90 ; CHECK-NEXT: ldr w9, [x9]
91 ; CHECK-NEXT: cmp w8, w9
92 ; CHECK-NEXT: b.ne .LBB1_6
93 ; CHECK-NEXT: // %bb.2:
94 ; CHECK-NEXT: mov w0, #1 // =0x1
96 ; CHECK-NEXT: .LBB1_3: // %lor.lhs.false
97 ; CHECK-NEXT: b.ge .LBB1_6
98 ; CHECK-NEXT: // %bb.4: // %land.lhs.true3
99 ; CHECK-NEXT: adrp x8, :got:b
100 ; CHECK-NEXT: adrp x9, :got:d
101 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
102 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
103 ; CHECK-NEXT: ldr w8, [x8]
104 ; CHECK-NEXT: ldr w9, [x9]
105 ; CHECK-NEXT: cmp w8, w9
106 ; CHECK-NEXT: b.ne .LBB1_6
107 ; CHECK-NEXT: // %bb.5:
108 ; CHECK-NEXT: mov w0, #1 // =0x1
110 ; CHECK-NEXT: .LBB1_6: // %if.end
111 ; CHECK-NEXT: mov w0, wzr
114 %0 = load i32, ptr @a, align 4
115 %cmp = icmp sgt i32 %0, 5
116 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
118 land.lhs.true: ; preds = %entry
119 %1 = load i32, ptr @b, align 4
120 %2 = load i32, ptr @c, align 4
121 %cmp1 = icmp eq i32 %1, %2
122 br i1 %cmp1, label %return, label %if.end
124 lor.lhs.false: ; preds = %entry
125 %cmp2 = icmp slt i32 %0, 5
126 br i1 %cmp2, label %land.lhs.true3, label %if.end
128 land.lhs.true3: ; preds = %lor.lhs.false
129 %3 = load i32, ptr @b, align 4
130 %4 = load i32, ptr @d, align 4
131 %cmp4 = icmp eq i32 %3, %4
132 br i1 %cmp4, label %return, label %if.end
134 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
137 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
138 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
142 ; (a < 5 && b == c) || (a <= 5 && b == d)
143 define i32 @combine_lt_ge_5() #0 {
144 ; CHECK-LABEL: combine_lt_ge_5:
145 ; CHECK: // %bb.0: // %entry
146 ; CHECK-NEXT: adrp x8, :got:a
147 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
148 ; CHECK-NEXT: ldr w8, [x8]
149 ; CHECK-NEXT: cmp w8, #5
150 ; CHECK-NEXT: adrp x8, :got:b
151 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
152 ; CHECK-NEXT: b.ge .LBB2_3
153 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
154 ; CHECK-NEXT: adrp x9, :got:c
155 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
156 ; CHECK-NEXT: ldr w10, [x8]
157 ; CHECK-NEXT: ldr w9, [x9]
158 ; CHECK-NEXT: cmp w10, w9
159 ; CHECK-NEXT: b.ne .LBB2_4
160 ; CHECK-NEXT: // %bb.2:
161 ; CHECK-NEXT: mov w0, #1 // =0x1
163 ; CHECK-NEXT: .LBB2_3: // %lor.lhs.false
164 ; CHECK-NEXT: b.gt .LBB2_6
165 ; CHECK-NEXT: .LBB2_4: // %land.lhs.true3
166 ; CHECK-NEXT: adrp x9, :got:d
167 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
168 ; CHECK-NEXT: ldr w8, [x8]
169 ; CHECK-NEXT: ldr w9, [x9]
170 ; CHECK-NEXT: cmp w8, w9
171 ; CHECK-NEXT: b.ne .LBB2_6
172 ; CHECK-NEXT: // %bb.5:
173 ; CHECK-NEXT: mov w0, #1 // =0x1
175 ; CHECK-NEXT: .LBB2_6: // %if.end
176 ; CHECK-NEXT: mov w0, wzr
179 %0 = load i32, ptr @a, align 4
180 %cmp = icmp slt i32 %0, 5
181 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
183 land.lhs.true: ; preds = %entry
184 %1 = load i32, ptr @b, align 4
185 %2 = load i32, ptr @c, align 4
186 %cmp1 = icmp eq i32 %1, %2
187 br i1 %cmp1, label %return, label %land.lhs.true3
189 lor.lhs.false: ; preds = %entry
190 %cmp2 = icmp slt i32 %0, 6
191 br i1 %cmp2, label %land.lhs.true3, label %if.end
193 land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
194 %3 = load i32, ptr @b, align 4
195 %4 = load i32, ptr @d, align 4
196 %cmp4 = icmp eq i32 %3, %4
197 br i1 %cmp4, label %return, label %if.end
199 if.end: ; preds = %land.lhs.true3, %lor.lhs.false
202 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
203 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
207 ; (a < 5 && b == c) || (a > 5 && b == d)
208 define i32 @combine_lt_gt_5() #0 {
209 ; CHECK-LABEL: combine_lt_gt_5:
210 ; CHECK: // %bb.0: // %entry
211 ; CHECK-NEXT: adrp x8, :got:a
212 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
213 ; CHECK-NEXT: ldr w8, [x8]
214 ; CHECK-NEXT: cmp w8, #5
215 ; CHECK-NEXT: b.ge .LBB3_3
216 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
217 ; CHECK-NEXT: adrp x8, :got:b
218 ; CHECK-NEXT: adrp x9, :got:c
219 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
220 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
221 ; CHECK-NEXT: ldr w8, [x8]
222 ; CHECK-NEXT: ldr w9, [x9]
223 ; CHECK-NEXT: cmp w8, w9
224 ; CHECK-NEXT: b.ne .LBB3_6
225 ; CHECK-NEXT: // %bb.2:
226 ; CHECK-NEXT: mov w0, #1 // =0x1
228 ; CHECK-NEXT: .LBB3_3: // %lor.lhs.false
229 ; CHECK-NEXT: b.le .LBB3_6
230 ; CHECK-NEXT: // %bb.4: // %land.lhs.true3
231 ; CHECK-NEXT: adrp x8, :got:b
232 ; CHECK-NEXT: adrp x9, :got:d
233 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
234 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
235 ; CHECK-NEXT: ldr w8, [x8]
236 ; CHECK-NEXT: ldr w9, [x9]
237 ; CHECK-NEXT: cmp w8, w9
238 ; CHECK-NEXT: b.ne .LBB3_6
239 ; CHECK-NEXT: // %bb.5:
240 ; CHECK-NEXT: mov w0, #1 // =0x1
242 ; CHECK-NEXT: .LBB3_6: // %if.end
243 ; CHECK-NEXT: mov w0, wzr
246 %0 = load i32, ptr @a, align 4
247 %cmp = icmp slt i32 %0, 5
248 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
250 land.lhs.true: ; preds = %entry
251 %1 = load i32, ptr @b, align 4
252 %2 = load i32, ptr @c, align 4
253 %cmp1 = icmp eq i32 %1, %2
254 br i1 %cmp1, label %return, label %if.end
256 lor.lhs.false: ; preds = %entry
257 %cmp2 = icmp sgt i32 %0, 5
258 br i1 %cmp2, label %land.lhs.true3, label %if.end
260 land.lhs.true3: ; preds = %lor.lhs.false
261 %3 = load i32, ptr @b, align 4
262 %4 = load i32, ptr @d, align 4
263 %cmp4 = icmp eq i32 %3, %4
264 br i1 %cmp4, label %return, label %if.end
266 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
269 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
270 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
274 ; (a > -5 && b == c) || (a < -5 && b == d)
275 define i32 @combine_gt_lt_n5() #0 {
276 ; CHECK-LABEL: combine_gt_lt_n5:
277 ; CHECK: // %bb.0: // %entry
278 ; CHECK-NEXT: adrp x8, :got:a
279 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
280 ; CHECK-NEXT: ldr w8, [x8]
281 ; CHECK-NEXT: cmn w8, #5
282 ; CHECK-NEXT: b.le .LBB4_3
283 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
284 ; CHECK-NEXT: adrp x8, :got:b
285 ; CHECK-NEXT: adrp x9, :got:c
286 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
287 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
288 ; CHECK-NEXT: ldr w8, [x8]
289 ; CHECK-NEXT: ldr w9, [x9]
290 ; CHECK-NEXT: cmp w8, w9
291 ; CHECK-NEXT: b.ne .LBB4_6
292 ; CHECK-NEXT: // %bb.2:
293 ; CHECK-NEXT: mov w0, #1 // =0x1
295 ; CHECK-NEXT: .LBB4_3: // %lor.lhs.false
296 ; CHECK-NEXT: b.ge .LBB4_6
297 ; CHECK-NEXT: // %bb.4: // %land.lhs.true3
298 ; CHECK-NEXT: adrp x8, :got:b
299 ; CHECK-NEXT: adrp x9, :got:d
300 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
301 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
302 ; CHECK-NEXT: ldr w8, [x8]
303 ; CHECK-NEXT: ldr w9, [x9]
304 ; CHECK-NEXT: cmp w8, w9
305 ; CHECK-NEXT: b.ne .LBB4_6
306 ; CHECK-NEXT: // %bb.5:
307 ; CHECK-NEXT: mov w0, #1 // =0x1
309 ; CHECK-NEXT: .LBB4_6: // %if.end
310 ; CHECK-NEXT: mov w0, wzr
313 %0 = load i32, ptr @a, align 4
314 %cmp = icmp sgt i32 %0, -5
315 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
317 land.lhs.true: ; preds = %entry
318 %1 = load i32, ptr @b, align 4
319 %2 = load i32, ptr @c, align 4
320 %cmp1 = icmp eq i32 %1, %2
321 br i1 %cmp1, label %return, label %if.end
323 lor.lhs.false: ; preds = %entry
324 %cmp2 = icmp slt i32 %0, -5
325 br i1 %cmp2, label %land.lhs.true3, label %if.end
327 land.lhs.true3: ; preds = %lor.lhs.false
328 %3 = load i32, ptr @b, align 4
329 %4 = load i32, ptr @d, align 4
330 %cmp4 = icmp eq i32 %3, %4
331 br i1 %cmp4, label %return, label %if.end
333 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
336 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
337 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
341 ; (a < -5 && b == c) || (a > -5 && b == d)
342 define i32 @combine_lt_gt_n5() #0 {
343 ; CHECK-LABEL: combine_lt_gt_n5:
344 ; CHECK: // %bb.0: // %entry
345 ; CHECK-NEXT: adrp x8, :got:a
346 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
347 ; CHECK-NEXT: ldr w8, [x8]
348 ; CHECK-NEXT: cmn w8, #5
349 ; CHECK-NEXT: b.ge .LBB5_3
350 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
351 ; CHECK-NEXT: adrp x8, :got:b
352 ; CHECK-NEXT: adrp x9, :got:c
353 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
354 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
355 ; CHECK-NEXT: ldr w8, [x8]
356 ; CHECK-NEXT: ldr w9, [x9]
357 ; CHECK-NEXT: cmp w8, w9
358 ; CHECK-NEXT: b.ne .LBB5_6
359 ; CHECK-NEXT: // %bb.2:
360 ; CHECK-NEXT: mov w0, #1 // =0x1
362 ; CHECK-NEXT: .LBB5_3: // %lor.lhs.false
363 ; CHECK-NEXT: b.le .LBB5_6
364 ; CHECK-NEXT: // %bb.4: // %land.lhs.true3
365 ; CHECK-NEXT: adrp x8, :got:b
366 ; CHECK-NEXT: adrp x9, :got:d
367 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
368 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
369 ; CHECK-NEXT: ldr w8, [x8]
370 ; CHECK-NEXT: ldr w9, [x9]
371 ; CHECK-NEXT: cmp w8, w9
372 ; CHECK-NEXT: b.ne .LBB5_6
373 ; CHECK-NEXT: // %bb.5:
374 ; CHECK-NEXT: mov w0, #1 // =0x1
376 ; CHECK-NEXT: .LBB5_6: // %if.end
377 ; CHECK-NEXT: mov w0, wzr
380 %0 = load i32, ptr @a, align 4
381 %cmp = icmp slt i32 %0, -5
382 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
384 land.lhs.true: ; preds = %entry
385 %1 = load i32, ptr @b, align 4
386 %2 = load i32, ptr @c, align 4
387 %cmp1 = icmp eq i32 %1, %2
388 br i1 %cmp1, label %return, label %if.end
390 lor.lhs.false: ; preds = %entry
391 %cmp2 = icmp sgt i32 %0, -5
392 br i1 %cmp2, label %land.lhs.true3, label %if.end
394 land.lhs.true3: ; preds = %lor.lhs.false
395 %3 = load i32, ptr @b, align 4
396 %4 = load i32, ptr @d, align 4
397 %cmp4 = icmp eq i32 %3, %4
398 br i1 %cmp4, label %return, label %if.end
400 if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
403 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
404 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
408 %struct.Struct = type { i64, i64 }
410 @glob = internal unnamed_addr global ptr null, align 8
412 declare ptr @Update(ptr) #1
414 ; no checks for this case, it just should be processed without errors
415 define void @combine_non_adjacent_cmp_br(ptr nocapture readonly %hdCall) #0 {
416 ; CHECK-LABEL: combine_non_adjacent_cmp_br:
417 ; CHECK: // %bb.0: // %entry
418 ; CHECK-NEXT: str x30, [sp, #-48]! // 8-byte Folded Spill
419 ; CHECK-NEXT: .cfi_def_cfa_offset 48
420 ; CHECK-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill
421 ; CHECK-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill
422 ; CHECK-NEXT: .cfi_offset w19, -8
423 ; CHECK-NEXT: .cfi_offset w20, -16
424 ; CHECK-NEXT: .cfi_offset w21, -24
425 ; CHECK-NEXT: .cfi_offset w22, -32
426 ; CHECK-NEXT: .cfi_offset w30, -48
427 ; CHECK-NEXT: ldr x20, [x0]
428 ; CHECK-NEXT: mov w19, #24 // =0x18
429 ; CHECK-NEXT: adrp x22, glob
430 ; CHECK-NEXT: add x21, x20, #2
431 ; CHECK-NEXT: .LBB6_1: // %land.rhs
432 ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
433 ; CHECK-NEXT: ldr x8, [x19]
434 ; CHECK-NEXT: cmp x8, #1
435 ; CHECK-NEXT: b.lt .LBB6_3
436 ; CHECK-NEXT: // %bb.2: // %while.body
437 ; CHECK-NEXT: // in Loop: Header=BB6_1 Depth=1
438 ; CHECK-NEXT: ldr x0, [x22, :lo12:glob]
439 ; CHECK-NEXT: bl Update
440 ; CHECK-NEXT: sub x21, x21, #2
441 ; CHECK-NEXT: cmp x20, x21
442 ; CHECK-NEXT: b.lt .LBB6_1
443 ; CHECK-NEXT: .LBB6_3: // %while.end
444 ; CHECK-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
445 ; CHECK-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
446 ; CHECK-NEXT: ldr x30, [sp], #48 // 8-byte Folded Reload
447 ; CHECK-NEXT: .cfi_def_cfa_offset 0
448 ; CHECK-NEXT: .cfi_restore w19
449 ; CHECK-NEXT: .cfi_restore w20
450 ; CHECK-NEXT: .cfi_restore w21
451 ; CHECK-NEXT: .cfi_restore w22
452 ; CHECK-NEXT: .cfi_restore w30
455 %0 = load i64, ptr %hdCall, align 8
459 %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ]
460 %1 = load i64, ptr inttoptr (i64 24 to ptr), align 8
461 %cmp2 = icmp sgt i64 %1, 0
462 br i1 %cmp2, label %while.body, label %while.end
465 %2 = load ptr, ptr @glob, align 8
466 %call = tail call ptr @Update(ptr %2) #2
467 %sub = add nsw i64 %rp.06, -2
468 %cmp = icmp slt i64 %0, %rp.06
469 br i1 %cmp, label %land.rhs, label %while.end
475 ; undefined external to prevent possible optimizations
476 declare void @do_something() #1
478 define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
479 ; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ:
480 ; CHECK: // %bb.0: // %entry
481 ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
482 ; CHECK-NEXT: .cfi_def_cfa_offset 32
483 ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
484 ; CHECK-NEXT: .cfi_offset w19, -8
485 ; CHECK-NEXT: .cfi_offset w20, -16
486 ; CHECK-NEXT: .cfi_offset w30, -32
487 ; CHECK-NEXT: adrp x19, :got:a
488 ; CHECK-NEXT: ldr x19, [x19, :got_lo12:a]
489 ; CHECK-NEXT: ldr w8, [x19]
490 ; CHECK-NEXT: cmn w8, #2
491 ; CHECK-NEXT: b.gt .LBB7_4
492 ; CHECK-NEXT: // %bb.1: // %while.body.preheader
493 ; CHECK-NEXT: sub w20, w8, #1
494 ; CHECK-NEXT: .LBB7_2: // %while.body
495 ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
496 ; CHECK-NEXT: bl do_something
497 ; CHECK-NEXT: adds w20, w20, #1
498 ; CHECK-NEXT: b.mi .LBB7_2
499 ; CHECK-NEXT: // %bb.3: // %while.cond.while.end_crit_edge
500 ; CHECK-NEXT: ldr w8, [x19]
501 ; CHECK-NEXT: .LBB7_4: // %while.end
502 ; CHECK-NEXT: cmp w8, #1
503 ; CHECK-NEXT: b.gt .LBB7_7
504 ; CHECK-NEXT: // %bb.5: // %land.lhs.true
505 ; CHECK-NEXT: adrp x8, :got:b
506 ; CHECK-NEXT: adrp x9, :got:d
507 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
508 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
509 ; CHECK-NEXT: ldr w8, [x8]
510 ; CHECK-NEXT: ldr w9, [x9]
511 ; CHECK-NEXT: cmp w8, w9
512 ; CHECK-NEXT: b.ne .LBB7_7
513 ; CHECK-NEXT: // %bb.6:
514 ; CHECK-NEXT: mov w0, #123 // =0x7b
515 ; CHECK-NEXT: b .LBB7_8
516 ; CHECK-NEXT: .LBB7_7: // %if.end
517 ; CHECK-NEXT: mov w0, wzr
518 ; CHECK-NEXT: .LBB7_8: // %return
519 ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
520 ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
521 ; CHECK-NEXT: .cfi_def_cfa_offset 0
522 ; CHECK-NEXT: .cfi_restore w19
523 ; CHECK-NEXT: .cfi_restore w20
524 ; CHECK-NEXT: .cfi_restore w30
527 %0 = load i32, ptr @a, align 4
528 %cmp4 = icmp slt i32 %0, -1
529 br i1 %cmp4, label %while.body.preheader, label %while.end
531 while.body.preheader: ; preds = %entry
534 while.body: ; preds = %while.body, %while.body.preheader
535 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
536 tail call void @do_something() #2
537 %inc = add nsw i32 %i.05, 1
538 %cmp = icmp slt i32 %i.05, 0
539 br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge
541 while.cond.while.end_crit_edge: ; preds = %while.body
542 %.pre = load i32, ptr @a, align 4
545 while.end: ; preds = %while.cond.while.end_crit_edge, %entry
546 %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ]
547 %cmp1 = icmp slt i32 %1, 2
548 br i1 %cmp1, label %land.lhs.true, label %if.end
550 land.lhs.true: ; preds = %while.end
551 %2 = load i32, ptr @b, align 4
552 %3 = load i32, ptr @d, align 4
553 %cmp2 = icmp eq i32 %2, %3
554 br i1 %cmp2, label %return, label %if.end
556 if.end: ; preds = %land.lhs.true, %while.end
559 return: ; preds = %if.end, %land.lhs.true
560 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
564 define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
565 ; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other:
566 ; CHECK: // %bb.0: // %entry
567 ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
568 ; CHECK-NEXT: .cfi_def_cfa_offset 16
569 ; CHECK-NEXT: .cfi_offset w19, -8
570 ; CHECK-NEXT: .cfi_offset w30, -16
571 ; CHECK-NEXT: .cfi_remember_state
572 ; CHECK-NEXT: adrp x8, :got:a
573 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
574 ; CHECK-NEXT: ldr w8, [x8]
575 ; CHECK-NEXT: cmp w8, #0
576 ; CHECK-NEXT: b.gt .LBB8_3
577 ; CHECK-NEXT: // %bb.1: // %while.body.preheader
578 ; CHECK-NEXT: sub w19, w8, #1
579 ; CHECK-NEXT: .LBB8_2: // %while.body
580 ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
581 ; CHECK-NEXT: bl do_something
582 ; CHECK-NEXT: adds w19, w19, #1
583 ; CHECK-NEXT: b.mi .LBB8_2
584 ; CHECK-NEXT: .LBB8_3: // %while.end
585 ; CHECK-NEXT: adrp x8, :got:c
586 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:c]
587 ; CHECK-NEXT: ldr w8, [x8]
588 ; CHECK-NEXT: cmn w8, #2
589 ; CHECK-NEXT: b.lt .LBB8_6
590 ; CHECK-NEXT: // %bb.4: // %land.lhs.true
591 ; CHECK-NEXT: adrp x8, :got:b
592 ; CHECK-NEXT: adrp x9, :got:d
593 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
594 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
595 ; CHECK-NEXT: ldr w8, [x8]
596 ; CHECK-NEXT: ldr w9, [x9]
597 ; CHECK-NEXT: cmp w8, w9
598 ; CHECK-NEXT: b.ne .LBB8_6
599 ; CHECK-NEXT: // %bb.5:
600 ; CHECK-NEXT: mov w0, #123 // =0x7b
601 ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
602 ; CHECK-NEXT: .cfi_def_cfa_offset 0
603 ; CHECK-NEXT: .cfi_restore w19
604 ; CHECK-NEXT: .cfi_restore w30
606 ; CHECK-NEXT: .LBB8_6: // %if.end
607 ; CHECK-NEXT: .cfi_restore_state
608 ; CHECK-NEXT: mov w0, wzr
609 ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
610 ; CHECK-NEXT: .cfi_def_cfa_offset 0
611 ; CHECK-NEXT: .cfi_restore w19
612 ; CHECK-NEXT: .cfi_restore w30
615 %0 = load i32, ptr @a, align 4
616 %cmp4 = icmp slt i32 %0, 1
617 br i1 %cmp4, label %while.body.preheader, label %while.end
619 while.body.preheader: ; preds = %entry
622 while.body: ; preds = %while.body, %while.body.preheader
623 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
624 tail call void @do_something() #2
625 %inc = add nsw i32 %i.05, 1
626 %cmp = icmp slt i32 %i.05, 0
627 br i1 %cmp, label %while.body, label %while.end.loopexit
629 while.end.loopexit: ; preds = %while.body
632 while.end: ; preds = %while.end.loopexit, %entry
633 %1 = load i32, ptr @c, align 4
634 %cmp1 = icmp sgt i32 %1, -3
635 br i1 %cmp1, label %land.lhs.true, label %if.end
637 land.lhs.true: ; preds = %while.end
638 %2 = load i32, ptr @b, align 4
639 %3 = load i32, ptr @d, align 4
640 %cmp2 = icmp eq i32 %2, %3
641 br i1 %cmp2, label %return, label %if.end
643 if.end: ; preds = %land.lhs.true, %while.end
646 return: ; preds = %if.end, %land.lhs.true
647 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
651 ; Test in the following case, we don't hit 'cmp' and trigger a false positive
658 define i32 @fcmpri(i32 %argc, ptr nocapture readonly %argv) #0 {
659 ; CHECK-LABEL: fcmpri:
660 ; CHECK: // %bb.0: // %entry
661 ; CHECK-NEXT: cmp w0, #2
662 ; CHECK-NEXT: b.lt .LBB9_3
663 ; CHECK-NEXT: // %bb.1: // %land.lhs.true
664 ; CHECK-NEXT: ldr x8, [x1, #8]
665 ; CHECK-NEXT: cbz x8, .LBB9_3
666 ; CHECK-NEXT: // %bb.2:
667 ; CHECK-NEXT: mov w0, #3 // =0x3
669 ; CHECK-NEXT: .LBB9_3: // %if.end
670 ; CHECK-NEXT: str d8, [sp, #-32]! // 8-byte Folded Spill
671 ; CHECK-NEXT: .cfi_def_cfa_offset 32
672 ; CHECK-NEXT: stp x30, x19, [sp, #16] // 16-byte Folded Spill
673 ; CHECK-NEXT: .cfi_offset w19, -8
674 ; CHECK-NEXT: .cfi_offset w30, -16
675 ; CHECK-NEXT: .cfi_offset b8, -32
676 ; CHECK-NEXT: mov w0, #1 // =0x1
678 ; CHECK-NEXT: mov w19, w0
679 ; CHECK-NEXT: mov w0, #-1 // =0xffffffff
681 ; CHECK-NEXT: cmp w19, #0
682 ; CHECK-NEXT: mov w1, #2 // =0x2
683 ; CHECK-NEXT: fmov d8, d0
684 ; CHECK-NEXT: cinc w0, w19, gt
686 ; CHECK-NEXT: fmov d0, #-1.00000000
687 ; CHECK-NEXT: fcmp d8, #0.0
688 ; CHECK-NEXT: fmov d1, #-2.00000000
689 ; CHECK-NEXT: fadd d0, d8, d0
690 ; CHECK-NEXT: fcsel d0, d8, d0, gt
692 ; CHECK-NEXT: ldp x30, x19, [sp, #16] // 16-byte Folded Reload
693 ; CHECK-NEXT: mov w0, #4 // =0x4
694 ; CHECK-NEXT: ldr d8, [sp], #32 // 8-byte Folded Reload
695 ; CHECK-NEXT: .cfi_def_cfa_offset 0
696 ; CHECK-NEXT: .cfi_restore w19
697 ; CHECK-NEXT: .cfi_restore w30
698 ; CHECK-NEXT: .cfi_restore b8
701 ; CHECK-LABEL-DAG: .LBB9_3
704 %cmp = icmp sgt i32 %argc, 1
705 br i1 %cmp, label %land.lhs.true, label %if.end
707 land.lhs.true: ; preds = %entry
708 %arrayidx = getelementptr inbounds ptr, ptr %argv, i64 1
709 %0 = load ptr, ptr %arrayidx, align 8
710 %cmp1 = icmp eq ptr %0, null
711 br i1 %cmp1, label %if.end, label %return
713 if.end: ; preds = %land.lhs.true, %entry
714 %call = call i32 @zoo(i32 1)
715 %call2 = call double @yoo(i32 -1)
716 %cmp4 = icmp sgt i32 %call, 0
717 %add = zext i1 %cmp4 to i32
718 %cond = add nsw i32 %add, %call
719 %call7 = call i32 @xoo(i32 %cond, i32 2)
720 %cmp9 = fcmp ogt double %call2, 0.000000e+00
721 br i1 %cmp9, label %cond.end14, label %cond.false12
723 cond.false12: ; preds = %if.end
724 %sub = fadd fast double %call2, -1.000000e+00
727 cond.end14: ; preds = %if.end, %cond.false12
728 %cond15 = phi double [ %sub, %cond.false12 ], [ %call2, %if.end ]
729 %call16 = call i32 @woo(double %cond15, double -2.000000e+00)
732 return: ; preds = %land.lhs.true, %cond.end14
733 %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ]
737 define void @cmp_shifted(i32 %in, i32 %lhs, i32 %rhs) #0 {
738 ; CHECK-LABEL: cmp_shifted:
739 ; CHECK: // %bb.0: // %common.ret
740 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
741 ; CHECK-NEXT: .cfi_def_cfa_offset 16
742 ; CHECK-NEXT: .cfi_offset w30, -16
743 ; CHECK-NEXT: mov w8, #42 // =0x2a
744 ; CHECK-NEXT: cmp w0, #0
745 ; CHECK-NEXT: mov w9, #128 // =0x80
746 ; CHECK-NEXT: csinc w8, w8, wzr, gt
747 ; CHECK-NEXT: cmp w0, #2, lsl #12 // =8192
748 ; CHECK-NEXT: csel w0, w9, w8, ge
750 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
751 ; CHECK-NEXT: .cfi_def_cfa_offset 0
752 ; CHECK-NEXT: .cfi_restore w30
756 %tst_low = icmp sgt i32 %in, 8191
757 br i1 %tst_low, label %true, label %false
760 call i32 @zoo(i32 128)
764 %tst = icmp sgt i32 %in, 0
765 br i1 %tst, label %truer, label %falser
768 call i32 @zoo(i32 42)
776 define i32 @combine_gt_ge_sel(i64 %v, ptr %p) #0 {
777 ; CHECK-LABEL: combine_gt_ge_sel:
778 ; CHECK: // %bb.0: // %entry
779 ; CHECK-NEXT: adrp x8, :got:a
780 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:a]
781 ; CHECK-NEXT: ldr w8, [x8]
782 ; CHECK-NEXT: cmp w8, #0
783 ; CHECK-NEXT: csel x9, x0, xzr, gt
784 ; CHECK-NEXT: str x9, [x1]
785 ; CHECK-NEXT: b.le .LBB11_2
786 ; CHECK-NEXT: // %bb.1: // %lor.lhs.false
787 ; CHECK-NEXT: cmp w8, #2
788 ; CHECK-NEXT: b.ge .LBB11_4
789 ; CHECK-NEXT: b .LBB11_6
790 ; CHECK-NEXT: .LBB11_2: // %land.lhs.true
791 ; CHECK-NEXT: adrp x8, :got:b
792 ; CHECK-NEXT: adrp x9, :got:c
793 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
794 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:c]
795 ; CHECK-NEXT: ldr w8, [x8]
796 ; CHECK-NEXT: ldr w9, [x9]
797 ; CHECK-NEXT: cmp w8, w9
798 ; CHECK-NEXT: b.ne .LBB11_4
799 ; CHECK-NEXT: // %bb.3:
800 ; CHECK-NEXT: mov w0, #1 // =0x1
802 ; CHECK-NEXT: .LBB11_4: // %land.lhs.true3
803 ; CHECK-NEXT: adrp x8, :got:b
804 ; CHECK-NEXT: adrp x9, :got:d
805 ; CHECK-NEXT: ldr x8, [x8, :got_lo12:b]
806 ; CHECK-NEXT: ldr x9, [x9, :got_lo12:d]
807 ; CHECK-NEXT: ldr w8, [x8]
808 ; CHECK-NEXT: ldr w9, [x9]
809 ; CHECK-NEXT: cmp w8, w9
810 ; CHECK-NEXT: b.ne .LBB11_6
811 ; CHECK-NEXT: // %bb.5:
812 ; CHECK-NEXT: mov w0, #1 // =0x1
814 ; CHECK-NEXT: .LBB11_6: // %if.end
815 ; CHECK-NEXT: mov w0, wzr
818 %0 = load i32, ptr @a, align 4
819 %cmp = icmp sgt i32 %0, 0
820 %m = select i1 %cmp, i64 %v, i64 0
822 br i1 %cmp, label %lor.lhs.false, label %land.lhs.true
824 land.lhs.true: ; preds = %entry
825 %1 = load i32, ptr @b, align 4
826 %2 = load i32, ptr @c, align 4
827 %cmp1 = icmp eq i32 %1, %2
828 br i1 %cmp1, label %return, label %land.lhs.true3
830 lor.lhs.false: ; preds = %entry
831 %cmp2 = icmp sgt i32 %0, 1
832 br i1 %cmp2, label %land.lhs.true3, label %if.end
834 land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
835 %3 = load i32, ptr @b, align 4
836 %4 = load i32, ptr @d, align 4
837 %cmp4 = icmp eq i32 %3, %4
838 br i1 %cmp4, label %return, label %if.end
840 if.end: ; preds = %land.lhs.true3, %lor.lhs.false
843 return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
844 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
848 declare i32 @zoo(i32)
850 declare double @yoo(i32)
852 declare i32 @xoo(i32, i32)
854 declare i32 @woo(double, double)
856 attributes #0 = { uwtable }