• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefix=RV32IF %s
4
5define float @select_fcmp_false(float %a, float %b) nounwind {
6; RV32IF-LABEL: select_fcmp_false:
7; RV32IF:       # %bb.0:
8; RV32IF-NEXT:    mv a0, a1
9; RV32IF-NEXT:    ret
10  %1 = fcmp false float %a, %b
11  %2 = select i1 %1, float %a, float %b
12  ret float %2
13}
14
15define float @select_fcmp_oeq(float %a, float %b) nounwind {
16; RV32IF-LABEL: select_fcmp_oeq:
17; RV32IF:       # %bb.0:
18; RV32IF-NEXT:    fmv.w.x ft1, a1
19; RV32IF-NEXT:    fmv.w.x ft0, a0
20; RV32IF-NEXT:    feq.s a0, ft0, ft1
21; RV32IF-NEXT:    bnez a0, .LBB1_2
22; RV32IF-NEXT:  # %bb.1:
23; RV32IF-NEXT:    fmv.s ft0, ft1
24; RV32IF-NEXT:  .LBB1_2:
25; RV32IF-NEXT:    fmv.x.w a0, ft0
26; RV32IF-NEXT:    ret
27  %1 = fcmp oeq float %a, %b
28  %2 = select i1 %1, float %a, float %b
29  ret float %2
30}
31
32define float @select_fcmp_ogt(float %a, float %b) nounwind {
33; RV32IF-LABEL: select_fcmp_ogt:
34; RV32IF:       # %bb.0:
35; RV32IF-NEXT:    fmv.w.x ft0, a0
36; RV32IF-NEXT:    fmv.w.x ft1, a1
37; RV32IF-NEXT:    flt.s a0, ft1, ft0
38; RV32IF-NEXT:    bnez a0, .LBB2_2
39; RV32IF-NEXT:  # %bb.1:
40; RV32IF-NEXT:    fmv.s ft0, ft1
41; RV32IF-NEXT:  .LBB2_2:
42; RV32IF-NEXT:    fmv.x.w a0, ft0
43; RV32IF-NEXT:    ret
44  %1 = fcmp ogt float %a, %b
45  %2 = select i1 %1, float %a, float %b
46  ret float %2
47}
48
49define float @select_fcmp_oge(float %a, float %b) nounwind {
50; RV32IF-LABEL: select_fcmp_oge:
51; RV32IF:       # %bb.0:
52; RV32IF-NEXT:    fmv.w.x ft0, a0
53; RV32IF-NEXT:    fmv.w.x ft1, a1
54; RV32IF-NEXT:    fle.s a0, ft1, ft0
55; RV32IF-NEXT:    bnez a0, .LBB3_2
56; RV32IF-NEXT:  # %bb.1:
57; RV32IF-NEXT:    fmv.s ft0, ft1
58; RV32IF-NEXT:  .LBB3_2:
59; RV32IF-NEXT:    fmv.x.w a0, ft0
60; RV32IF-NEXT:    ret
61  %1 = fcmp oge float %a, %b
62  %2 = select i1 %1, float %a, float %b
63  ret float %2
64}
65
66define float @select_fcmp_olt(float %a, float %b) nounwind {
67; RV32IF-LABEL: select_fcmp_olt:
68; RV32IF:       # %bb.0:
69; RV32IF-NEXT:    fmv.w.x ft1, a1
70; RV32IF-NEXT:    fmv.w.x ft0, a0
71; RV32IF-NEXT:    flt.s a0, ft0, ft1
72; RV32IF-NEXT:    bnez a0, .LBB4_2
73; RV32IF-NEXT:  # %bb.1:
74; RV32IF-NEXT:    fmv.s ft0, ft1
75; RV32IF-NEXT:  .LBB4_2:
76; RV32IF-NEXT:    fmv.x.w a0, ft0
77; RV32IF-NEXT:    ret
78  %1 = fcmp olt float %a, %b
79  %2 = select i1 %1, float %a, float %b
80  ret float %2
81}
82
83define float @select_fcmp_ole(float %a, float %b) nounwind {
84; RV32IF-LABEL: select_fcmp_ole:
85; RV32IF:       # %bb.0:
86; RV32IF-NEXT:    fmv.w.x ft1, a1
87; RV32IF-NEXT:    fmv.w.x ft0, a0
88; RV32IF-NEXT:    fle.s a0, ft0, ft1
89; RV32IF-NEXT:    bnez a0, .LBB5_2
90; RV32IF-NEXT:  # %bb.1:
91; RV32IF-NEXT:    fmv.s ft0, ft1
92; RV32IF-NEXT:  .LBB5_2:
93; RV32IF-NEXT:    fmv.x.w a0, ft0
94; RV32IF-NEXT:    ret
95  %1 = fcmp ole float %a, %b
96  %2 = select i1 %1, float %a, float %b
97  ret float %2
98}
99
100define float @select_fcmp_one(float %a, float %b) nounwind {
101; TODO: feq.s+sltiu+bne sequence could be optimised
102; RV32IF-LABEL: select_fcmp_one:
103; RV32IF:       # %bb.0:
104; RV32IF-NEXT:    fmv.w.x ft0, a0
105; RV32IF-NEXT:    fmv.w.x ft1, a1
106; RV32IF-NEXT:    feq.s a0, ft1, ft1
107; RV32IF-NEXT:    feq.s a1, ft0, ft0
108; RV32IF-NEXT:    and a0, a1, a0
109; RV32IF-NEXT:    feq.s a1, ft0, ft1
110; RV32IF-NEXT:    not a1, a1
111; RV32IF-NEXT:    seqz a0, a0
112; RV32IF-NEXT:    xori a0, a0, 1
113; RV32IF-NEXT:    and a0, a1, a0
114; RV32IF-NEXT:    bnez a0, .LBB6_2
115; RV32IF-NEXT:  # %bb.1:
116; RV32IF-NEXT:    fmv.s ft0, ft1
117; RV32IF-NEXT:  .LBB6_2:
118; RV32IF-NEXT:    fmv.x.w a0, ft0
119; RV32IF-NEXT:    ret
120  %1 = fcmp one float %a, %b
121  %2 = select i1 %1, float %a, float %b
122  ret float %2
123}
124
125define float @select_fcmp_ord(float %a, float %b) nounwind {
126; RV32IF-LABEL: select_fcmp_ord:
127; RV32IF:       # %bb.0:
128; RV32IF-NEXT:    fmv.w.x ft0, a0
129; RV32IF-NEXT:    fmv.w.x ft1, a1
130; RV32IF-NEXT:    feq.s a0, ft1, ft1
131; RV32IF-NEXT:    feq.s a1, ft0, ft0
132; RV32IF-NEXT:    and a0, a1, a0
133; RV32IF-NEXT:    seqz a0, a0
134; RV32IF-NEXT:    xori a0, a0, 1
135; RV32IF-NEXT:    bnez a0, .LBB7_2
136; RV32IF-NEXT:  # %bb.1:
137; RV32IF-NEXT:    fmv.s ft0, ft1
138; RV32IF-NEXT:  .LBB7_2:
139; RV32IF-NEXT:    fmv.x.w a0, ft0
140; RV32IF-NEXT:    ret
141  %1 = fcmp ord float %a, %b
142  %2 = select i1 %1, float %a, float %b
143  ret float %2
144}
145
146define float @select_fcmp_ueq(float %a, float %b) nounwind {
147; RV32IF-LABEL: select_fcmp_ueq:
148; RV32IF:       # %bb.0:
149; RV32IF-NEXT:    fmv.w.x ft0, a0
150; RV32IF-NEXT:    fmv.w.x ft1, a1
151; RV32IF-NEXT:    feq.s a0, ft1, ft1
152; RV32IF-NEXT:    feq.s a1, ft0, ft0
153; RV32IF-NEXT:    and a0, a1, a0
154; RV32IF-NEXT:    seqz a0, a0
155; RV32IF-NEXT:    feq.s a1, ft0, ft1
156; RV32IF-NEXT:    or a0, a1, a0
157; RV32IF-NEXT:    bnez a0, .LBB8_2
158; RV32IF-NEXT:  # %bb.1:
159; RV32IF-NEXT:    fmv.s ft0, ft1
160; RV32IF-NEXT:  .LBB8_2:
161; RV32IF-NEXT:    fmv.x.w a0, ft0
162; RV32IF-NEXT:    ret
163  %1 = fcmp ueq float %a, %b
164  %2 = select i1 %1, float %a, float %b
165  ret float %2
166}
167
168define float @select_fcmp_ugt(float %a, float %b) nounwind {
169; RV32IF-LABEL: select_fcmp_ugt:
170; RV32IF:       # %bb.0:
171; RV32IF-NEXT:    fmv.w.x ft1, a1
172; RV32IF-NEXT:    fmv.w.x ft0, a0
173; RV32IF-NEXT:    fle.s a0, ft0, ft1
174; RV32IF-NEXT:    xori a0, a0, 1
175; RV32IF-NEXT:    bnez a0, .LBB9_2
176; RV32IF-NEXT:  # %bb.1:
177; RV32IF-NEXT:    fmv.s ft0, ft1
178; RV32IF-NEXT:  .LBB9_2:
179; RV32IF-NEXT:    fmv.x.w a0, ft0
180; RV32IF-NEXT:    ret
181  %1 = fcmp ugt float %a, %b
182  %2 = select i1 %1, float %a, float %b
183  ret float %2
184}
185
186define float @select_fcmp_uge(float %a, float %b) nounwind {
187; RV32IF-LABEL: select_fcmp_uge:
188; RV32IF:       # %bb.0:
189; RV32IF-NEXT:    fmv.w.x ft1, a1
190; RV32IF-NEXT:    fmv.w.x ft0, a0
191; RV32IF-NEXT:    flt.s a0, ft0, ft1
192; RV32IF-NEXT:    xori a0, a0, 1
193; RV32IF-NEXT:    bnez a0, .LBB10_2
194; RV32IF-NEXT:  # %bb.1:
195; RV32IF-NEXT:    fmv.s ft0, ft1
196; RV32IF-NEXT:  .LBB10_2:
197; RV32IF-NEXT:    fmv.x.w a0, ft0
198; RV32IF-NEXT:    ret
199  %1 = fcmp uge float %a, %b
200  %2 = select i1 %1, float %a, float %b
201  ret float %2
202}
203
204define float @select_fcmp_ult(float %a, float %b) nounwind {
205; RV32IF-LABEL: select_fcmp_ult:
206; RV32IF:       # %bb.0:
207; RV32IF-NEXT:    fmv.w.x ft0, a0
208; RV32IF-NEXT:    fmv.w.x ft1, a1
209; RV32IF-NEXT:    fle.s a0, ft1, ft0
210; RV32IF-NEXT:    xori a0, a0, 1
211; RV32IF-NEXT:    bnez a0, .LBB11_2
212; RV32IF-NEXT:  # %bb.1:
213; RV32IF-NEXT:    fmv.s ft0, ft1
214; RV32IF-NEXT:  .LBB11_2:
215; RV32IF-NEXT:    fmv.x.w a0, ft0
216; RV32IF-NEXT:    ret
217  %1 = fcmp ult float %a, %b
218  %2 = select i1 %1, float %a, float %b
219  ret float %2
220}
221
222define float @select_fcmp_ule(float %a, float %b) nounwind {
223; RV32IF-LABEL: select_fcmp_ule:
224; RV32IF:       # %bb.0:
225; RV32IF-NEXT:    fmv.w.x ft0, a0
226; RV32IF-NEXT:    fmv.w.x ft1, a1
227; RV32IF-NEXT:    flt.s a0, ft1, ft0
228; RV32IF-NEXT:    xori a0, a0, 1
229; RV32IF-NEXT:    bnez a0, .LBB12_2
230; RV32IF-NEXT:  # %bb.1:
231; RV32IF-NEXT:    fmv.s ft0, ft1
232; RV32IF-NEXT:  .LBB12_2:
233; RV32IF-NEXT:    fmv.x.w a0, ft0
234; RV32IF-NEXT:    ret
235  %1 = fcmp ule float %a, %b
236  %2 = select i1 %1, float %a, float %b
237  ret float %2
238}
239
240define float @select_fcmp_une(float %a, float %b) nounwind {
241; RV32IF-LABEL: select_fcmp_une:
242; RV32IF:       # %bb.0:
243; RV32IF-NEXT:    fmv.w.x ft1, a1
244; RV32IF-NEXT:    fmv.w.x ft0, a0
245; RV32IF-NEXT:    feq.s a0, ft0, ft1
246; RV32IF-NEXT:    xori a0, a0, 1
247; RV32IF-NEXT:    bnez a0, .LBB13_2
248; RV32IF-NEXT:  # %bb.1:
249; RV32IF-NEXT:    fmv.s ft0, ft1
250; RV32IF-NEXT:  .LBB13_2:
251; RV32IF-NEXT:    fmv.x.w a0, ft0
252; RV32IF-NEXT:    ret
253  %1 = fcmp une float %a, %b
254  %2 = select i1 %1, float %a, float %b
255  ret float %2
256}
257
258define float @select_fcmp_uno(float %a, float %b) nounwind {
259; TODO: sltiu+bne could be optimized
260; RV32IF-LABEL: select_fcmp_uno:
261; RV32IF:       # %bb.0:
262; RV32IF-NEXT:    fmv.w.x ft0, a0
263; RV32IF-NEXT:    fmv.w.x ft1, a1
264; RV32IF-NEXT:    feq.s a0, ft1, ft1
265; RV32IF-NEXT:    feq.s a1, ft0, ft0
266; RV32IF-NEXT:    and a0, a1, a0
267; RV32IF-NEXT:    seqz a0, a0
268; RV32IF-NEXT:    bnez a0, .LBB14_2
269; RV32IF-NEXT:  # %bb.1:
270; RV32IF-NEXT:    fmv.s ft0, ft1
271; RV32IF-NEXT:  .LBB14_2:
272; RV32IF-NEXT:    fmv.x.w a0, ft0
273; RV32IF-NEXT:    ret
274  %1 = fcmp uno float %a, %b
275  %2 = select i1 %1, float %a, float %b
276  ret float %2
277}
278
279define float @select_fcmp_true(float %a, float %b) nounwind {
280; RV32IF-LABEL: select_fcmp_true:
281; RV32IF:       # %bb.0:
282; RV32IF-NEXT:    ret
283  %1 = fcmp true float %a, %b
284  %2 = select i1 %1, float %a, float %b
285  ret float %2
286}
287
288; Ensure that ISel succeeds for a select+fcmp that has an i32 result type.
289define i32 @i32_select_fcmp_oeq(float %a, float %b, i32 %c, i32 %d) nounwind {
290; RV32IF-LABEL: i32_select_fcmp_oeq:
291; RV32IF:       # %bb.0:
292; RV32IF-NEXT:    fmv.w.x ft0, a1
293; RV32IF-NEXT:    fmv.w.x ft1, a0
294; RV32IF-NEXT:    feq.s a0, ft1, ft0
295; RV32IF-NEXT:    bnez a0, .LBB16_2
296; RV32IF-NEXT:  # %bb.1:
297; RV32IF-NEXT:    mv a2, a3
298; RV32IF-NEXT:  .LBB16_2:
299; RV32IF-NEXT:    mv a0, a2
300; RV32IF-NEXT:    ret
301  %1 = fcmp oeq float %a, %b
302  %2 = select i1 %1, i32 %c, i32 %d
303  ret i32 %2
304}
305