xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/arm64-ccmp.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=cyclone -verify-machineinstrs -aarch64-ccmp -aarch64-stress-ccmp | FileCheck %s
2*9880d681SAndroid Build Coastguard Workertarget triple = "arm64-apple-ios"
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; CHECK: single_same
5*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #5
6*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w1, #17, #4, ne
7*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.ne
8*9880d681SAndroid Build Coastguard Worker; CHECK: %if.then
9*9880d681SAndroid Build Coastguard Worker; CHECK: bl _foo
10*9880d681SAndroid Build Coastguard Worker; CHECK: %if.end
11*9880d681SAndroid Build Coastguard Workerdefine i32 @single_same(i32 %a, i32 %b) nounwind ssp {
12*9880d681SAndroid Build Coastguard Workerentry:
13*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 5
14*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp eq i32 %b, 17
15*9880d681SAndroid Build Coastguard Worker  %or.cond = or i1 %cmp, %cmp1
16*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Workerif.then:
19*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
20*9880d681SAndroid Build Coastguard Worker  br label %if.end
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Workerif.end:
23*9880d681SAndroid Build Coastguard Worker  ret i32 7
24*9880d681SAndroid Build Coastguard Worker}
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker; Different condition codes for the two compares.
27*9880d681SAndroid Build Coastguard Worker; CHECK: single_different
28*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #6
29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w1, #17, #0, ge
30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.eq
31*9880d681SAndroid Build Coastguard Worker; CHECK: %if.then
32*9880d681SAndroid Build Coastguard Worker; CHECK: bl _foo
33*9880d681SAndroid Build Coastguard Worker; CHECK: %if.end
34*9880d681SAndroid Build Coastguard Workerdefine i32 @single_different(i32 %a, i32 %b) nounwind ssp {
35*9880d681SAndroid Build Coastguard Workerentry:
36*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sle i32 %a, 5
37*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp ne i32 %b, 17
38*9880d681SAndroid Build Coastguard Worker  %or.cond = or i1 %cmp, %cmp1
39*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Workerif.then:
42*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
43*9880d681SAndroid Build Coastguard Worker  br label %if.end
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Workerif.end:
46*9880d681SAndroid Build Coastguard Worker  ret i32 7
47*9880d681SAndroid Build Coastguard Worker}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; Second block clobbers the flags, can't convert (easily).
50*9880d681SAndroid Build Coastguard Worker; CHECK: single_flagclobber
51*9880d681SAndroid Build Coastguard Worker; CHECK: cmp
52*9880d681SAndroid Build Coastguard Worker; CHECK: b.eq
53*9880d681SAndroid Build Coastguard Worker; CHECK: cmp
54*9880d681SAndroid Build Coastguard Worker; CHECK: b.gt
55*9880d681SAndroid Build Coastguard Workerdefine i32 @single_flagclobber(i32 %a, i32 %b) nounwind ssp {
56*9880d681SAndroid Build Coastguard Workerentry:
57*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 5
58*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if.then, label %lor.lhs.false
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Workerlor.lhs.false:                                    ; preds = %entry
61*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i32 %b, 7
62*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %b, 1
63*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %b, 1
64*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %cmp1, i32 %mul, i32 %add
65*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp slt i32 %cond, 17
66*9880d681SAndroid Build Coastguard Worker  br i1 %cmp2, label %if.then, label %if.end
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %lor.lhs.false, %entry
69*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
70*9880d681SAndroid Build Coastguard Worker  br label %if.end
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.then, %lor.lhs.false
73*9880d681SAndroid Build Coastguard Worker  ret i32 7
74*9880d681SAndroid Build Coastguard Worker}
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker; Second block clobbers the flags and ends with a tbz terminator.
77*9880d681SAndroid Build Coastguard Worker; CHECK: single_flagclobber_tbz
78*9880d681SAndroid Build Coastguard Worker; CHECK: cmp
79*9880d681SAndroid Build Coastguard Worker; CHECK: b.eq
80*9880d681SAndroid Build Coastguard Worker; CHECK: cmp
81*9880d681SAndroid Build Coastguard Worker; CHECK: tbz
82*9880d681SAndroid Build Coastguard Workerdefine i32 @single_flagclobber_tbz(i32 %a, i32 %b) nounwind ssp {
83*9880d681SAndroid Build Coastguard Workerentry:
84*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 5
85*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if.then, label %lor.lhs.false
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Workerlor.lhs.false:                                    ; preds = %entry
88*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i32 %b, 7
89*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %b, 1
90*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %b, 1
91*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %cmp1, i32 %mul, i32 %add
92*9880d681SAndroid Build Coastguard Worker  %and = and i32 %cond, 8
93*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp ne i32 %and, 0
94*9880d681SAndroid Build Coastguard Worker  br i1 %cmp2, label %if.then, label %if.end
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %lor.lhs.false, %entry
97*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
98*9880d681SAndroid Build Coastguard Worker  br label %if.end
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.then, %lor.lhs.false
101*9880d681SAndroid Build Coastguard Worker  ret i32 7
102*9880d681SAndroid Build Coastguard Worker}
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker; Speculatively execute division by zero.
105*9880d681SAndroid Build Coastguard Worker; The sdiv/udiv instructions do not trap when the divisor is zero, so they are
106*9880d681SAndroid Build Coastguard Worker; safe to speculate.
107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: speculate_division:
108*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #1
109*9880d681SAndroid Build Coastguard Worker; CHECK: sdiv [[DIVRES:w[0-9]+]], w1, w0
110*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp [[DIVRES]], #16, #0, ge
111*9880d681SAndroid Build Coastguard Worker; CHECK: b.gt [[BLOCK:LBB[0-9_]+]]
112*9880d681SAndroid Build Coastguard Worker; CHECK: bl _foo
113*9880d681SAndroid Build Coastguard Worker; CHECK: [[BLOCK]]:
114*9880d681SAndroid Build Coastguard Worker; CHECK: orr w0, wzr, #0x7
115*9880d681SAndroid Build Coastguard Workerdefine i32 @speculate_division(i32 %a, i32 %b) nounwind ssp {
116*9880d681SAndroid Build Coastguard Workerentry:
117*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, 0
118*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %land.lhs.true, label %if.end
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerland.lhs.true:
121*9880d681SAndroid Build Coastguard Worker  %div = sdiv i32 %b, %a
122*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp slt i32 %div, 17
123*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %if.end
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Workerif.then:
126*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
127*9880d681SAndroid Build Coastguard Worker  br label %if.end
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Workerif.end:
130*9880d681SAndroid Build Coastguard Worker  ret i32 7
131*9880d681SAndroid Build Coastguard Worker}
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker; Floating point compare.
134*9880d681SAndroid Build Coastguard Worker; CHECK: single_fcmp
135*9880d681SAndroid Build Coastguard Worker; CHECK: cmp
136*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: b.
137*9880d681SAndroid Build Coastguard Worker; CHECK: fccmp {{.*}}, #8, ge
138*9880d681SAndroid Build Coastguard Worker; CHECK: b.lt
139*9880d681SAndroid Build Coastguard Workerdefine i32 @single_fcmp(i32 %a, float %b) nounwind ssp {
140*9880d681SAndroid Build Coastguard Workerentry:
141*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, 0
142*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %land.lhs.true, label %if.end
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workerland.lhs.true:
145*9880d681SAndroid Build Coastguard Worker  %conv = sitofp i32 %a to float
146*9880d681SAndroid Build Coastguard Worker  %div = fdiv float %b, %conv
147*9880d681SAndroid Build Coastguard Worker  %cmp1 = fcmp oge float %div, 1.700000e+01
148*9880d681SAndroid Build Coastguard Worker  br i1 %cmp1, label %if.then, label %if.end
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Workerif.then:
151*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
152*9880d681SAndroid Build Coastguard Worker  br label %if.end
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Workerif.end:
155*9880d681SAndroid Build Coastguard Worker  ret i32 7
156*9880d681SAndroid Build Coastguard Worker}
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker; Chain multiple compares.
159*9880d681SAndroid Build Coastguard Worker; CHECK: multi_different
160*9880d681SAndroid Build Coastguard Worker; CHECK: cmp
161*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp
162*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp
163*9880d681SAndroid Build Coastguard Worker; CHECK: b.
164*9880d681SAndroid Build Coastguard Workerdefine void @multi_different(i32 %a, i32 %b, i32 %c) nounwind ssp {
165*9880d681SAndroid Build Coastguard Workerentry:
166*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %a, %b
167*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %land.lhs.true, label %if.end
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerland.lhs.true:
170*9880d681SAndroid Build Coastguard Worker  %div = sdiv i32 %b, %a
171*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp eq i32 %div, 5
172*9880d681SAndroid Build Coastguard Worker  %cmp4 = icmp sgt i32 %div, %c
173*9880d681SAndroid Build Coastguard Worker  %or.cond = and i1 %cmp1, %cmp4
174*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Workerif.then:
177*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
178*9880d681SAndroid Build Coastguard Worker  br label %if.end
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Workerif.end:
181*9880d681SAndroid Build Coastguard Worker  ret void
182*9880d681SAndroid Build Coastguard Worker}
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker; Convert a cbz in the head block.
185*9880d681SAndroid Build Coastguard Worker; CHECK: cbz_head
186*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
187*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp
188*9880d681SAndroid Build Coastguard Workerdefine i32 @cbz_head(i32 %a, i32 %b) nounwind ssp {
189*9880d681SAndroid Build Coastguard Workerentry:
190*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
191*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp ne i32 %b, 17
192*9880d681SAndroid Build Coastguard Worker  %or.cond = or i1 %cmp, %cmp1
193*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Workerif.then:
196*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
197*9880d681SAndroid Build Coastguard Worker  br label %if.end
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Workerif.end:
200*9880d681SAndroid Build Coastguard Worker  ret i32 7
201*9880d681SAndroid Build Coastguard Worker}
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker; Check that the immediate operand is in range. The ccmp instruction encodes a
204*9880d681SAndroid Build Coastguard Worker; smaller range of immediates than subs/adds.
205*9880d681SAndroid Build Coastguard Worker; The ccmp immediates must be in the range 0-31.
206*9880d681SAndroid Build Coastguard Worker; CHECK: immediate_range
207*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ccmp
208*9880d681SAndroid Build Coastguard Workerdefine i32 @immediate_range(i32 %a, i32 %b) nounwind ssp {
209*9880d681SAndroid Build Coastguard Workerentry:
210*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 5
211*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp eq i32 %b, 32
212*9880d681SAndroid Build Coastguard Worker  %or.cond = or i1 %cmp, %cmp1
213*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Workerif.then:
216*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
217*9880d681SAndroid Build Coastguard Worker  br label %if.end
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Workerif.end:
220*9880d681SAndroid Build Coastguard Worker  ret i32 7
221*9880d681SAndroid Build Coastguard Worker}
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker; Convert a cbz in the second block.
224*9880d681SAndroid Build Coastguard Worker; CHECK: cbz_second
225*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
226*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp w1, #0, #0, ne
227*9880d681SAndroid Build Coastguard Worker; CHECK: b.eq
228*9880d681SAndroid Build Coastguard Workerdefine i32 @cbz_second(i32 %a, i32 %b) nounwind ssp {
229*9880d681SAndroid Build Coastguard Workerentry:
230*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
231*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp ne i32 %b, 0
232*9880d681SAndroid Build Coastguard Worker  %or.cond = or i1 %cmp, %cmp1
233*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Workerif.then:
236*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
237*9880d681SAndroid Build Coastguard Worker  br label %if.end
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Workerif.end:
240*9880d681SAndroid Build Coastguard Worker  ret i32 7
241*9880d681SAndroid Build Coastguard Worker}
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker; Convert a cbnz in the second block.
244*9880d681SAndroid Build Coastguard Worker; CHECK: cbnz_second
245*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w0, #0
246*9880d681SAndroid Build Coastguard Worker; CHECK: ccmp w1, #0, #4, ne
247*9880d681SAndroid Build Coastguard Worker; CHECK: b.ne
248*9880d681SAndroid Build Coastguard Workerdefine i32 @cbnz_second(i32 %a, i32 %b) nounwind ssp {
249*9880d681SAndroid Build Coastguard Workerentry:
250*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
251*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp eq i32 %b, 0
252*9880d681SAndroid Build Coastguard Worker  %or.cond = or i1 %cmp, %cmp1
253*9880d681SAndroid Build Coastguard Worker  br i1 %or.cond, label %if.then, label %if.end
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Workerif.then:
256*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @foo() nounwind
257*9880d681SAndroid Build Coastguard Worker  br label %if.end
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Workerif.end:
260*9880d681SAndroid Build Coastguard Worker  ret i32 7
261*9880d681SAndroid Build Coastguard Worker}
262*9880d681SAndroid Build Coastguard Workerdeclare i32 @foo()
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker%str1 = type { %str2 }
265*9880d681SAndroid Build Coastguard Worker%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* }
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker; Test case distilled from 126.gcc.
268*9880d681SAndroid Build Coastguard Worker; The phi in sw.bb.i.i gets multiple operands for the %entry predecessor.
269*9880d681SAndroid Build Coastguard Worker; CHECK: build_modify_expr
270*9880d681SAndroid Build Coastguard Workerdefine void @build_modify_expr() nounwind ssp {
271*9880d681SAndroid Build Coastguard Workerentry:
272*9880d681SAndroid Build Coastguard Worker  switch i32 undef, label %sw.bb.i.i [
273*9880d681SAndroid Build Coastguard Worker    i32 69, label %if.end85
274*9880d681SAndroid Build Coastguard Worker    i32 70, label %if.end85
275*9880d681SAndroid Build Coastguard Worker    i32 71, label %if.end85
276*9880d681SAndroid Build Coastguard Worker    i32 72, label %if.end85
277*9880d681SAndroid Build Coastguard Worker    i32 73, label %if.end85
278*9880d681SAndroid Build Coastguard Worker    i32 105, label %if.end85
279*9880d681SAndroid Build Coastguard Worker    i32 106, label %if.end85
280*9880d681SAndroid Build Coastguard Worker  ]
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Workerif.end85:
283*9880d681SAndroid Build Coastguard Worker  ret void
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Workersw.bb.i.i:
286*9880d681SAndroid Build Coastguard Worker  %ref.tr.i.i = phi %str1* [ %0, %sw.bb.i.i ], [ undef, %entry ]
287*9880d681SAndroid Build Coastguard Worker  %operands.i.i = getelementptr inbounds %str1, %str1* %ref.tr.i.i, i64 0, i32 0, i32 2
288*9880d681SAndroid Build Coastguard Worker  %arrayidx.i.i = bitcast i32* %operands.i.i to %str1**
289*9880d681SAndroid Build Coastguard Worker  %0 = load %str1*, %str1** %arrayidx.i.i, align 8
290*9880d681SAndroid Build Coastguard Worker  %code1.i.i.phi.trans.insert = getelementptr inbounds %str1, %str1* %0, i64 0, i32 0, i32 0, i64 16
291*9880d681SAndroid Build Coastguard Worker  br label %sw.bb.i.i
292*9880d681SAndroid Build Coastguard Worker}
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and
295*9880d681SAndroid Build Coastguard Workerdefine i64 @select_and(i32 %w0, i32 %w1, i64 %x2, i64 %x3) {
296*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w1, #5
297*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, w1, #0, ne
298*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, x2, x3, lt
299*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
300*9880d681SAndroid Build Coastguard Worker  %1 = icmp slt i32 %w0, %w1
301*9880d681SAndroid Build Coastguard Worker  %2 = icmp ne i32 5, %w1
302*9880d681SAndroid Build Coastguard Worker  %3 = and i1 %1, %2
303*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %3, i64 %x2, i64 %x3
304*9880d681SAndroid Build Coastguard Worker  ret i64 %sel
305*9880d681SAndroid Build Coastguard Worker}
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or
308*9880d681SAndroid Build Coastguard Workerdefine i64 @select_or(i32 %w0, i32 %w1, i64 %x2, i64 %x3) {
309*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w1, #5
310*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, w1, #8, eq
311*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, x2, x3, lt
312*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
313*9880d681SAndroid Build Coastguard Worker  %1 = icmp slt i32 %w0, %w1
314*9880d681SAndroid Build Coastguard Worker  %2 = icmp ne i32 5, %w1
315*9880d681SAndroid Build Coastguard Worker  %3 = or i1 %1, %2
316*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %3, i64 %x2, i64 %x3
317*9880d681SAndroid Build Coastguard Worker  ret i64 %sel
318*9880d681SAndroid Build Coastguard Worker}
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: gccbug
321*9880d681SAndroid Build Coastguard Workerdefine i64 @gccbug(i64 %x0, i64 %x1) {
322*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #2
323*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp x0, #4, #4, ne
324*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp x1, #0, #0, eq
325*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr w[[REGNUM:[0-9]+]], wzr, #0x1
326*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cinc x0, x[[REGNUM]], eq
327*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
328*9880d681SAndroid Build Coastguard Worker  %cmp0 = icmp eq i64 %x1, 0
329*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp eq i64 %x0, 2
330*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp eq i64 %x0, 4
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker  %or = or i1 %cmp2, %cmp1
333*9880d681SAndroid Build Coastguard Worker  %and = and i1 %or, %cmp0
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %and, i64 2, i64 1
336*9880d681SAndroid Build Coastguard Worker  ret i64 %sel
337*9880d681SAndroid Build Coastguard Worker}
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_ororand
340*9880d681SAndroid Build Coastguard Workerdefine i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) {
341*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w3, #4
342*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w2, #2, #0, gt
343*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w1, #13, #2, ge
344*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, #0, #4, ls
345*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w3, wzr, eq
346*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
347*9880d681SAndroid Build Coastguard Worker  %c0 = icmp eq i32 %w0, 0
348*9880d681SAndroid Build Coastguard Worker  %c1 = icmp ugt i32 %w1, 13
349*9880d681SAndroid Build Coastguard Worker  %c2 = icmp slt i32 %w2, 2
350*9880d681SAndroid Build Coastguard Worker  %c4 = icmp sgt i32 %w3, 4
351*9880d681SAndroid Build Coastguard Worker  %or = or i1 %c0, %c1
352*9880d681SAndroid Build Coastguard Worker  %and = and i1 %c2, %c4
353*9880d681SAndroid Build Coastguard Worker  %or1 = or i1 %or, %and
354*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %or1, i32 %w3, i32 0
355*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
356*9880d681SAndroid Build Coastguard Worker}
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_andor
359*9880d681SAndroid Build Coastguard Workerdefine i32 @select_andor(i32 %v1, i32 %v2, i32 %v3) {
360*9880d681SAndroid Build Coastguard Worker; CHECK: cmp w1, w2
361*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, #0, #4, lt
362*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ccmp w0, w1, #0, eq
363*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, eq
364*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
365*9880d681SAndroid Build Coastguard Worker  %c0 = icmp eq i32 %v1, %v2
366*9880d681SAndroid Build Coastguard Worker  %c1 = icmp sge i32 %v2, %v3
367*9880d681SAndroid Build Coastguard Worker  %c2 = icmp eq i32 %v1, 0
368*9880d681SAndroid Build Coastguard Worker  %or = or i1 %c2, %c1
369*9880d681SAndroid Build Coastguard Worker  %and = and i1 %or, %c0
370*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %and, i32 %v1, i32 %v2
371*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
372*9880d681SAndroid Build Coastguard Worker}
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_noccmp1
375*9880d681SAndroid Build Coastguard Workerdefine i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
376*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0
377*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt
378*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x0, #13
379*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ccmp
380*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt
381*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x2, #2
382*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG2:w[0-9]+]], lt
383*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x2, #4
384*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG3:w[0-9]+]], gt
385*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[REG4:w[0-9]+]], [[REG0]], [[REG1]]
386*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[REG5:w[0-9]+]], [[REG2]], [[REG3]]
387*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[REG6:w[0-9]+]], [[REG4]], [[REG5]]
388*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[REG6]], #0
389*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, xzr, x3, ne
390*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
391*9880d681SAndroid Build Coastguard Worker  %c0 = icmp slt i64 %v1, 0
392*9880d681SAndroid Build Coastguard Worker  %c1 = icmp sgt i64 %v1, 13
393*9880d681SAndroid Build Coastguard Worker  %c2 = icmp slt i64 %v3, 2
394*9880d681SAndroid Build Coastguard Worker  %c4 = icmp sgt i64 %v3, 4
395*9880d681SAndroid Build Coastguard Worker  %and0 = and i1 %c0, %c1
396*9880d681SAndroid Build Coastguard Worker  %and1 = and i1 %c2, %c4
397*9880d681SAndroid Build Coastguard Worker  %or = or i1 %and0, %and1
398*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %or, i64 0, i64 %r
399*9880d681SAndroid Build Coastguard Worker  ret i64 %sel
400*9880d681SAndroid Build Coastguard Worker}
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker@g = global i32 0
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker; Should not use ccmp if we have to compute the or expression in an integer
405*9880d681SAndroid Build Coastguard Worker; register anyway because of other users.
406*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_noccmp2
407*9880d681SAndroid Build Coastguard Workerdefine i64 @select_noccmp2(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
408*9880d681SAndroid Build Coastguard Worker; CHECK: cmp x0, #0
409*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG0:w[0-9]+]], lt
410*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ccmp
411*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x0, #13
412*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cset [[REG1:w[0-9]+]], gt
413*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[REG2:w[0-9]+]], [[REG0]], [[REG1]]
414*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[REG2]], #0
415*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel x0, xzr, x3, ne
416*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sbfx [[REG3:w[0-9]+]], [[REG2]], #0, #1
417*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: adrp x[[REGN4:[0-9]+]], _g@PAGE
418*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[REG3]], [x[[REGN4]], _g@PAGEOFF]
419*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
420*9880d681SAndroid Build Coastguard Worker  %c0 = icmp slt i64 %v1, 0
421*9880d681SAndroid Build Coastguard Worker  %c1 = icmp sgt i64 %v1, 13
422*9880d681SAndroid Build Coastguard Worker  %or = or i1 %c0, %c1
423*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %or, i64 0, i64 %r
424*9880d681SAndroid Build Coastguard Worker  %ext = sext i1 %or to i32
425*9880d681SAndroid Build Coastguard Worker  store volatile i32 %ext, i32* @g
426*9880d681SAndroid Build Coastguard Worker  ret i64 %sel
427*9880d681SAndroid Build Coastguard Worker}
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker; The following is not possible to implement with a single cmp;ccmp;csel
430*9880d681SAndroid Build Coastguard Worker; sequence.
431*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_noccmp3
432*9880d681SAndroid Build Coastguard Workerdefine i32 @select_noccmp3(i32 %v0, i32 %v1, i32 %v2) {
433*9880d681SAndroid Build Coastguard Worker  %c0 = icmp slt i32 %v0, 0
434*9880d681SAndroid Build Coastguard Worker  %c1 = icmp sgt i32 %v0, 13
435*9880d681SAndroid Build Coastguard Worker  %c2 = icmp slt i32 %v0, 22
436*9880d681SAndroid Build Coastguard Worker  %c3 = icmp sgt i32 %v0, 44
437*9880d681SAndroid Build Coastguard Worker  %c4 = icmp eq i32 %v0, 99
438*9880d681SAndroid Build Coastguard Worker  %c5 = icmp eq i32 %v0, 77
439*9880d681SAndroid Build Coastguard Worker  %or0 = or i1 %c0, %c1
440*9880d681SAndroid Build Coastguard Worker  %or1 = or i1 %c2, %c3
441*9880d681SAndroid Build Coastguard Worker  %and0 = and i1 %or0, %or1
442*9880d681SAndroid Build Coastguard Worker  %or2 = or i1 %c4, %c5
443*9880d681SAndroid Build Coastguard Worker  %and1 = and i1 %and0, %or2
444*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %and1, i32 %v1, i32 %v2
445*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
446*9880d681SAndroid Build Coastguard Worker}
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker; Test the IR CCs that expand to two cond codes.
449*9880d681SAndroid Build Coastguard Worker
450*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_olt_one:
451*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
452*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
453*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #4, mi
454*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #1, ne
455*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vc
456*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
457*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_olt_one(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
458*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt double %v0, %v1
459*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp one double %v2, %v3
460*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
461*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
462*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
463*9880d681SAndroid Build Coastguard Worker}
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_one_olt:
466*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
467*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
468*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #1, ne
469*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, vc
470*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi
471*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
472*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_one_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
473*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp one double %v0, %v1
474*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp olt double %v2, %v3
475*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
476*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
477*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
478*9880d681SAndroid Build Coastguard Worker}
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_olt_ueq:
481*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
482*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
483*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, mi
484*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, le
485*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, pl
486*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
487*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_olt_ueq(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
488*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt double %v0, %v1
489*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp ueq double %v2, %v3
490*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
491*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
492*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
493*9880d681SAndroid Build Coastguard Worker}
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_and_ueq_olt:
496*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
497*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
498*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #8, le
499*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, pl
500*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi
501*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
502*9880d681SAndroid Build Coastguard Workerdefine i32 @select_and_ueq_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
503*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp ueq double %v0, %v1
504*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp olt double %v2, %v3
505*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
506*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
507*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
508*9880d681SAndroid Build Coastguard Worker}
509*9880d681SAndroid Build Coastguard Worker
510*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_one:
511*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
512*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
513*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, pl
514*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, le
515*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi
516*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
517*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_one(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
518*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt double %v0, %v1
519*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp one double %v2, %v3
520*9880d681SAndroid Build Coastguard Worker  %cr = or i1 %c1, %c0
521*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
522*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
523*9880d681SAndroid Build Coastguard Worker}
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_one_olt:
526*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
527*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
528*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #1, ne
529*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, vs
530*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi
531*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
532*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_one_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
533*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp one double %v0, %v1
534*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp olt double %v2, %v3
535*9880d681SAndroid Build Coastguard Worker  %cr = or i1 %c1, %c0
536*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
537*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
538*9880d681SAndroid Build Coastguard Worker}
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_ueq:
541*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
542*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
543*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #4, pl
544*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #1, ne
545*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vs
546*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
547*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_ueq(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
548*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt double %v0, %v1
549*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp ueq double %v2, %v3
550*9880d681SAndroid Build Coastguard Worker  %cr = or i1 %c1, %c0
551*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
552*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
553*9880d681SAndroid Build Coastguard Worker}
554*9880d681SAndroid Build Coastguard Worker
555*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_ueq_olt:
556*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
557*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
558*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d0, d1, #8, le
559*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #8, mi
560*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, mi
561*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
562*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_ueq_olt(double %v0, double %v1, double %v2, double %v3, i32 %a, i32 %b) #0 {
563*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp ueq double %v0, %v1
564*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp olt double %v2, %v3
565*9880d681SAndroid Build Coastguard Worker  %cr = or i1 %c1, %c0
566*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
567*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
568*9880d681SAndroid Build Coastguard Worker}
569*9880d681SAndroid Build Coastguard Worker
570*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_ogt_ueq:
571*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
572*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
573*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #0, pl
574*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d4, d5, #4, le
575*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d4, d5, #1, ne
576*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vs
577*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
578*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_ogt_ueq(double %v0, double %v1, double %v2, double %v3, double %v4, double %v5, i32 %a, i32 %b) #0 {
579*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt double %v0, %v1
580*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp ogt double %v2, %v3
581*9880d681SAndroid Build Coastguard Worker  %c2 = fcmp ueq double %v4, %v5
582*9880d681SAndroid Build Coastguard Worker  %c3 = or i1 %c1, %c0
583*9880d681SAndroid Build Coastguard Worker  %cr = or i1 %c2, %c3
584*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
585*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
586*9880d681SAndroid Build Coastguard Worker}
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: select_or_olt_ueq_ogt:
589*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
590*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp d0, d1
591*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #4, pl
592*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d2, d3, #1, ne
593*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp d4, d5, #0, vc
594*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, gt
595*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
596*9880d681SAndroid Build Coastguard Workerdefine i32 @select_or_olt_ueq_ogt(double %v0, double %v1, double %v2, double %v3, double %v4, double %v5, i32 %a, i32 %b) #0 {
597*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt double %v0, %v1
598*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp ueq double %v2, %v3
599*9880d681SAndroid Build Coastguard Worker  %c2 = fcmp ogt double %v4, %v5
600*9880d681SAndroid Build Coastguard Worker  %c3 = or i1 %c1, %c0
601*9880d681SAndroid Build Coastguard Worker  %cr = or i1 %c2, %c3
602*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
603*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
604*9880d681SAndroid Build Coastguard Worker}
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Worker; Verify that we correctly promote f16.
607*9880d681SAndroid Build Coastguard Worker
608*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: half_select_and_olt_oge:
609*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
610*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S0:s[0-9]+]], h0
611*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S1:s[0-9]+]], h1
612*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp [[S0]], [[S1]]
613*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S2:s[0-9]+]], h2
614*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S3:s[0-9]+]], h3
615*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp [[S2]], [[S3]], #8, mi
616*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, ge
617*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
618*9880d681SAndroid Build Coastguard Workerdefine i32 @half_select_and_olt_oge(half %v0, half %v1, half %v2, half %v3, i32 %a, i32 %b) #0 {
619*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt half %v0, %v1
620*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp oge half %v2, %v3
621*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
622*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
623*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
624*9880d681SAndroid Build Coastguard Worker}
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: half_select_and_olt_one:
627*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: ; BB#0:
628*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S0:s[0-9]+]], h0
629*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S1:s[0-9]+]], h1
630*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fcmp [[S0]], [[S1]]
631*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S2:s[0-9]+]], h2
632*9880d681SAndroid Build Coastguard Worker; CHECK-DAG:  fcvt [[S3:s[0-9]+]], h3
633*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp [[S2]], [[S3]], #4, mi
634*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: fccmp [[S2]], [[S3]], #1, ne
635*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel w0, w0, w1, vc
636*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
637*9880d681SAndroid Build Coastguard Workerdefine i32 @half_select_and_olt_one(half %v0, half %v1, half %v2, half %v3, i32 %a, i32 %b) #0 {
638*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt half %v0, %v1
639*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp one half %v2, %v3
640*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
641*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
642*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
643*9880d681SAndroid Build Coastguard Worker}
644*9880d681SAndroid Build Coastguard Worker
645*9880d681SAndroid Build Coastguard Worker; Also verify that we don't try to generate f128 FCCMPs, using RT calls instead.
646*9880d681SAndroid Build Coastguard Worker
647*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f128_select_and_olt_oge:
648*9880d681SAndroid Build Coastguard Worker; CHECK: bl ___lttf2
649*9880d681SAndroid Build Coastguard Worker; CHECK: bl ___getf2
650*9880d681SAndroid Build Coastguard Workerdefine i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3, i32 %a, i32 %b) #0 {
651*9880d681SAndroid Build Coastguard Worker  %c0 = fcmp olt fp128 %v0, %v1
652*9880d681SAndroid Build Coastguard Worker  %c1 = fcmp oge fp128 %v2, %v3
653*9880d681SAndroid Build Coastguard Worker  %cr = and i1 %c1, %c0
654*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %cr, i32 %a, i32 %b
655*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
656*9880d681SAndroid Build Coastguard Worker}
657*9880d681SAndroid Build Coastguard Worker
658*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind }
659