[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / combine-comparisons-by-cse.ll
blob6449c3e11d6672aa8d767a590f2445327added87
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
30 ; CHECK-NEXT:    ret
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
42 ; CHECK-NEXT:    ret
43 ; CHECK-NEXT:  .LBB0_6: // %if.end
44 ; CHECK-NEXT:    mov w0, wzr
45 ; CHECK-NEXT:    ret
46 entry:
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
68   br label %return
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 ]
72   ret i32 %retval.0
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
95 ; CHECK-NEXT:    ret
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
109 ; CHECK-NEXT:    ret
110 ; CHECK-NEXT:  .LBB1_6: // %if.end
111 ; CHECK-NEXT:    mov w0, wzr
112 ; CHECK-NEXT:    ret
113 entry:
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
135   br label %return
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 ]
139   ret i32 %retval.0
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
162 ; CHECK-NEXT:    ret
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
174 ; CHECK-NEXT:    ret
175 ; CHECK-NEXT:  .LBB2_6: // %if.end
176 ; CHECK-NEXT:    mov w0, wzr
177 ; CHECK-NEXT:    ret
178 entry:
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
200   br label %return
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 ]
204   ret i32 %retval.0
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
227 ; CHECK-NEXT:    ret
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
241 ; CHECK-NEXT:    ret
242 ; CHECK-NEXT:  .LBB3_6: // %if.end
243 ; CHECK-NEXT:    mov w0, wzr
244 ; CHECK-NEXT:    ret
245 entry:
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
267   br label %return
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 ]
271   ret i32 %retval.0
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
294 ; CHECK-NEXT:    ret
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
308 ; CHECK-NEXT:    ret
309 ; CHECK-NEXT:  .LBB4_6: // %if.end
310 ; CHECK-NEXT:    mov w0, wzr
311 ; CHECK-NEXT:    ret
312 entry:
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
334   br label %return
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 ]
338   ret i32 %retval.0
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
361 ; CHECK-NEXT:    ret
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
375 ; CHECK-NEXT:    ret
376 ; CHECK-NEXT:  .LBB5_6: // %if.end
377 ; CHECK-NEXT:    mov w0, wzr
378 ; CHECK-NEXT:    ret
379 entry:
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
401   br label %return
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 ]
405   ret i32 %retval.0
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
453 ; CHECK-NEXT:    ret
454 entry:
455   %0 = load i64, ptr %hdCall, align 8
456   br label %land.rhs
458 land.rhs:
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
464 while.body:
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
471 while.end:
472   ret void
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
525 ; CHECK-NEXT:    ret
526 entry:
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
532   br label %while.body
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
543   br label %while.end
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
557   br label %return
559 return:                                           ; preds = %if.end, %land.lhs.true
560   %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
561   ret i32 %retval.0
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
605 ; CHECK-NEXT:    ret
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
613 ; CHECK-NEXT:    ret
614 entry:
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
620   br label %while.body
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
630   br label %while.end
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
644   br label %return
646 return:                                           ; preds = %if.end, %land.lhs.true
647   %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
648   ret i32 %retval.0
651 ; Test in the following case, we don't hit 'cmp' and trigger a false positive
652 ; cmp  w19, #0
653 ; cinc w0, w19, gt
654 ; ...
655 ; fcmp d8, #0.0
656 ; b.gt .LBB0_5
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
668 ; CHECK-NEXT:    ret
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
677 ; CHECK-NEXT:    bl zoo
678 ; CHECK-NEXT:    mov w19, w0
679 ; CHECK-NEXT:    mov w0, #-1 // =0xffffffff
680 ; CHECK-NEXT:    bl yoo
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
685 ; CHECK-NEXT:    bl xoo
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
691 ; CHECK-NEXT:    bl woo
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
699 ; CHECK-NEXT:    ret
701 ; CHECK-LABEL-DAG: .LBB9_3
703 entry:
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
725   br label %cond.end14
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)
730   br label %return
732 return:                                           ; preds = %land.lhs.true, %cond.end14
733   %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ]
734   ret i32 %retval.0
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
749 ; CHECK-NEXT:    bl zoo
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
753 ; CHECK-NEXT:    ret
754 ; [...]
756   %tst_low = icmp sgt i32 %in, 8191
757   br i1 %tst_low, label %true, label %false
759 true:
760   call i32 @zoo(i32 128)
761   ret void
763 false:
764   %tst = icmp sgt i32 %in, 0
765   br i1 %tst, label %truer, label %falser
767 truer:
768   call i32 @zoo(i32 42)
769   ret void
771 falser:
772   call i32 @zoo(i32 1)
773   ret void
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
801 ; CHECK-NEXT:    ret
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
813 ; CHECK-NEXT:    ret
814 ; CHECK-NEXT:  .LBB11_6: // %if.end
815 ; CHECK-NEXT:    mov w0, wzr
816 ; CHECK-NEXT:    ret
817 entry:
818   %0 = load i32, ptr @a, align 4
819   %cmp = icmp sgt i32 %0, 0
820   %m = select i1 %cmp, i64 %v, i64 0
821   store i64 %m, ptr %p
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
841   br label %return
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 ]
845   ret i32 %retval.0
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 }