[FastISel][AArch64] Optimize compare-and-branch for i1 to use 'tbz'.
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-fcmp-opt.ll
1 ; RUN: llc < %s -march=arm64 -mcpu=cyclone -aarch64-neon-syntax=apple | FileCheck %s
2 ; rdar://10263824
3
4 define i1 @fcmp_float1(float %a) nounwind ssp {
5 entry:
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
13 define i1 @fcmp_float2(float %a, float %b) nounwind ssp {
14 entry:
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
22 define i1 @fcmp_double1(double %a) nounwind ssp {
23 entry:
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
31 define i1 @fcmp_double2(double %a, double %b) nounwind ssp {
32 entry:
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
41 define 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
53 define 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
65 define 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
77 define 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
89 define 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
101 define 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
112 define 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
123 define 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
134 define 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
145 define 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
156 define 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
167 define 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()
180 define 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()
194 define 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 }