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
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
43 ; CHECK-NEXT: .LBB0_6: // %if.end
44 ; CHECK-NEXT: mov w0, wzr
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
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
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
110 ; CHECK-NEXT: .LBB1_6: // %if.end
111 ; CHECK-NEXT: mov w0, wzr
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
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 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
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
175 ; CHECK-NEXT: .LBB2_6: // %if.end
176 ; CHECK-NEXT: mov w0, wzr
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
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
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
242 ; CHECK-NEXT: .LBB3_6: // %if.end
243 ; CHECK-NEXT: mov w0, wzr
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
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
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
309 ; CHECK-NEXT: .LBB4_6: // %if.end
310 ; CHECK-NEXT: mov w0, wzr
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
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
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
376 ; CHECK-NEXT: .LBB5_6: // %if.end
377 ; CHECK-NEXT: mov w0, wzr
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
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 %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
449 %size = getelementptr inbounds %struct.Struct, %struct.Struct* %hdCall, i64 0, i32 0
450 %0 = load i64, i64* %size, align 8
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
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
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
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
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
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
550 return: ; preds = %if.end, %land.lhs.true
551 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
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
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
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
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
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
629 return: ; preds = %if.end, %land.lhs.true
630 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
634 ; Test in the following case, we don't hit 'cmp' and trigger a false positive
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
661 ; CHECK-NEXT: mov w19, w0
662 ; CHECK-NEXT: mov w0, #-1
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
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
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
681 ; CHECK-LABEL-DAG: .LBB9_3
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
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)
712 return: ; preds = %land.lhs.true, %cond.end14
713 %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ]
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
730 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
734 %tst_low = icmp sgt i32 %in, 8191
735 br i1 %tst_low, label %true, label %false
738 call i32 @zoo(i32 128)
742 %tst = icmp sgt i32 %in, 0
743 br i1 %tst, label %truer, label %falser
746 call i32 @zoo(i32 42)
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
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
792 ; CHECK-NEXT: .LBB11_6: // %if.end
793 ; CHECK-NEXT: mov w0, wzr
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
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 ]
826 declare i32 @zoo(i32)
828 declare double @yoo(i32)
830 declare i32 @xoo(i32, i32)
832 declare i32 @woo(double, double)