1 ; RUN: llc < %s -mcpu=cyclone -verify-machineinstrs -aarch64-enable-ccmp -aarch64-stress-ccmp | FileCheck %s
2 target triple = "arm64-apple-ios"
6 ; CHECK-NEXT: ccmp w1, #17, #4, ne
11 define i32 @single_same(i32 %a, i32 %b) nounwind ssp {
13 %cmp = icmp eq i32 %a, 5
14 %cmp1 = icmp eq i32 %b, 17
15 %or.cond = or i1 %cmp, %cmp1
16 br i1 %or.cond, label %if.then, label %if.end
19 %call = tail call i32 @foo() nounwind
26 ; Different condition codes for the two compares.
27 ; CHECK: single_different
29 ; CHECK-NEXT: ccmp w1, #17, #0, ge
34 define i32 @single_different(i32 %a, i32 %b) nounwind ssp {
36 %cmp = icmp sle i32 %a, 5
37 %cmp1 = icmp ne i32 %b, 17
38 %or.cond = or i1 %cmp, %cmp1
39 br i1 %or.cond, label %if.then, label %if.end
42 %call = tail call i32 @foo() nounwind
49 ; Second block clobbers the flags, can't convert (easily).
50 ; CHECK: single_flagclobber
55 define i32 @single_flagclobber(i32 %a, i32 %b) nounwind ssp {
57 %cmp = icmp eq i32 %a, 5
58 br i1 %cmp, label %if.then, label %lor.lhs.false
60 lor.lhs.false: ; preds = %entry
61 %cmp1 = icmp slt i32 %b, 7
62 %mul = shl nsw i32 %b, 1
63 %add = add nsw i32 %b, 1
64 %cond = select i1 %cmp1, i32 %mul, i32 %add
65 %cmp2 = icmp slt i32 %cond, 17
66 br i1 %cmp2, label %if.then, label %if.end
68 if.then: ; preds = %lor.lhs.false, %entry
69 %call = tail call i32 @foo() nounwind
72 if.end: ; preds = %if.then, %lor.lhs.false
76 ; Second block clobbers the flags and ends with a tbz terminator.
77 ; CHECK: single_flagclobber_tbz
82 define i32 @single_flagclobber_tbz(i32 %a, i32 %b) nounwind ssp {
84 %cmp = icmp eq i32 %a, 5
85 br i1 %cmp, label %if.then, label %lor.lhs.false
87 lor.lhs.false: ; preds = %entry
88 %cmp1 = icmp slt i32 %b, 7
89 %mul = shl nsw i32 %b, 1
90 %add = add nsw i32 %b, 1
91 %cond = select i1 %cmp1, i32 %mul, i32 %add
92 %and = and i32 %cond, 8
93 %cmp2 = icmp ne i32 %and, 0
94 br i1 %cmp2, label %if.then, label %if.end
96 if.then: ; preds = %lor.lhs.false, %entry
97 %call = tail call i32 @foo() nounwind
100 if.end: ; preds = %if.then, %lor.lhs.false
104 ; Speculatively execute division by zero.
105 ; The sdiv/udiv instructions do not trap when the divisor is zero, so they are
107 ; CHECK-LABEL: speculate_division:
109 ; CHECK: sdiv [[DIVRES:w[0-9]+]], w1, w0
110 ; CHECK: ccmp [[DIVRES]], #16, #0, ge
111 ; CHECK: b.le [[BLOCK:LBB[0-9_]+]]
115 define i32 @speculate_division(i32 %a, i32 %b) nounwind ssp {
117 %cmp = icmp sgt i32 %a, 0
118 br i1 %cmp, label %land.lhs.true, label %if.end
121 %div = sdiv i32 %b, %a
122 %cmp1 = icmp slt i32 %div, 17
123 br i1 %cmp1, label %if.then, label %if.end
126 %call = tail call i32 @foo() nounwind
133 ; Floating point compare.
138 ; CHECK: fccmp {{.*}}, #8, ge
140 define i32 @single_fcmp(i32 %a, float %b) nounwind ssp {
142 %cmp = icmp sgt i32 %a, 0
143 br i1 %cmp, label %land.lhs.true, label %if.end
146 %conv = sitofp i32 %a to float
147 %div = fdiv float %b, %conv
148 %cmp1 = fcmp oge float %div, 1.700000e+01
149 br i1 %cmp1, label %if.then, label %if.end
152 %call = tail call i32 @foo() nounwind
159 ; Chain multiple compares.
160 ; CHECK: multi_different
165 define void @multi_different(i32 %a, i32 %b, i32 %c) nounwind ssp {
167 %cmp = icmp sgt i32 %a, %b
168 br i1 %cmp, label %land.lhs.true, label %if.end
171 %div = sdiv i32 %b, %a
172 %cmp1 = icmp eq i32 %div, 5
173 %cmp4 = icmp sgt i32 %div, %c
174 %or.cond = and i1 %cmp1, %cmp4
175 br i1 %or.cond, label %if.then, label %if.end
178 %call = tail call i32 @foo() nounwind
185 ; Convert a cbz in the head block.
189 define i32 @cbz_head(i32 %a, i32 %b) nounwind ssp {
191 %cmp = icmp eq i32 %a, 0
192 %cmp1 = icmp ne i32 %b, 17
193 %or.cond = or i1 %cmp, %cmp1
194 br i1 %or.cond, label %if.then, label %if.end
197 %call = tail call i32 @foo() nounwind
204 ; Check that the immediate operand is in range. The ccmp instruction encodes a
205 ; smaller range of immediates than subs/adds.
206 ; The ccmp immediates must be in the range 0-31.
207 ; CHECK: immediate_range
209 define i32 @immediate_range(i32 %a, i32 %b) nounwind ssp {
211 %cmp = icmp eq i32 %a, 5
212 %cmp1 = icmp eq i32 %b, 32
213 %or.cond = or i1 %cmp, %cmp1
214 br i1 %or.cond, label %if.then, label %if.end
217 %call = tail call i32 @foo() nounwind
224 ; Convert a cbz in the second block.
227 ; CHECK: ccmp w1, #0, #0, ne
229 define i32 @cbz_second(i32 %a, i32 %b) nounwind ssp {
231 %cmp = icmp eq i32 %a, 0
232 %cmp1 = icmp ne i32 %b, 0
233 %or.cond = or i1 %cmp, %cmp1
234 br i1 %or.cond, label %if.then, label %if.end
237 %call = tail call i32 @foo() nounwind
244 ; Convert a cbnz in the second block.
247 ; CHECK: ccmp w1, #0, #4, ne
249 define i32 @cbnz_second(i32 %a, i32 %b) nounwind ssp {
251 %cmp = icmp eq i32 %a, 0
252 %cmp1 = icmp eq i32 %b, 0
253 %or.cond = or i1 %cmp, %cmp1
254 br i1 %or.cond, label %if.then, label %if.end
257 %call = tail call i32 @foo() nounwind
265 %str1 = type { %str2 }
266 %str2 = type { [24 x i8], i8*, i32, %str1*, i32, [4 x i8], %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, i8*, i8, i8*, %str1*, i8* }
268 ; Test case distilled from 126.gcc.
269 ; The phi in sw.bb.i.i gets multiple operands for the %entry predecessor.
270 ; CHECK: build_modify_expr
271 define void @build_modify_expr() nounwind ssp {
273 switch i32 undef, label %sw.bb.i.i [
274 i32 69, label %if.end85
275 i32 70, label %if.end85
276 i32 71, label %if.end85
277 i32 72, label %if.end85
278 i32 73, label %if.end85
279 i32 105, label %if.end85
280 i32 106, label %if.end85
287 %ref.tr.i.i = phi %str1* [ %0, %sw.bb.i.i ], [ undef, %entry ]
288 %operands.i.i = getelementptr inbounds %str1, %str1* %ref.tr.i.i, i64 0, i32 0, i32 2
289 %arrayidx.i.i = bitcast i32* %operands.i.i to %str1**
290 %0 = load %str1*, %str1** %arrayidx.i.i, align 8
291 %code1.i.i.phi.trans.insert = getelementptr inbounds %str1, %str1* %0, i64 0, i32 0, i32 0, i64 16
295 ; CHECK-LABEL: select_and
296 define i64 @select_and(i32 %w0, i32 %w1, i64 %x2, i64 %x3) {
298 ; CHECK-NEXT: ccmp w0, w1, #0, ne
299 ; CHECK-NEXT: csel x0, x2, x3, lt
301 %1 = icmp slt i32 %w0, %w1
302 %2 = icmp ne i32 5, %w1
304 %sel = select i1 %3, i64 %x2, i64 %x3
308 ; CHECK-LABEL: select_or
309 define i64 @select_or(i32 %w0, i32 %w1, i64 %x2, i64 %x3) {
311 ; CHECK-NEXT: ccmp w0, w1, #8, eq
312 ; CHECK-NEXT: csel x0, x2, x3, lt
314 %1 = icmp slt i32 %w0, %w1
315 %2 = icmp ne i32 5, %w1
317 %sel = select i1 %3, i64 %x2, i64 %x3
321 ; CHECK-LABEL: gccbug
322 define i64 @gccbug(i64 %x0, i64 %x1) {
324 ; CHECK-NEXT: ccmp x0, #4, #4, ne
325 ; CHECK-NEXT: ccmp x1, #0, #0, eq
326 ; CHECK-NEXT: mov w[[REGNUM:[0-9]+]], #1
327 ; CHECK-NEXT: cinc x0, x[[REGNUM]], eq
329 %cmp0 = icmp eq i64 %x1, 0
330 %cmp1 = icmp eq i64 %x0, 2
331 %cmp2 = icmp eq i64 %x0, 4
333 %or = or i1 %cmp2, %cmp1
334 %and = and i1 %or, %cmp0
336 %sel = select i1 %and, i64 2, i64 1
340 ; CHECK-LABEL: select_ororand
341 define i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) {
343 ; CHECK-NEXT: ccmp w2, #2, #0, gt
344 ; CHECK-NEXT: ccmp w1, #13, #2, ge
345 ; CHECK-NEXT: ccmp w0, #0, #4, ls
346 ; CHECK-NEXT: csel w0, w3, wzr, eq
348 %c0 = icmp eq i32 %w0, 0
349 %c1 = icmp ugt i32 %w1, 13
350 %c2 = icmp slt i32 %w2, 2
351 %c4 = icmp sgt i32 %w3, 4
353 %and = and i1 %c2, %c4
354 %or1 = or i1 %or, %and
355 %sel = select i1 %or1, i32 %w3, i32 0
359 ; CHECK-LABEL: select_andor
360 define i32 @select_andor(i32 %v1, i32 %v2, i32 %v3) {
362 ; CHECK-NEXT: ccmp w0, #0, #4, lt
363 ; CHECK-NEXT: ccmp w0, w1, #0, eq
364 ; CHECK-NEXT: csel w0, w0, w1, eq
366 %c0 = icmp eq i32 %v1, %v2
367 %c1 = icmp sge i32 %v2, %v3
368 %c2 = icmp eq i32 %v1, 0
370 %and = and i1 %or, %c0
371 %sel = select i1 %and, i32 %v1, i32 %v2
375 ; CHECK-LABEL: select_noccmp1
376 define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
378 ; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt
379 ; CHECK-NEXT: cmp x0, #13
381 ; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt
382 ; CHECK-NEXT: cmp x2, #2
383 ; CHECK-NEXT: cset [[REG2:w[0-9]+]], lt
384 ; CHECK-NEXT: cmp x2, #4
385 ; CHECK-NEXT: cset [[REG3:w[0-9]+]], gt
386 ; CHECK-NEXT: and [[REG4:w[0-9]+]], [[REG0]], [[REG1]]
387 ; CHECK-NEXT: and [[REG5:w[0-9]+]], [[REG2]], [[REG3]]
388 ; CHECK-NEXT: orr [[REG6:w[0-9]+]], [[REG4]], [[REG5]]
389 ; CHECK-NEXT: cmp [[REG6]], #0
390 ; CHECK-NEXT: csel x0, xzr, x3, ne
392 %c0 = icmp slt i64 %v1, 0
393 %c1 = icmp sgt i64 %v1, 13
394 %c2 = icmp slt i64 %v3, 2
395 %c4 = icmp sgt i64 %v3, 4
396 %and0 = and i1 %c0, %c1
397 %and1 = and i1 %c2, %c4
398 %or = or i1 %and0, %and1
399 %sel = select i1 %or, i64 0, i64 %r
405 ; Should not use ccmp if we have to compute the or expression in an integer
406 ; register anyway because of other users.
407 ; CHECK-LABEL: select_noccmp2
408 define i64 @select_noccmp2(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
410 ; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt
412 ; CHECK-NEXT: cmp x0, #13
413 ; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt
414 ; CHECK-NEXT: orr [[REG2:w[0-9]+]], [[REG0]], [[REG1]]
415 ; CHECK-NEXT: cmp [[REG2]], #0
416 ; CHECK-NEXT: csel x0, xzr, x3, ne
417 ; CHECK-NEXT: sbfx [[REG3:w[0-9]+]], [[REG2]], #0, #1
418 ; CHECK-NEXT: adrp x[[REGN4:[0-9]+]], _g@PAGE
419 ; CHECK-NEXT: str [[REG3]], [x[[REGN4]], _g@PAGEOFF]
421 %c0 = icmp slt i64 %v1, 0
422 %c1 = icmp sgt i64 %v1, 13
424 %sel = select i1 %or, i64 0, i64 %r
425 %ext = sext i1 %or to i32
426 store volatile i32 %ext, i32* @g
430 ; The following is not possible to implement with a single cmp;ccmp;csel
432 ; CHECK-LABEL: select_noccmp3
433 define i32 @select_noccmp3(i32 %v0, i32 %v1, i32 %v2) {
434 %c0 = icmp slt i32 %v0, 0
435 %c1 = icmp sgt i32 %v0, 13
436 %c2 = icmp slt i32 %v0, 22
437 %c3 = icmp sgt i32 %v0, 44
438 %c4 = icmp eq i32 %v0, 99
439 %c5 = icmp eq i32 %v0, 77
440 %or0 = or i1 %c0, %c1
441 %or1 = or i1 %c2, %c3
442 %and0 = and i1 %or0, %or1
443 %or2 = or i1 %c4, %c5
444 %and1 = and i1 %and0, %or2
445 %sel = select i1 %and1, i32 %v1, i32 %v2
449 ; Test the IR CCs that expand to two cond codes.
451 ; CHECK-LABEL: select_and_olt_one:
452 ; CHECK-LABEL: ; %bb.0:
453 ; CHECK-NEXT: fcmp d0, d1
454 ; CHECK-NEXT: fccmp d2, d3, #4, mi
455 ; CHECK-NEXT: fccmp d2, d3, #1, ne
456 ; CHECK-NEXT: csel w0, w0, w1, vc
458 define i32 @select_and_olt_one(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
459 %c0 = fcmp olt double %v0, %v1
460 %c1 = fcmp one double %v2, %v3
461 %cr = and i1 %c1, %c0
462 %sel = select i1 %cr, i32 %a, i32 %b
466 ; CHECK-LABEL: select_and_one_olt:
467 ; CHECK-LABEL: ; %bb.0:
468 ; CHECK-NEXT: fcmp d0, d1
469 ; CHECK-NEXT: fccmp d0, d1, #1, ne
470 ; CHECK-NEXT: fccmp d2, d3, #0, vc
471 ; CHECK-NEXT: csel w0, w0, w1, mi
473 define i32 @select_and_one_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
474 %c0 = fcmp one double %v0, %v1
475 %c1 = fcmp olt double %v2, %v3
476 %cr = and i1 %c1, %c0
477 %sel = select i1 %cr, i32 %a, i32 %b
481 ; CHECK-LABEL: select_and_olt_ueq:
482 ; CHECK-LABEL: ; %bb.0:
483 ; CHECK-NEXT: fcmp d0, d1
484 ; CHECK-NEXT: fccmp d2, d3, #0, mi
485 ; CHECK-NEXT: fccmp d2, d3, #8, le
486 ; CHECK-NEXT: csel w0, w0, w1, pl
488 define i32 @select_and_olt_ueq(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
489 %c0 = fcmp olt double %v0, %v1
490 %c1 = fcmp ueq double %v2, %v3
491 %cr = and i1 %c1, %c0
492 %sel = select i1 %cr, i32 %a, i32 %b
496 ; CHECK-LABEL: select_and_ueq_olt:
497 ; CHECK-LABEL: ; %bb.0:
498 ; CHECK-NEXT: fcmp d0, d1
499 ; CHECK-NEXT: fccmp d0, d1, #8, le
500 ; CHECK-NEXT: fccmp d2, d3, #0, pl
501 ; CHECK-NEXT: csel w0, w0, w1, mi
503 define i32 @select_and_ueq_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
504 %c0 = fcmp ueq double %v0, %v1
505 %c1 = fcmp olt double %v2, %v3
506 %cr = and i1 %c1, %c0
507 %sel = select i1 %cr, i32 %a, i32 %b
511 ; CHECK-LABEL: select_or_olt_one:
512 ; CHECK-LABEL: ; %bb.0:
513 ; CHECK-NEXT: fcmp d0, d1
514 ; CHECK-NEXT: fccmp d2, d3, #0, pl
515 ; CHECK-NEXT: fccmp d2, d3, #8, le
516 ; CHECK-NEXT: csel w0, w0, w1, mi
518 define i32 @select_or_olt_one(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
519 %c0 = fcmp olt double %v0, %v1
520 %c1 = fcmp one double %v2, %v3
522 %sel = select i1 %cr, i32 %a, i32 %b
526 ; CHECK-LABEL: select_or_one_olt:
527 ; CHECK-LABEL: ; %bb.0:
528 ; CHECK-NEXT: fcmp d0, d1
529 ; CHECK-NEXT: fccmp d0, d1, #8, le
530 ; CHECK-NEXT: fccmp d2, d3, #8, pl
531 ; CHECK-NEXT: csel w0, w0, w1, mi
533 define i32 @select_or_one_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
534 %c0 = fcmp one double %v0, %v1
535 %c1 = fcmp olt double %v2, %v3
537 %sel = select i1 %cr, i32 %a, i32 %b
541 ; CHECK-LABEL: select_or_olt_ueq:
542 ; CHECK-LABEL: ; %bb.0:
543 ; CHECK-NEXT: fcmp d0, d1
544 ; CHECK-NEXT: fccmp d2, d3, #4, pl
545 ; CHECK-NEXT: fccmp d2, d3, #1, ne
546 ; CHECK-NEXT: csel w0, w0, w1, vs
548 define i32 @select_or_olt_ueq(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
549 %c0 = fcmp olt double %v0, %v1
550 %c1 = fcmp ueq double %v2, %v3
552 %sel = select i1 %cr, i32 %a, i32 %b
556 ; CHECK-LABEL: select_or_ueq_olt:
557 ; CHECK-LABEL: ; %bb.0:
558 ; CHECK-NEXT: fcmp d0, d1
559 ; CHECK-NEXT: fccmp d0, d1, #1, ne
560 ; CHECK-NEXT: fccmp d2, d3, #8, vc
561 ; CHECK-NEXT: csel w0, w0, w1, mi
563 define i32 @select_or_ueq_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
564 %c0 = fcmp ueq double %v0, %v1
565 %c1 = fcmp olt double %v2, %v3
567 %sel = select i1 %cr, i32 %a, i32 %b
571 ; CHECK-LABEL: select_or_olt_ogt_ueq:
572 ; CHECK-LABEL: ; %bb.0:
573 ; CHECK-NEXT: fcmp d0, d1
574 ; CHECK-NEXT: fccmp d2, d3, #0, pl
575 ; CHECK-NEXT: fccmp d4, d5, #4, le
576 ; CHECK-NEXT: fccmp d4, d5, #1, ne
577 ; CHECK-NEXT: csel w0, w0, w1, vs
579 define i32 @select_or_olt_ogt_ueq(double %v0, double %v1, double %v2, double %v3, double %v4, double %v5, i32 %a, i32 %b) #0 {
580 %c0 = fcmp olt double %v0, %v1
581 %c1 = fcmp ogt double %v2, %v3
582 %c2 = fcmp ueq double %v4, %v5
585 %sel = select i1 %cr, i32 %a, i32 %b
589 ; CHECK-LABEL: select_or_olt_ueq_ogt:
590 ; CHECK-LABEL: ; %bb.0:
591 ; CHECK-NEXT: fcmp d0, d1
592 ; CHECK-NEXT: fccmp d2, d3, #4, pl
593 ; CHECK-NEXT: fccmp d2, d3, #1, ne
594 ; CHECK-NEXT: fccmp d4, d5, #0, vc
595 ; CHECK-NEXT: csel w0, w0, w1, gt
597 define i32 @select_or_olt_ueq_ogt(double %v0, double %v1, double %v2, double %v3, double %v4, double %v5, i32 %a, i32 %b) #0 {
598 %c0 = fcmp olt double %v0, %v1
599 %c1 = fcmp ueq double %v2, %v3
600 %c2 = fcmp ogt double %v4, %v5
603 %sel = select i1 %cr, i32 %a, i32 %b
607 ; Verify that we correctly promote f16.
609 ; CHECK-LABEL: half_select_and_olt_oge:
610 ; CHECK-LABEL: ; %bb.0:
611 ; CHECK-DAG: fcvt [[S0:s[0-9]+]], h0
612 ; CHECK-DAG: fcvt [[S1:s[0-9]+]], h1
613 ; CHECK-NEXT: fcmp [[S0]], [[S1]]
614 ; CHECK-DAG: fcvt [[S2:s[0-9]+]], h2
615 ; CHECK-DAG: fcvt [[S3:s[0-9]+]], h3
616 ; CHECK-NEXT: fccmp [[S2]], [[S3]], #8, mi
617 ; CHECK-NEXT: csel w0, w0, w1, ge
619 define i32 @half_select_and_olt_oge(half %v0, half %v1, half %v2, half %v3, i32 %a, i32 %b) #0 {
620 %c0 = fcmp olt half %v0, %v1
621 %c1 = fcmp oge half %v2, %v3
622 %cr = and i1 %c1, %c0
623 %sel = select i1 %cr, i32 %a, i32 %b
627 ; CHECK-LABEL: half_select_and_olt_one:
628 ; CHECK-LABEL: ; %bb.0:
629 ; CHECK-DAG: fcvt [[S0:s[0-9]+]], h0
630 ; CHECK-DAG: fcvt [[S1:s[0-9]+]], h1
631 ; CHECK-NEXT: fcmp [[S0]], [[S1]]
632 ; CHECK-DAG: fcvt [[S2:s[0-9]+]], h2
633 ; CHECK-DAG: fcvt [[S3:s[0-9]+]], h3
634 ; CHECK-NEXT: fccmp [[S2]], [[S3]], #4, mi
635 ; CHECK-NEXT: fccmp [[S2]], [[S3]], #1, ne
636 ; CHECK-NEXT: csel w0, w0, w1, vc
638 define i32 @half_select_and_olt_one(half %v0, half %v1, half %v2, half %v3, i32 %a, i32 %b) #0 {
639 %c0 = fcmp olt half %v0, %v1
640 %c1 = fcmp one half %v2, %v3
641 %cr = and i1 %c1, %c0
642 %sel = select i1 %cr, i32 %a, i32 %b
646 ; Also verify that we don't try to generate f128 FCCMPs, using RT calls instead.
648 ; CHECK-LABEL: f128_select_and_olt_oge:
651 define i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3, i32 %a, i32 %b) #0 {
652 %c0 = fcmp olt fp128 %v0, %v1
653 %c1 = fcmp oge fp128 %v2, %v3
654 %cr = and i1 %c1, %c0
655 %sel = select i1 %cr, i32 %a, i32 %b
659 ; This testcase resembles the core problem of http://llvm.org/PR39550
660 ; (an OR operation is 2 levels deep but needs to be implemented first)
661 ; CHECK-LABEL: deep_or
663 ; CHECK-NEXT: ccmp w2, #15, #4, ne
664 ; CHECK-NEXT: ccmp w1, #0, #4, eq
665 ; CHECK-NEXT: ccmp w0, #0, #4, ne
666 ; CHECK-NEXT: csel w0, w4, w5, ne
668 define i32 @deep_or(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
669 %c0 = icmp ne i32 %a0, 0
670 %c1 = icmp ne i32 %a1, 0
671 %c2 = icmp eq i32 %a2, 15
672 %c3 = icmp eq i32 %a2, 20
675 %and0 = and i1 %or, %c1
676 %and1 = and i1 %and0, %c0
677 %sel = select i1 %and1, i32 %x, i32 %y
681 ; Variation of deep_or, we still need to implement the OR first though.
682 ; CHECK-LABEL: deep_or1
684 ; CHECK-NEXT: ccmp w2, #15, #4, ne
685 ; CHECK-NEXT: ccmp w0, #0, #4, eq
686 ; CHECK-NEXT: ccmp w1, #0, #4, ne
687 ; CHECK-NEXT: csel w0, w4, w5, ne
689 define i32 @deep_or1(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
690 %c0 = icmp ne i32 %a0, 0
691 %c1 = icmp ne i32 %a1, 0
692 %c2 = icmp eq i32 %a2, 15
693 %c3 = icmp eq i32 %a2, 20
696 %and0 = and i1 %c0, %or
697 %and1 = and i1 %and0, %c1
698 %sel = select i1 %and1, i32 %x, i32 %y
702 ; Variation of deep_or, we still need to implement the OR first though.
703 ; CHECK-LABEL: deep_or2
705 ; CHECK-NEXT: ccmp w2, #15, #4, ne
706 ; CHECK-NEXT: ccmp w1, #0, #4, eq
707 ; CHECK-NEXT: ccmp w0, #0, #4, ne
708 ; CHECK-NEXT: csel w0, w4, w5, ne
710 define i32 @deep_or2(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
711 %c0 = icmp ne i32 %a0, 0
712 %c1 = icmp ne i32 %a1, 0
713 %c2 = icmp eq i32 %a2, 15
714 %c3 = icmp eq i32 %a2, 20
717 %and0 = and i1 %c0, %c1
718 %and1 = and i1 %and0, %or
719 %sel = select i1 %and1, i32 %x, i32 %y
723 attributes #0 = { nounwind }