1; RUN: llc < %s -march=arm64 -mcpu=cyclone -aarch64-neon-syntax=apple | FileCheck %s
2; rdar://10263824
3
4define i1 @fcmp_float1(float %a) nounwind ssp {
5entry:
6; CHECK-LABEL: @fcmp_float1
7; CHECK: fcmp s0, #0.0
8; CHECK: cset w0, ne
9  %cmp = fcmp une float %a, 0.000000e+00
10  ret i1 %cmp
11}
12
13define i1 @fcmp_float2(float %a, float %b) nounwind ssp {
14entry:
15; CHECK-LABEL: @fcmp_float2
16; CHECK: fcmp s0, s1
17; CHECK: cset w0, ne
18  %cmp = fcmp une float %a, %b
19  ret i1 %cmp
20}
21
22define i1 @fcmp_double1(double %a) nounwind ssp {
23entry:
24; CHECK-LABEL: @fcmp_double1
25; CHECK: fcmp d0, #0.0
26; CHECK: cset w0, ne
27  %cmp = fcmp une double %a, 0.000000e+00
28  ret i1 %cmp
29}
30
31define i1 @fcmp_double2(double %a, double %b) nounwind ssp {
32entry:
33; CHECK-LABEL: @fcmp_double2
34; CHECK: fcmp d0, d1
35; CHECK: cset w0, ne
36  %cmp = fcmp une double %a, %b
37  ret i1 %cmp
38}
39
40; Check each fcmp condition
41define float @fcmp_oeq(float %a, float %b) nounwind ssp {
42; CHECK-LABEL: @fcmp_oeq
43; CHECK: fcmp s0, s1
44; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
45; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
46; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], eq
47
48  %cmp = fcmp oeq float %a, %b
49  %conv = uitofp i1 %cmp to float
50  ret float %conv
51}
52
53define float @fcmp_ogt(float %a, float %b) nounwind ssp {
54; CHECK-LABEL: @fcmp_ogt
55; CHECK: fcmp s0, s1
56; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
57; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
58; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], gt
59
60  %cmp = fcmp ogt float %a, %b
61  %conv = uitofp i1 %cmp to float
62  ret float %conv
63}
64
65define float @fcmp_oge(float %a, float %b) nounwind ssp {
66; CHECK-LABEL: @fcmp_oge
67; CHECK: fcmp s0, s1
68; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
69; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
70; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], ge
71
72  %cmp = fcmp oge float %a, %b
73  %conv = uitofp i1 %cmp to float
74  ret float %conv
75}
76
77define float @fcmp_olt(float %a, float %b) nounwind ssp {
78; CHECK-LABEL: @fcmp_olt
79; CHECK: fcmp s0, s1
80; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
81; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
82; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], mi
83
84  %cmp = fcmp olt float %a, %b
85  %conv = uitofp i1 %cmp to float
86  ret float %conv
87}
88
89define float @fcmp_ole(float %a, float %b) nounwind ssp {
90; CHECK-LABEL: @fcmp_ole
91; CHECK: fcmp s0, s1
92; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
93; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
94; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], ls
95
96  %cmp = fcmp ole float %a, %b
97  %conv = uitofp i1 %cmp to float
98  ret float %conv
99}
100
101define float @fcmp_ord(float %a, float %b) nounwind ssp {
102; CHECK-LABEL: @fcmp_ord
103; CHECK: fcmp s0, s1
104; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
105; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
106; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], vc
107  %cmp = fcmp ord float %a, %b
108  %conv = uitofp i1 %cmp to float
109  ret float %conv
110}
111
112define float @fcmp_uno(float %a, float %b) nounwind ssp {
113; CHECK-LABEL: @fcmp_uno
114; CHECK: fcmp s0, s1
115; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
116; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
117; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], vs
118  %cmp = fcmp uno float %a, %b
119  %conv = uitofp i1 %cmp to float
120  ret float %conv
121}
122
123define float @fcmp_ugt(float %a, float %b) nounwind ssp {
124; CHECK-LABEL: @fcmp_ugt
125; CHECK: fcmp s0, s1
126; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
127; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
128; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], hi
129  %cmp = fcmp ugt float %a, %b
130  %conv = uitofp i1 %cmp to float
131  ret float %conv
132}
133
134define float @fcmp_uge(float %a, float %b) nounwind ssp {
135; CHECK-LABEL: @fcmp_uge
136; CHECK: fcmp s0, s1
137; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
138; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
139; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], pl
140  %cmp = fcmp uge float %a, %b
141  %conv = uitofp i1 %cmp to float
142  ret float %conv
143}
144
145define float @fcmp_ult(float %a, float %b) nounwind ssp {
146; CHECK-LABEL: @fcmp_ult
147; CHECK: fcmp s0, s1
148; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
149; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
150; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], lt
151  %cmp = fcmp ult float %a, %b
152  %conv = uitofp i1 %cmp to float
153  ret float %conv
154}
155
156define float @fcmp_ule(float %a, float %b) nounwind ssp {
157; CHECK-LABEL: @fcmp_ule
158; CHECK: fcmp s0, s1
159; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
160; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
161; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], le
162  %cmp = fcmp ule float %a, %b
163  %conv = uitofp i1 %cmp to float
164  ret float %conv
165}
166
167define float @fcmp_une(float %a, float %b) nounwind ssp {
168; CHECK-LABEL: @fcmp_une
169; CHECK: fcmp s0, s1
170; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
171; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
172; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], ne
173  %cmp = fcmp une float %a, %b
174  %conv = uitofp i1 %cmp to float
175  ret float %conv
176}
177
178; Possible opportunity for improvement.  See comment in
179; ARM64TargetLowering::LowerSETCC()
180define float @fcmp_one(float %a, float %b) nounwind ssp {
181; CHECK-LABEL: @fcmp_one
182;	fcmp	s0, s1
183; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
184; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
185; CHECK: fcsel [[TMP:s[0-9]+]], s[[ONE]], s[[ZERO]], mi
186; CHECK: fcsel s0, s[[ONE]], [[TMP]], gt
187  %cmp = fcmp one float %a, %b
188  %conv = uitofp i1 %cmp to float
189  ret float %conv
190}
191
192; Possible opportunity for improvement.  See comment in
193; ARM64TargetLowering::LowerSETCC()
194define float @fcmp_ueq(float %a, float %b) nounwind ssp {
195; CHECK-LABEL: @fcmp_ueq
196; CHECK: fcmp s0, s1
197; CHECK-DAG: movi.2d v[[ZERO:[0-9]+]], #0
198; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0
199; CHECK: fcsel [[TMP:s[0-9]+]], s[[ONE]], s[[ZERO]], eq
200; CHECK: fcsel s0, s[[ONE]], [[TMP]], vs
201  %cmp = fcmp ueq float %a, %b
202  %conv = uitofp i1 %cmp to float
203  ret float %conv
204}
205