[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / combine-comparisons-by-cse.ll
blob92f01ec5fdeacf78fbcddd6beefca7f4b4de82ad
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 x10, :got:c
23 ; CHECK-NEXT:    ldr w9, [x8]
24 ; CHECK-NEXT:    ldr x10, [x10, :got_lo12:c]
25 ; CHECK-NEXT:    ldr w10, [x10]
26 ; CHECK-NEXT:    cmp w9, w10
27 ; CHECK-NEXT:    b.ne .LBB0_4
28 ; CHECK-NEXT:  // %bb.2:
29 ; CHECK-NEXT:    mov w0, #1
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 w8, [x8]
36 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
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
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, i32* @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, i32* @b, align 4
53   %2 = load i32, i32* @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, i32* @b, align 4
63   %4 = load i32, i32* @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
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
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, i32* @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, i32* @b, align 4
120   %2 = load i32, i32* @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, i32* @b, align 4
130   %4 = load i32, i32* @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 x10, :got:c
155 ; CHECK-NEXT:    ldr w9, [x8]
156 ; CHECK-NEXT:    ldr x10, [x10, :got_lo12:c]
157 ; CHECK-NEXT:    ldr w10, [x10]
158 ; CHECK-NEXT:    cmp w9, w10
159 ; CHECK-NEXT:    b.ne .LBB2_4
160 ; CHECK-NEXT:  // %bb.2:
161 ; CHECK-NEXT:    mov w0, #1
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 w8, [x8]
168 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
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
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, i32* @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, i32* @b, align 4
185   %2 = load i32, i32* @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, i32* @b, align 4
195   %4 = load i32, i32* @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
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
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, i32* @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, i32* @b, align 4
252   %2 = load i32, i32* @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, i32* @b, align 4
262   %4 = load i32, i32* @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
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
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, i32* @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, i32* @b, align 4
319   %2 = load i32, i32* @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, i32* @b, align 4
329   %4 = load i32, i32* @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
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
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, i32* @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, i32* @b, align 4
386   %2 = load i32, i32* @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, i32* @b, align 4
396   %4 = load i32, i32* @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 %struct.Struct* null, align 8
412 declare %struct.Struct* @Update(%struct.Struct*) #1
414 ; no checks for this case, it just should be processed without errors
415 define void @combine_non_adjacent_cmp_br(%struct.Struct* 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:    stp x22, x21, [sp, #16] // 16-byte Folded Spill
420 ; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
421 ; CHECK-NEXT:    .cfi_def_cfa_offset 48
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 x19, [x0]
428 ; CHECK-NEXT:    mov w20, #24
429 ; CHECK-NEXT:    adrp x22, glob
430 ; CHECK-NEXT:    add x21, x19, #2
431 ; CHECK-NEXT:  .LBB6_1: // %land.rhs
432 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
433 ; CHECK-NEXT:    ldr x8, [x20]
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 x19, 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:    ret
448 entry:
449   %size = getelementptr inbounds %struct.Struct, %struct.Struct* %hdCall, i64 0, i32 0
450   %0 = load i64, i64* %size, align 8
451   br label %land.rhs
453 land.rhs:
454   %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ]
455   %1 = load i64, i64* inttoptr (i64 24 to i64*), align 8
456   %cmp2 = icmp sgt i64 %1, 0
457   br i1 %cmp2, label %while.body, label %while.end
459 while.body:
460   %2 = load %struct.Struct*, %struct.Struct** @glob, align 8
461   %call = tail call %struct.Struct* @Update(%struct.Struct* %2) #2
462   %sub = add nsw i64 %rp.06, -2
463   %cmp = icmp slt i64 %0, %rp.06
464   br i1 %cmp, label %land.rhs, label %while.end
466 while.end:
467   ret void
470 ; undefined external to prevent possible optimizations
471 declare void @do_something() #1
473 define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
474 ; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ:
475 ; CHECK:       // %bb.0: // %entry
476 ; CHECK-NEXT:    str x30, [sp, #-32]! // 8-byte Folded Spill
477 ; CHECK-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
478 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
479 ; CHECK-NEXT:    .cfi_offset w19, -8
480 ; CHECK-NEXT:    .cfi_offset w20, -16
481 ; CHECK-NEXT:    .cfi_offset w30, -32
482 ; CHECK-NEXT:    adrp x19, :got:a
483 ; CHECK-NEXT:    ldr x19, [x19, :got_lo12:a]
484 ; CHECK-NEXT:    ldr w8, [x19]
485 ; CHECK-NEXT:    cmn w8, #2
486 ; CHECK-NEXT:    b.gt .LBB7_4
487 ; CHECK-NEXT:  // %bb.1: // %while.body.preheader
488 ; CHECK-NEXT:    sub w20, w8, #1
489 ; CHECK-NEXT:  .LBB7_2: // %while.body
490 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
491 ; CHECK-NEXT:    bl do_something
492 ; CHECK-NEXT:    adds w20, w20, #1
493 ; CHECK-NEXT:    b.mi .LBB7_2
494 ; CHECK-NEXT:  // %bb.3: // %while.cond.while.end_crit_edge
495 ; CHECK-NEXT:    ldr w8, [x19]
496 ; CHECK-NEXT:  .LBB7_4: // %while.end
497 ; CHECK-NEXT:    cmp w8, #1
498 ; CHECK-NEXT:    b.gt .LBB7_7
499 ; CHECK-NEXT:  // %bb.5: // %land.lhs.true
500 ; CHECK-NEXT:    adrp x8, :got:b
501 ; CHECK-NEXT:    adrp x9, :got:d
502 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
503 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
504 ; CHECK-NEXT:    ldr w8, [x8]
505 ; CHECK-NEXT:    ldr w9, [x9]
506 ; CHECK-NEXT:    cmp w8, w9
507 ; CHECK-NEXT:    b.ne .LBB7_7
508 ; CHECK-NEXT:  // %bb.6:
509 ; CHECK-NEXT:    mov w0, #123
510 ; CHECK-NEXT:    b .LBB7_8
511 ; CHECK-NEXT:  .LBB7_7: // %if.end
512 ; CHECK-NEXT:    mov w0, wzr
513 ; CHECK-NEXT:  .LBB7_8: // %return
514 ; CHECK-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
515 ; CHECK-NEXT:    ldr x30, [sp], #32 // 8-byte Folded Reload
516 ; CHECK-NEXT:    ret
517 entry:
518   %0 = load i32, i32* @a, align 4
519   %cmp4 = icmp slt i32 %0, -1
520   br i1 %cmp4, label %while.body.preheader, label %while.end
522 while.body.preheader:                             ; preds = %entry
523   br label %while.body
525 while.body:                                       ; preds = %while.body, %while.body.preheader
526   %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
527   tail call void @do_something() #2
528   %inc = add nsw i32 %i.05, 1
529   %cmp = icmp slt i32 %i.05, 0
530   br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge
532 while.cond.while.end_crit_edge:                   ; preds = %while.body
533   %.pre = load i32, i32* @a, align 4
534   br label %while.end
536 while.end:                                        ; preds = %while.cond.while.end_crit_edge, %entry
537   %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ]
538   %cmp1 = icmp slt i32 %1, 2
539   br i1 %cmp1, label %land.lhs.true, label %if.end
541 land.lhs.true:                                    ; preds = %while.end
542   %2 = load i32, i32* @b, align 4
543   %3 = load i32, i32* @d, align 4
544   %cmp2 = icmp eq i32 %2, %3
545   br i1 %cmp2, label %return, label %if.end
547 if.end:                                           ; preds = %land.lhs.true, %while.end
548   br label %return
550 return:                                           ; preds = %if.end, %land.lhs.true
551   %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
552   ret i32 %retval.0
555 define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
556 ; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other:
557 ; CHECK:       // %bb.0: // %entry
558 ; CHECK-NEXT:    stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
559 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
560 ; CHECK-NEXT:    .cfi_offset w19, -8
561 ; CHECK-NEXT:    .cfi_offset w30, -16
562 ; CHECK-NEXT:    adrp x8, :got:a
563 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
564 ; CHECK-NEXT:    ldr w8, [x8]
565 ; CHECK-NEXT:    cmp w8, #0
566 ; CHECK-NEXT:    b.gt .LBB8_3
567 ; CHECK-NEXT:  // %bb.1: // %while.body.preheader
568 ; CHECK-NEXT:    sub w19, w8, #1
569 ; CHECK-NEXT:  .LBB8_2: // %while.body
570 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
571 ; CHECK-NEXT:    bl do_something
572 ; CHECK-NEXT:    adds w19, w19, #1
573 ; CHECK-NEXT:    b.mi .LBB8_2
574 ; CHECK-NEXT:  .LBB8_3: // %while.end
575 ; CHECK-NEXT:    adrp x8, :got:c
576 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:c]
577 ; CHECK-NEXT:    ldr w8, [x8]
578 ; CHECK-NEXT:    cmn w8, #2
579 ; CHECK-NEXT:    b.lt .LBB8_6
580 ; CHECK-NEXT:  // %bb.4: // %land.lhs.true
581 ; CHECK-NEXT:    adrp x8, :got:b
582 ; CHECK-NEXT:    adrp x9, :got:d
583 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
584 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
585 ; CHECK-NEXT:    ldr w8, [x8]
586 ; CHECK-NEXT:    ldr w9, [x9]
587 ; CHECK-NEXT:    cmp w8, w9
588 ; CHECK-NEXT:    b.ne .LBB8_6
589 ; CHECK-NEXT:  // %bb.5:
590 ; CHECK-NEXT:    mov w0, #123
591 ; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
592 ; CHECK-NEXT:    ret
593 ; CHECK-NEXT:  .LBB8_6: // %if.end
594 ; CHECK-NEXT:    mov w0, wzr
595 ; CHECK-NEXT:    ldp x30, x19, [sp], #16 // 16-byte Folded Reload
596 ; CHECK-NEXT:    ret
597 entry:
598   %0 = load i32, i32* @a, align 4
599   %cmp4 = icmp slt i32 %0, 1
600   br i1 %cmp4, label %while.body.preheader, label %while.end
602 while.body.preheader:                             ; preds = %entry
603   br label %while.body
605 while.body:                                       ; preds = %while.body, %while.body.preheader
606   %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
607   tail call void @do_something() #2
608   %inc = add nsw i32 %i.05, 1
609   %cmp = icmp slt i32 %i.05, 0
610   br i1 %cmp, label %while.body, label %while.end.loopexit
612 while.end.loopexit:                               ; preds = %while.body
613   br label %while.end
615 while.end:                                        ; preds = %while.end.loopexit, %entry
616   %1 = load i32, i32* @c, align 4
617   %cmp1 = icmp sgt i32 %1, -3
618   br i1 %cmp1, label %land.lhs.true, label %if.end
620 land.lhs.true:                                    ; preds = %while.end
621   %2 = load i32, i32* @b, align 4
622   %3 = load i32, i32* @d, align 4
623   %cmp2 = icmp eq i32 %2, %3
624   br i1 %cmp2, label %return, label %if.end
626 if.end:                                           ; preds = %land.lhs.true, %while.end
627   br label %return
629 return:                                           ; preds = %if.end, %land.lhs.true
630   %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
631   ret i32 %retval.0
634 ; Test in the following case, we don't hit 'cmp' and trigger a false positive
635 ; cmp  w19, #0
636 ; cinc w0, w19, gt
637 ; ...
638 ; fcmp d8, #0.0
639 ; b.gt .LBB0_5
641 define i32 @fcmpri(i32 %argc, i8** nocapture readonly %argv) {
642 ; CHECK-LABEL: fcmpri:
643 ; CHECK:       // %bb.0: // %entry
644 ; CHECK-NEXT:    str d8, [sp, #-32]! // 8-byte Folded Spill
645 ; CHECK-NEXT:    stp x30, x19, [sp, #16] // 16-byte Folded Spill
646 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
647 ; CHECK-NEXT:    .cfi_offset w19, -8
648 ; CHECK-NEXT:    .cfi_offset w30, -16
649 ; CHECK-NEXT:    .cfi_offset b8, -32
650 ; CHECK-NEXT:    cmp w0, #2
651 ; CHECK-NEXT:    b.lt .LBB9_3
652 ; CHECK-NEXT:  // %bb.1: // %land.lhs.true
653 ; CHECK-NEXT:    ldr x8, [x1, #8]
654 ; CHECK-NEXT:    cbz x8, .LBB9_3
655 ; CHECK-NEXT:  // %bb.2:
656 ; CHECK-NEXT:    mov w0, #3
657 ; CHECK-NEXT:    b .LBB9_4
658 ; CHECK-NEXT:  .LBB9_3: // %if.end
659 ; CHECK-NEXT:    mov w0, #1
660 ; CHECK-NEXT:    bl zoo
661 ; CHECK-NEXT:    mov w19, w0
662 ; CHECK-NEXT:    mov w0, #-1
663 ; CHECK-NEXT:    bl yoo
664 ; CHECK-NEXT:    cmp w19, #0
665 ; CHECK-NEXT:    cinc w0, w19, gt
666 ; CHECK-NEXT:    mov w1, #2
667 ; CHECK-NEXT:    fmov d8, d0
668 ; CHECK-NEXT:    bl xoo
669 ; CHECK-NEXT:    fmov d0, #-1.00000000
670 ; CHECK-NEXT:    fadd d0, d8, d0
671 ; CHECK-NEXT:    fcmp d8, #0.0
672 ; CHECK-NEXT:    fcsel d0, d8, d0, gt
673 ; CHECK-NEXT:    fmov d1, #-2.00000000
674 ; CHECK-NEXT:    bl woo
675 ; CHECK-NEXT:    mov w0, #4
676 ; CHECK-NEXT:  .LBB9_4: // %return
677 ; CHECK-NEXT:    ldp x30, x19, [sp, #16] // 16-byte Folded Reload
678 ; CHECK-NEXT:    ldr d8, [sp], #32 // 8-byte Folded Reload
679 ; CHECK-NEXT:    ret
681 ; CHECK-LABEL-DAG: .LBB9_3
683 entry:
684   %cmp = icmp sgt i32 %argc, 1
685   br i1 %cmp, label %land.lhs.true, label %if.end
687 land.lhs.true:                                    ; preds = %entry
688   %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1
689   %0 = load i8*, i8** %arrayidx, align 8
690   %cmp1 = icmp eq i8* %0, null
691   br i1 %cmp1, label %if.end, label %return
693 if.end:                                           ; preds = %land.lhs.true, %entry
694   %call = call i32 @zoo(i32 1)
695   %call2 = call double @yoo(i32 -1)
696   %cmp4 = icmp sgt i32 %call, 0
697   %add = zext i1 %cmp4 to i32
698   %cond = add nsw i32 %add, %call
699   %call7 = call i32 @xoo(i32 %cond, i32 2)
700   %cmp9 = fcmp ogt double %call2, 0.000000e+00
701   br i1 %cmp9, label %cond.end14, label %cond.false12
703 cond.false12:                                     ; preds = %if.end
704   %sub = fadd fast double %call2, -1.000000e+00
705   br label %cond.end14
707 cond.end14:                                       ; preds = %if.end, %cond.false12
708   %cond15 = phi double [ %sub, %cond.false12 ], [ %call2, %if.end ]
709   %call16 = call i32 @woo(double %cond15, double -2.000000e+00)
710   br label %return
712 return:                                           ; preds = %land.lhs.true, %cond.end14
713   %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ]
714   ret i32 %retval.0
717 define void @cmp_shifted(i32 %in, i32 %lhs, i32 %rhs) {
718 ; CHECK-LABEL: cmp_shifted:
719 ; CHECK:       // %bb.0: // %common.ret
720 ; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
721 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
722 ; CHECK-NEXT:    .cfi_offset w30, -16
723 ; CHECK-NEXT:    cmp w0, #0
724 ; CHECK-NEXT:    mov w8, #42
725 ; CHECK-NEXT:    csinc w8, w8, wzr, gt
726 ; CHECK-NEXT:    cmp w0, #2, lsl #12 // =8192
727 ; CHECK-NEXT:    mov w9, #128
728 ; CHECK-NEXT:    csel w0, w9, w8, ge
729 ; CHECK-NEXT:    bl zoo
730 ; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
731 ; CHECK-NEXT:    ret
732 ; [...]
734   %tst_low = icmp sgt i32 %in, 8191
735   br i1 %tst_low, label %true, label %false
737 true:
738   call i32 @zoo(i32 128)
739   ret void
741 false:
742   %tst = icmp sgt i32 %in, 0
743   br i1 %tst, label %truer, label %falser
745 truer:
746   call i32 @zoo(i32 42)
747   ret void
749 falser:
750   call i32 @zoo(i32 1)
751   ret void
754 define i32 @combine_gt_ge_sel(i64 %v, i64* %p) #0 {
755 ; CHECK-LABEL: combine_gt_ge_sel:
756 ; CHECK:       // %bb.0: // %entry
757 ; CHECK-NEXT:    adrp x8, :got:a
758 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:a]
759 ; CHECK-NEXT:    ldr w8, [x8]
760 ; CHECK-NEXT:    cmp w8, #0
761 ; CHECK-NEXT:    csel x9, x0, xzr, gt
762 ; CHECK-NEXT:    str x9, [x1]
763 ; CHECK-NEXT:    b.le .LBB11_2
764 ; CHECK-NEXT:  // %bb.1: // %lor.lhs.false
765 ; CHECK-NEXT:    cmp w8, #2
766 ; CHECK-NEXT:    b.ge .LBB11_4
767 ; CHECK-NEXT:    b .LBB11_6
768 ; CHECK-NEXT:  .LBB11_2: // %land.lhs.true
769 ; CHECK-NEXT:    adrp x8, :got:b
770 ; CHECK-NEXT:    adrp x9, :got:c
771 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
772 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:c]
773 ; CHECK-NEXT:    ldr w8, [x8]
774 ; CHECK-NEXT:    ldr w9, [x9]
775 ; CHECK-NEXT:    cmp w8, w9
776 ; CHECK-NEXT:    b.ne .LBB11_4
777 ; CHECK-NEXT:  // %bb.3:
778 ; CHECK-NEXT:    mov w0, #1
779 ; CHECK-NEXT:    ret
780 ; CHECK-NEXT:  .LBB11_4: // %land.lhs.true3
781 ; CHECK-NEXT:    adrp x8, :got:b
782 ; CHECK-NEXT:    adrp x9, :got:d
783 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:b]
784 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:d]
785 ; CHECK-NEXT:    ldr w8, [x8]
786 ; CHECK-NEXT:    ldr w9, [x9]
787 ; CHECK-NEXT:    cmp w8, w9
788 ; CHECK-NEXT:    b.ne .LBB11_6
789 ; CHECK-NEXT:  // %bb.5:
790 ; CHECK-NEXT:    mov w0, #1
791 ; CHECK-NEXT:    ret
792 ; CHECK-NEXT:  .LBB11_6: // %if.end
793 ; CHECK-NEXT:    mov w0, wzr
794 ; CHECK-NEXT:    ret
795 entry:
796   %0 = load i32, i32* @a, align 4
797   %cmp = icmp sgt i32 %0, 0
798   %m = select i1 %cmp, i64 %v, i64 0
799   store i64 %m, i64* %p
800   br i1 %cmp, label %lor.lhs.false, label %land.lhs.true
802 land.lhs.true:                                    ; preds = %entry
803   %1 = load i32, i32* @b, align 4
804   %2 = load i32, i32* @c, align 4
805   %cmp1 = icmp eq i32 %1, %2
806   br i1 %cmp1, label %return, label %land.lhs.true3
808 lor.lhs.false:                                    ; preds = %entry
809   %cmp2 = icmp sgt i32 %0, 1
810   br i1 %cmp2, label %land.lhs.true3, label %if.end
812 land.lhs.true3:                                   ; preds = %lor.lhs.false, %land.lhs.true
813   %3 = load i32, i32* @b, align 4
814   %4 = load i32, i32* @d, align 4
815   %cmp4 = icmp eq i32 %3, %4
816   br i1 %cmp4, label %return, label %if.end
818 if.end:                                           ; preds = %land.lhs.true3, %lor.lhs.false
819   br label %return
821 return:                                           ; preds = %if.end, %land.lhs.true3, %land.lhs.true
822   %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
823   ret i32 %retval.0
826 declare i32 @zoo(i32)
828 declare double @yoo(i32)
830 declare i32 @xoo(i32, i32)
832 declare i32 @woo(double, double)