xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/arm64-csel.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -O3 < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64"
3*9880d681SAndroid Build Coastguard Workertarget triple = "arm64-unknown-unknown"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo1
6*9880d681SAndroid Build Coastguard Worker; CHECK: cinc w{{[0-9]+}}, w{{[0-9]+}}, ne
7*9880d681SAndroid Build Coastguard Workerdefine i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp {
8*9880d681SAndroid Build Coastguard Workerentry:
9*9880d681SAndroid Build Coastguard Worker  %not.tobool = icmp ne i32 %c, 0
10*9880d681SAndroid Build Coastguard Worker  %add = zext i1 %not.tobool to i32
11*9880d681SAndroid Build Coastguard Worker  %b.add = add i32 %c, %b
12*9880d681SAndroid Build Coastguard Worker  %add1 = add i32 %b.add, %add
13*9880d681SAndroid Build Coastguard Worker  ret i32 %add1
14*9880d681SAndroid Build Coastguard Worker}
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo2
17*9880d681SAndroid Build Coastguard Worker; CHECK: cneg w{{[0-9]+}}, w{{[0-9]+}}, ne
18*9880d681SAndroid Build Coastguard Workerdefine i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp {
19*9880d681SAndroid Build Coastguard Workerentry:
20*9880d681SAndroid Build Coastguard Worker  %mul = sub i32 0, %b
21*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %c, 0
22*9880d681SAndroid Build Coastguard Worker  %b.mul = select i1 %tobool, i32 %b, i32 %mul
23*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %b.mul, %c
24*9880d681SAndroid Build Coastguard Worker  ret i32 %add
25*9880d681SAndroid Build Coastguard Worker}
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo3
28*9880d681SAndroid Build Coastguard Worker; CHECK: cinv w{{[0-9]+}}, w{{[0-9]+}}, ne
29*9880d681SAndroid Build Coastguard Workerdefine i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp {
30*9880d681SAndroid Build Coastguard Workerentry:
31*9880d681SAndroid Build Coastguard Worker  %not.tobool = icmp ne i32 %c, 0
32*9880d681SAndroid Build Coastguard Worker  %xor = sext i1 %not.tobool to i32
33*9880d681SAndroid Build Coastguard Worker  %b.xor = xor i32 %xor, %b
34*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %b.xor, %c
35*9880d681SAndroid Build Coastguard Worker  ret i32 %add
36*9880d681SAndroid Build Coastguard Worker}
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker; rdar://11632325
39*9880d681SAndroid Build Coastguard Workerdefine i32@foo4(i32 %a) nounwind ssp {
40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo4
41*9880d681SAndroid Build Coastguard Worker; CHECK: cneg
42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
43*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, -1
44*9880d681SAndroid Build Coastguard Worker  %neg = sub nsw i32 0, %a
45*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %cmp, i32 %a, i32 %neg
46*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
47*9880d681SAndroid Build Coastguard Worker}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Workerdefine i32@foo5(i32 %a, i32 %b) nounwind ssp {
50*9880d681SAndroid Build Coastguard Workerentry:
51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo5
52*9880d681SAndroid Build Coastguard Worker; CHECK: subs
53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cneg
54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
55*9880d681SAndroid Build Coastguard Worker  %sub = sub nsw i32 %a, %b
56*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %sub, -1
57*9880d681SAndroid Build Coastguard Worker  %sub3 = sub nsw i32 0, %sub
58*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %cmp, i32 %sub, i32 %sub3
59*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
60*9880d681SAndroid Build Coastguard Worker}
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; make sure we can handle branch instruction in optimizeCompare.
63*9880d681SAndroid Build Coastguard Workerdefine i32@foo6(i32 %a, i32 %b) nounwind ssp {
64*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo6
65*9880d681SAndroid Build Coastguard Worker; CHECK: b
66*9880d681SAndroid Build Coastguard Worker  %sub = sub nsw i32 %a, %b
67*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %sub, 0
68*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %l.if, label %l.else
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Workerl.if:
71*9880d681SAndroid Build Coastguard Worker  ret i32 1
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Workerl.else:
74*9880d681SAndroid Build Coastguard Worker  ret i32 %sub
75*9880d681SAndroid Build Coastguard Worker}
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker; If CPSR is used multiple times and V flag is used, we don't remove cmp.
78*9880d681SAndroid Build Coastguard Workerdefine i32 @foo7(i32 %a, i32 %b) nounwind {
79*9880d681SAndroid Build Coastguard Workerentry:
80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo7:
81*9880d681SAndroid Build Coastguard Worker; CHECK: sub
82*9880d681SAndroid Build Coastguard Worker; CHECK-next: adds
83*9880d681SAndroid Build Coastguard Worker; CHECK-next: csneg
84*9880d681SAndroid Build Coastguard Worker; CHECK-next: b
85*9880d681SAndroid Build Coastguard Worker  %sub = sub nsw i32 %a, %b
86*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %sub, -1
87*9880d681SAndroid Build Coastguard Worker  %sub3 = sub nsw i32 0, %sub
88*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %cmp, i32 %sub, i32 %sub3
89*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if.then, label %if.else
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Workerif.then:
92*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp slt i32 %sub, -1
93*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cmp2, i32 %cond, i32 %a
94*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Workerif.else:
97*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
98*9880d681SAndroid Build Coastguard Worker}
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerdefine i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp {
101*9880d681SAndroid Build Coastguard Workerentry:
102*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo8:
103*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
104*9880d681SAndroid Build Coastguard Worker; CHECK: csinv w0, w1, w2, ne
105*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %v, 0
106*9880d681SAndroid Build Coastguard Worker  %neg = xor i32 -1, %b
107*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i32 %neg, i32 %a
108*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
109*9880d681SAndroid Build Coastguard Worker}
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Workerdefine i32 @foo9(i32 %v) nounwind readnone optsize ssp {
112*9880d681SAndroid Build Coastguard Workerentry:
113*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo9:
114*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
115*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
116*9880d681SAndroid Build Coastguard Worker; CHECK: cinv w0, w[[REG]], eq
117*9880d681SAndroid Build Coastguard Worker  %tobool = icmp ne i32 %v, 0
118*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i32 4, i32 -5
119*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
120*9880d681SAndroid Build Coastguard Worker}
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Workerdefine i64 @foo10(i64 %v) nounwind readnone optsize ssp {
123*9880d681SAndroid Build Coastguard Workerentry:
124*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo10:
125*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0
126*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
127*9880d681SAndroid Build Coastguard Worker; CHECK: cinv x0, x[[REG]], eq
128*9880d681SAndroid Build Coastguard Worker  %tobool = icmp ne i64 %v, 0
129*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i64 4, i64 -5
130*9880d681SAndroid Build Coastguard Worker  ret i64 %cond
131*9880d681SAndroid Build Coastguard Worker}
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Workerdefine i32 @foo11(i32 %v) nounwind readnone optsize ssp {
134*9880d681SAndroid Build Coastguard Workerentry:
135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo11:
136*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
137*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
138*9880d681SAndroid Build Coastguard Worker; CHECK: cneg w0, w[[REG]], eq
139*9880d681SAndroid Build Coastguard Worker  %tobool = icmp ne i32 %v, 0
140*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i32 4, i32 -4
141*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
142*9880d681SAndroid Build Coastguard Worker}
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workerdefine i64 @foo12(i64 %v) nounwind readnone optsize ssp {
145*9880d681SAndroid Build Coastguard Workerentry:
146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo12:
147*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0
148*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
149*9880d681SAndroid Build Coastguard Worker; CHECK: cneg x0, x[[REG]], eq
150*9880d681SAndroid Build Coastguard Worker  %tobool = icmp ne i64 %v, 0
151*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i64 4, i64 -4
152*9880d681SAndroid Build Coastguard Worker  ret i64 %cond
153*9880d681SAndroid Build Coastguard Worker}
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Workerdefine i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp {
156*9880d681SAndroid Build Coastguard Workerentry:
157*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo13:
158*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
159*9880d681SAndroid Build Coastguard Worker; CHECK: csneg w0, w1, w2, ne
160*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %v, 0
161*9880d681SAndroid Build Coastguard Worker  %sub = sub i32 0, %b
162*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i32 %sub, i32 %a
163*9880d681SAndroid Build Coastguard Worker  ret i32 %cond
164*9880d681SAndroid Build Coastguard Worker}
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Workerdefine i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp {
167*9880d681SAndroid Build Coastguard Workerentry:
168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo14:
169*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0
170*9880d681SAndroid Build Coastguard Worker; CHECK: csneg x0, x1, x2, ne
171*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i64 %v, 0
172*9880d681SAndroid Build Coastguard Worker  %sub = sub i64 0, %b
173*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %tobool, i64 %sub, i64 %a
174*9880d681SAndroid Build Coastguard Worker  ret i64 %cond
175*9880d681SAndroid Build Coastguard Worker}
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Workerdefine i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp {
178*9880d681SAndroid Build Coastguard Workerentry:
179*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo15:
180*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, w1
181*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
182*9880d681SAndroid Build Coastguard Worker; CHECK: cinc w0, w[[REG]], gt
183*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, %b
184*9880d681SAndroid Build Coastguard Worker  %. = select i1 %cmp, i32 2, i32 1
185*9880d681SAndroid Build Coastguard Worker  ret i32 %.
186*9880d681SAndroid Build Coastguard Worker}
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workerdefine i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp {
189*9880d681SAndroid Build Coastguard Workerentry:
190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo16:
191*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, w1
192*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
193*9880d681SAndroid Build Coastguard Worker; CHECK: cinc w0, w[[REG]], le
194*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, %b
195*9880d681SAndroid Build Coastguard Worker  %. = select i1 %cmp, i32 1, i32 2
196*9880d681SAndroid Build Coastguard Worker  ret i32 %.
197*9880d681SAndroid Build Coastguard Worker}
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Workerdefine i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp {
200*9880d681SAndroid Build Coastguard Workerentry:
201*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo17:
202*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, x1
203*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
204*9880d681SAndroid Build Coastguard Worker; CHECK: cinc x0, x[[REG]], gt
205*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i64 %a, %b
206*9880d681SAndroid Build Coastguard Worker  %. = select i1 %cmp, i64 2, i64 1
207*9880d681SAndroid Build Coastguard Worker  ret i64 %.
208*9880d681SAndroid Build Coastguard Worker}
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Workerdefine i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp {
211*9880d681SAndroid Build Coastguard Workerentry:
212*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo18:
213*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, x1
214*9880d681SAndroid Build Coastguard Worker; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
215*9880d681SAndroid Build Coastguard Worker; CHECK: cinc x0, x[[REG]], le
216*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i64 %a, %b
217*9880d681SAndroid Build Coastguard Worker  %. = select i1 %cmp, i64 1, i64 2
218*9880d681SAndroid Build Coastguard Worker  ret i64 %.
219*9880d681SAndroid Build Coastguard Worker}
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Workerdefine i64 @foo19(i64 %a, i64 %b, i64 %c) {
222*9880d681SAndroid Build Coastguard Workerentry:
223*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo19:
224*9880d681SAndroid Build Coastguard Worker; CHECK: cinc x0, x2
225*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add
226*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i64 %a, %b
227*9880d681SAndroid Build Coastguard Worker  %inc = zext i1 %cmp to i64
228*9880d681SAndroid Build Coastguard Worker  %inc.c = add i64 %inc, %c
229*9880d681SAndroid Build Coastguard Worker  ret i64 %inc.c
230*9880d681SAndroid Build Coastguard Worker}
231