1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=lanai | FileCheck %s
4 define i32 @f(i32 inreg %a, i32 inreg %b) nounwind ssp {
7 ; CHECK-NEXT: st %fp, [--%sp]
8 ; CHECK-NEXT: add %sp, 0x8, %fp
9 ; CHECK-NEXT: sub %sp, 0x8, %sp
10 ; CHECK-NEXT: sub.f %r6, %r7, %r3
11 ; CHECK-NEXT: sel.gt %r3, %r0, %rv
12 ; CHECK-NEXT: ld -4[%fp], %pc ! return
13 ; CHECK-NEXT: add %fp, 0x0, %sp
14 ; CHECK-NEXT: ld -8[%fp], %fp
15 %cmp = icmp sgt i32 %a, %b
16 %sub = sub nsw i32 %a, %b
17 %sub. = select i1 %cmp, i32 %sub, i32 0
21 define i32 @g(i32 inreg %a, i32 inreg %b) nounwind ssp {
24 ; CHECK-NEXT: st %fp, [--%sp]
25 ; CHECK-NEXT: add %sp, 0x8, %fp
26 ; CHECK-NEXT: sub %sp, 0x8, %sp
27 ; CHECK-NEXT: sub.f %r7, %r6, %r3
28 ; CHECK-NEXT: sel.gt %r3, %r0, %rv
29 ; CHECK-NEXT: ld -4[%fp], %pc ! return
30 ; CHECK-NEXT: add %fp, 0x0, %sp
31 ; CHECK-NEXT: ld -8[%fp], %fp
32 %cmp = icmp slt i32 %a, %b
33 %sub = sub nsw i32 %b, %a
34 %sub. = select i1 %cmp, i32 %sub, i32 0
38 define i32 @h(i32 inreg %a, i32 inreg %b) nounwind ssp {
41 ; CHECK-NEXT: st %fp, [--%sp]
42 ; CHECK-NEXT: add %sp, 0x8, %fp
43 ; CHECK-NEXT: sub %sp, 0x8, %sp
44 ; CHECK-NEXT: sub.f %r6, 0x3, %r3
45 ; CHECK-NEXT: sel.gt %r3, %r7, %rv
46 ; CHECK-NEXT: ld -4[%fp], %pc ! return
47 ; CHECK-NEXT: add %fp, 0x0, %sp
48 ; CHECK-NEXT: ld -8[%fp], %fp
49 %cmp = icmp sgt i32 %a, 3
50 %sub = sub nsw i32 %a, 3
51 %sub. = select i1 %cmp, i32 %sub, i32 %b
55 define i32 @i(i32 inreg %a, i32 inreg %b) nounwind readnone ssp {
58 ; CHECK-NEXT: st %fp, [--%sp]
59 ; CHECK-NEXT: add %sp, 0x8, %fp
60 ; CHECK-NEXT: sub %sp, 0x8, %sp
61 ; CHECK-NEXT: sub.f %r7, %r6, %r3
62 ; CHECK-NEXT: sel.ugt %r3, %r0, %rv
63 ; CHECK-NEXT: ld -4[%fp], %pc ! return
64 ; CHECK-NEXT: add %fp, 0x0, %sp
65 ; CHECK-NEXT: ld -8[%fp], %fp
66 %cmp = icmp ult i32 %a, %b
68 %sub. = select i1 %cmp, i32 %sub, i32 0
72 ; If SR is live-out, we can't remove cmp if there exists a swapped sub.
73 define i32 @j(i32 inreg %a, i32 inreg %b) nounwind {
75 ; CHECK: ! %bb.0: ! %entry
76 ; CHECK-NEXT: st %fp, [--%sp]
77 ; CHECK-NEXT: add %sp, 0x8, %fp
78 ; CHECK-NEXT: sub.f %r6, %r7, %rv
79 ; CHECK-NEXT: bne .LBB4_2
80 ; CHECK-NEXT: sub %sp, 0x8, %sp
81 ; CHECK-NEXT: .LBB4_1: ! %if.then
82 ; CHECK-NEXT: sub.f %r7, %r6, %r0
83 ; CHECK-NEXT: sel.gt %rv, %r6, %rv
84 ; CHECK-NEXT: .LBB4_2: ! %if.else
85 ; CHECK-NEXT: ld -4[%fp], %pc ! return
86 ; CHECK-NEXT: add %fp, 0x0, %sp
87 ; CHECK-NEXT: ld -8[%fp], %fp
89 %cmp = icmp eq i32 %b, %a
90 %sub = sub nsw i32 %a, %b
91 br i1 %cmp, label %if.then, label %if.else
94 %cmp2 = icmp sgt i32 %b, %a
95 %sel = select i1 %cmp2, i32 %sub, i32 %a
102 declare void @abort()
103 declare void @exit(i32)
104 @t = common global i32 0
106 ; If the comparison uses the C bit (signed overflow/underflow), we can't
107 ; omit the comparison.
108 define i32 @cmp_ult0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) {
109 ; CHECK-LABEL: cmp_ult0:
110 ; CHECK: ! %bb.0: ! %entry
111 ; CHECK-NEXT: st %fp, [--%sp]
112 ; CHECK-NEXT: add %sp, 0x8, %fp
113 ; CHECK-NEXT: mov hi(t), %r3
114 ; CHECK-NEXT: or %r3, lo(t), %r3
115 ; CHECK-NEXT: ld 0[%r3], %r3
116 ; CHECK-NEXT: sub %r3, 0x11, %r3
117 ; CHECK-NEXT: sub.f %r3, 0x0, %r0
118 ; CHECK-NEXT: buge .LBB5_2
119 ; CHECK-NEXT: sub %sp, 0x10, %sp
120 ; CHECK-NEXT: .LBB5_1: ! %if.then
121 ; CHECK-NEXT: add %pc, 0x10, %rca
122 ; CHECK-NEXT: st %rca, [--%sp]
123 ; CHECK-NEXT: bt abort
125 ; CHECK-NEXT: .LBB5_2: ! %if.else
126 ; CHECK-NEXT: st %r0, 0[%sp]
127 ; CHECK-NEXT: add %pc, 0x10, %rca
128 ; CHECK-NEXT: st %rca, [--%sp]
129 ; CHECK-NEXT: bt exit
132 %load = load i32, i32* @t, align 4
133 %sub = sub i32 %load, 17
134 %cmp = icmp ult i32 %sub, 0
135 br i1 %cmp, label %if.then, label %if.else
142 call void @exit(i32 0)
146 ; Same for the V bit.
147 ; TODO: add test that exercises V bit individually (VC/VS).
148 define i32 @cmp_gt0(i32 inreg %a, i32 inreg %b, i32 inreg %x, i32 inreg %y) {
149 ; CHECK-LABEL: cmp_gt0:
150 ; CHECK: ! %bb.0: ! %entry
151 ; CHECK-NEXT: st %fp, [--%sp]
152 ; CHECK-NEXT: add %sp, 0x8, %fp
153 ; CHECK-NEXT: mov hi(t), %r3
154 ; CHECK-NEXT: or %r3, lo(t), %r3
155 ; CHECK-NEXT: ld 0[%r3], %r3
156 ; CHECK-NEXT: sub %r3, 0x11, %r3
157 ; CHECK-NEXT: sub.f %r3, 0x1, %r0
158 ; CHECK-NEXT: blt .LBB6_2
159 ; CHECK-NEXT: sub %sp, 0x10, %sp
160 ; CHECK-NEXT: .LBB6_1: ! %if.then
161 ; CHECK-NEXT: add %pc, 0x10, %rca
162 ; CHECK-NEXT: st %rca, [--%sp]
163 ; CHECK-NEXT: bt abort
165 ; CHECK-NEXT: .LBB6_2: ! %if.else
166 ; CHECK-NEXT: st %r0, 0[%sp]
167 ; CHECK-NEXT: add %pc, 0x10, %rca
168 ; CHECK-NEXT: st %rca, [--%sp]
169 ; CHECK-NEXT: bt exit
172 %load = load i32, i32* @t, align 4
173 %sub = sub i32 %load, 17
174 %cmp = icmp sgt i32 %sub, 0
175 br i1 %cmp, label %if.then, label %if.else
182 call void @exit(i32 0)