1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefix=RV32IFD %s
4
5define double @select_fcmp_false(double %a, double %b) nounwind {
6; RV32IFD-LABEL: select_fcmp_false:
7; RV32IFD:       # %bb.0:
8; RV32IFD-NEXT:    mv a0, a2
9; RV32IFD-NEXT:    mv a1, a3
10; RV32IFD-NEXT:    ret
11  %1 = fcmp false double %a, %b
12  %2 = select i1 %1, double %a, double %b
13  ret double %2
14}
15
16define double @select_fcmp_oeq(double %a, double %b) nounwind {
17; RV32IFD-LABEL: select_fcmp_oeq:
18; RV32IFD:       # %bb.0:
19; RV32IFD-NEXT:    addi sp, sp, -16
20; RV32IFD-NEXT:    sw a2, 8(sp)
21; RV32IFD-NEXT:    sw a3, 12(sp)
22; RV32IFD-NEXT:    fld ft0, 8(sp)
23; RV32IFD-NEXT:    sw a0, 8(sp)
24; RV32IFD-NEXT:    sw a1, 12(sp)
25; RV32IFD-NEXT:    fld ft1, 8(sp)
26; RV32IFD-NEXT:    feq.d a0, ft1, ft0
27; RV32IFD-NEXT:    bnez a0, .LBB1_2
28; RV32IFD-NEXT:  # %bb.1:
29; RV32IFD-NEXT:    fmv.d ft1, ft0
30; RV32IFD-NEXT:  .LBB1_2:
31; RV32IFD-NEXT:    fsd ft1, 8(sp)
32; RV32IFD-NEXT:    lw a0, 8(sp)
33; RV32IFD-NEXT:    lw a1, 12(sp)
34; RV32IFD-NEXT:    addi sp, sp, 16
35; RV32IFD-NEXT:    ret
36  %1 = fcmp oeq double %a, %b
37  %2 = select i1 %1, double %a, double %b
38  ret double %2
39}
40
41define double @select_fcmp_ogt(double %a, double %b) nounwind {
42; RV32IFD-LABEL: select_fcmp_ogt:
43; RV32IFD:       # %bb.0:
44; RV32IFD-NEXT:    addi sp, sp, -16
45; RV32IFD-NEXT:    sw a0, 8(sp)
46; RV32IFD-NEXT:    sw a1, 12(sp)
47; RV32IFD-NEXT:    fld ft0, 8(sp)
48; RV32IFD-NEXT:    sw a2, 8(sp)
49; RV32IFD-NEXT:    sw a3, 12(sp)
50; RV32IFD-NEXT:    fld ft1, 8(sp)
51; RV32IFD-NEXT:    flt.d a0, ft1, ft0
52; RV32IFD-NEXT:    bnez a0, .LBB2_2
53; RV32IFD-NEXT:  # %bb.1:
54; RV32IFD-NEXT:    fmv.d ft0, ft1
55; RV32IFD-NEXT:  .LBB2_2:
56; RV32IFD-NEXT:    fsd ft0, 8(sp)
57; RV32IFD-NEXT:    lw a0, 8(sp)
58; RV32IFD-NEXT:    lw a1, 12(sp)
59; RV32IFD-NEXT:    addi sp, sp, 16
60; RV32IFD-NEXT:    ret
61  %1 = fcmp ogt double %a, %b
62  %2 = select i1 %1, double %a, double %b
63  ret double %2
64}
65
66define double @select_fcmp_oge(double %a, double %b) nounwind {
67; RV32IFD-LABEL: select_fcmp_oge:
68; RV32IFD:       # %bb.0:
69; RV32IFD-NEXT:    addi sp, sp, -16
70; RV32IFD-NEXT:    sw a0, 8(sp)
71; RV32IFD-NEXT:    sw a1, 12(sp)
72; RV32IFD-NEXT:    fld ft0, 8(sp)
73; RV32IFD-NEXT:    sw a2, 8(sp)
74; RV32IFD-NEXT:    sw a3, 12(sp)
75; RV32IFD-NEXT:    fld ft1, 8(sp)
76; RV32IFD-NEXT:    fle.d a0, ft1, ft0
77; RV32IFD-NEXT:    bnez a0, .LBB3_2
78; RV32IFD-NEXT:  # %bb.1:
79; RV32IFD-NEXT:    fmv.d ft0, ft1
80; RV32IFD-NEXT:  .LBB3_2:
81; RV32IFD-NEXT:    fsd ft0, 8(sp)
82; RV32IFD-NEXT:    lw a0, 8(sp)
83; RV32IFD-NEXT:    lw a1, 12(sp)
84; RV32IFD-NEXT:    addi sp, sp, 16
85; RV32IFD-NEXT:    ret
86  %1 = fcmp oge double %a, %b
87  %2 = select i1 %1, double %a, double %b
88  ret double %2
89}
90
91define double @select_fcmp_olt(double %a, double %b) nounwind {
92; RV32IFD-LABEL: select_fcmp_olt:
93; RV32IFD:       # %bb.0:
94; RV32IFD-NEXT:    addi sp, sp, -16
95; RV32IFD-NEXT:    sw a2, 8(sp)
96; RV32IFD-NEXT:    sw a3, 12(sp)
97; RV32IFD-NEXT:    fld ft0, 8(sp)
98; RV32IFD-NEXT:    sw a0, 8(sp)
99; RV32IFD-NEXT:    sw a1, 12(sp)
100; RV32IFD-NEXT:    fld ft1, 8(sp)
101; RV32IFD-NEXT:    flt.d a0, ft1, ft0
102; RV32IFD-NEXT:    bnez a0, .LBB4_2
103; RV32IFD-NEXT:  # %bb.1:
104; RV32IFD-NEXT:    fmv.d ft1, ft0
105; RV32IFD-NEXT:  .LBB4_2:
106; RV32IFD-NEXT:    fsd ft1, 8(sp)
107; RV32IFD-NEXT:    lw a0, 8(sp)
108; RV32IFD-NEXT:    lw a1, 12(sp)
109; RV32IFD-NEXT:    addi sp, sp, 16
110; RV32IFD-NEXT:    ret
111  %1 = fcmp olt double %a, %b
112  %2 = select i1 %1, double %a, double %b
113  ret double %2
114}
115
116define double @select_fcmp_ole(double %a, double %b) nounwind {
117; RV32IFD-LABEL: select_fcmp_ole:
118; RV32IFD:       # %bb.0:
119; RV32IFD-NEXT:    addi sp, sp, -16
120; RV32IFD-NEXT:    sw a2, 8(sp)
121; RV32IFD-NEXT:    sw a3, 12(sp)
122; RV32IFD-NEXT:    fld ft0, 8(sp)
123; RV32IFD-NEXT:    sw a0, 8(sp)
124; RV32IFD-NEXT:    sw a1, 12(sp)
125; RV32IFD-NEXT:    fld ft1, 8(sp)
126; RV32IFD-NEXT:    fle.d a0, ft1, ft0
127; RV32IFD-NEXT:    bnez a0, .LBB5_2
128; RV32IFD-NEXT:  # %bb.1:
129; RV32IFD-NEXT:    fmv.d ft1, ft0
130; RV32IFD-NEXT:  .LBB5_2:
131; RV32IFD-NEXT:    fsd ft1, 8(sp)
132; RV32IFD-NEXT:    lw a0, 8(sp)
133; RV32IFD-NEXT:    lw a1, 12(sp)
134; RV32IFD-NEXT:    addi sp, sp, 16
135; RV32IFD-NEXT:    ret
136  %1 = fcmp ole double %a, %b
137  %2 = select i1 %1, double %a, double %b
138  ret double %2
139}
140
141define double @select_fcmp_one(double %a, double %b) nounwind {
142; TODO: feq.s+sltiu+bne sequence could be optimised
143; RV32IFD-LABEL: select_fcmp_one:
144; RV32IFD:       # %bb.0:
145; RV32IFD-NEXT:    addi sp, sp, -16
146; RV32IFD-NEXT:    sw a0, 8(sp)
147; RV32IFD-NEXT:    sw a1, 12(sp)
148; RV32IFD-NEXT:    fld ft0, 8(sp)
149; RV32IFD-NEXT:    sw a2, 8(sp)
150; RV32IFD-NEXT:    sw a3, 12(sp)
151; RV32IFD-NEXT:    fld ft1, 8(sp)
152; RV32IFD-NEXT:    feq.d a0, ft1, ft1
153; RV32IFD-NEXT:    feq.d a1, ft0, ft0
154; RV32IFD-NEXT:    and a0, a1, a0
155; RV32IFD-NEXT:    feq.d a1, ft0, ft1
156; RV32IFD-NEXT:    not a1, a1
157; RV32IFD-NEXT:    seqz a0, a0
158; RV32IFD-NEXT:    xori a0, a0, 1
159; RV32IFD-NEXT:    and a0, a1, a0
160; RV32IFD-NEXT:    bnez a0, .LBB6_2
161; RV32IFD-NEXT:  # %bb.1:
162; RV32IFD-NEXT:    fmv.d ft0, ft1
163; RV32IFD-NEXT:  .LBB6_2:
164; RV32IFD-NEXT:    fsd ft0, 8(sp)
165; RV32IFD-NEXT:    lw a0, 8(sp)
166; RV32IFD-NEXT:    lw a1, 12(sp)
167; RV32IFD-NEXT:    addi sp, sp, 16
168; RV32IFD-NEXT:    ret
169  %1 = fcmp one double %a, %b
170  %2 = select i1 %1, double %a, double %b
171  ret double %2
172}
173
174define double @select_fcmp_ord(double %a, double %b) nounwind {
175; RV32IFD-LABEL: select_fcmp_ord:
176; RV32IFD:       # %bb.0:
177; RV32IFD-NEXT:    addi sp, sp, -16
178; RV32IFD-NEXT:    sw a0, 8(sp)
179; RV32IFD-NEXT:    sw a1, 12(sp)
180; RV32IFD-NEXT:    fld ft0, 8(sp)
181; RV32IFD-NEXT:    sw a2, 8(sp)
182; RV32IFD-NEXT:    sw a3, 12(sp)
183; RV32IFD-NEXT:    fld ft1, 8(sp)
184; RV32IFD-NEXT:    feq.d a0, ft1, ft1
185; RV32IFD-NEXT:    feq.d a1, ft0, ft0
186; RV32IFD-NEXT:    and a0, a1, a0
187; RV32IFD-NEXT:    seqz a0, a0
188; RV32IFD-NEXT:    xori a0, a0, 1
189; RV32IFD-NEXT:    bnez a0, .LBB7_2
190; RV32IFD-NEXT:  # %bb.1:
191; RV32IFD-NEXT:    fmv.d ft0, ft1
192; RV32IFD-NEXT:  .LBB7_2:
193; RV32IFD-NEXT:    fsd ft0, 8(sp)
194; RV32IFD-NEXT:    lw a0, 8(sp)
195; RV32IFD-NEXT:    lw a1, 12(sp)
196; RV32IFD-NEXT:    addi sp, sp, 16
197; RV32IFD-NEXT:    ret
198  %1 = fcmp ord double %a, %b
199  %2 = select i1 %1, double %a, double %b
200  ret double %2
201}
202
203define double @select_fcmp_ueq(double %a, double %b) nounwind {
204; RV32IFD-LABEL: select_fcmp_ueq:
205; RV32IFD:       # %bb.0:
206; RV32IFD-NEXT:    addi sp, sp, -16
207; RV32IFD-NEXT:    sw a0, 8(sp)
208; RV32IFD-NEXT:    sw a1, 12(sp)
209; RV32IFD-NEXT:    fld ft0, 8(sp)
210; RV32IFD-NEXT:    sw a2, 8(sp)
211; RV32IFD-NEXT:    sw a3, 12(sp)
212; RV32IFD-NEXT:    fld ft1, 8(sp)
213; RV32IFD-NEXT:    feq.d a0, ft1, ft1
214; RV32IFD-NEXT:    feq.d a1, ft0, ft0
215; RV32IFD-NEXT:    and a0, a1, a0
216; RV32IFD-NEXT:    seqz a0, a0
217; RV32IFD-NEXT:    feq.d a1, ft0, ft1
218; RV32IFD-NEXT:    or a0, a1, a0
219; RV32IFD-NEXT:    bnez a0, .LBB8_2
220; RV32IFD-NEXT:  # %bb.1:
221; RV32IFD-NEXT:    fmv.d ft0, ft1
222; RV32IFD-NEXT:  .LBB8_2:
223; RV32IFD-NEXT:    fsd ft0, 8(sp)
224; RV32IFD-NEXT:    lw a0, 8(sp)
225; RV32IFD-NEXT:    lw a1, 12(sp)
226; RV32IFD-NEXT:    addi sp, sp, 16
227; RV32IFD-NEXT:    ret
228  %1 = fcmp ueq double %a, %b
229  %2 = select i1 %1, double %a, double %b
230  ret double %2
231}
232
233define double @select_fcmp_ugt(double %a, double %b) nounwind {
234; RV32IFD-LABEL: select_fcmp_ugt:
235; RV32IFD:       # %bb.0:
236; RV32IFD-NEXT:    addi sp, sp, -16
237; RV32IFD-NEXT:    sw a2, 8(sp)
238; RV32IFD-NEXT:    sw a3, 12(sp)
239; RV32IFD-NEXT:    fld ft0, 8(sp)
240; RV32IFD-NEXT:    sw a0, 8(sp)
241; RV32IFD-NEXT:    sw a1, 12(sp)
242; RV32IFD-NEXT:    fld ft1, 8(sp)
243; RV32IFD-NEXT:    fle.d a0, ft1, ft0
244; RV32IFD-NEXT:    xori a0, a0, 1
245; RV32IFD-NEXT:    bnez a0, .LBB9_2
246; RV32IFD-NEXT:  # %bb.1:
247; RV32IFD-NEXT:    fmv.d ft1, ft0
248; RV32IFD-NEXT:  .LBB9_2:
249; RV32IFD-NEXT:    fsd ft1, 8(sp)
250; RV32IFD-NEXT:    lw a0, 8(sp)
251; RV32IFD-NEXT:    lw a1, 12(sp)
252; RV32IFD-NEXT:    addi sp, sp, 16
253; RV32IFD-NEXT:    ret
254  %1 = fcmp ugt double %a, %b
255  %2 = select i1 %1, double %a, double %b
256  ret double %2
257}
258
259define double @select_fcmp_uge(double %a, double %b) nounwind {
260; RV32IFD-LABEL: select_fcmp_uge:
261; RV32IFD:       # %bb.0:
262; RV32IFD-NEXT:    addi sp, sp, -16
263; RV32IFD-NEXT:    sw a2, 8(sp)
264; RV32IFD-NEXT:    sw a3, 12(sp)
265; RV32IFD-NEXT:    fld ft0, 8(sp)
266; RV32IFD-NEXT:    sw a0, 8(sp)
267; RV32IFD-NEXT:    sw a1, 12(sp)
268; RV32IFD-NEXT:    fld ft1, 8(sp)
269; RV32IFD-NEXT:    flt.d a0, ft1, ft0
270; RV32IFD-NEXT:    xori a0, a0, 1
271; RV32IFD-NEXT:    bnez a0, .LBB10_2
272; RV32IFD-NEXT:  # %bb.1:
273; RV32IFD-NEXT:    fmv.d ft1, ft0
274; RV32IFD-NEXT:  .LBB10_2:
275; RV32IFD-NEXT:    fsd ft1, 8(sp)
276; RV32IFD-NEXT:    lw a0, 8(sp)
277; RV32IFD-NEXT:    lw a1, 12(sp)
278; RV32IFD-NEXT:    addi sp, sp, 16
279; RV32IFD-NEXT:    ret
280  %1 = fcmp uge double %a, %b
281  %2 = select i1 %1, double %a, double %b
282  ret double %2
283}
284
285define double @select_fcmp_ult(double %a, double %b) nounwind {
286; RV32IFD-LABEL: select_fcmp_ult:
287; RV32IFD:       # %bb.0:
288; RV32IFD-NEXT:    addi sp, sp, -16
289; RV32IFD-NEXT:    sw a0, 8(sp)
290; RV32IFD-NEXT:    sw a1, 12(sp)
291; RV32IFD-NEXT:    fld ft0, 8(sp)
292; RV32IFD-NEXT:    sw a2, 8(sp)
293; RV32IFD-NEXT:    sw a3, 12(sp)
294; RV32IFD-NEXT:    fld ft1, 8(sp)
295; RV32IFD-NEXT:    fle.d a0, ft1, ft0
296; RV32IFD-NEXT:    xori a0, a0, 1
297; RV32IFD-NEXT:    bnez a0, .LBB11_2
298; RV32IFD-NEXT:  # %bb.1:
299; RV32IFD-NEXT:    fmv.d ft0, ft1
300; RV32IFD-NEXT:  .LBB11_2:
301; RV32IFD-NEXT:    fsd ft0, 8(sp)
302; RV32IFD-NEXT:    lw a0, 8(sp)
303; RV32IFD-NEXT:    lw a1, 12(sp)
304; RV32IFD-NEXT:    addi sp, sp, 16
305; RV32IFD-NEXT:    ret
306  %1 = fcmp ult double %a, %b
307  %2 = select i1 %1, double %a, double %b
308  ret double %2
309}
310
311define double @select_fcmp_ule(double %a, double %b) nounwind {
312; RV32IFD-LABEL: select_fcmp_ule:
313; RV32IFD:       # %bb.0:
314; RV32IFD-NEXT:    addi sp, sp, -16
315; RV32IFD-NEXT:    sw a0, 8(sp)
316; RV32IFD-NEXT:    sw a1, 12(sp)
317; RV32IFD-NEXT:    fld ft0, 8(sp)
318; RV32IFD-NEXT:    sw a2, 8(sp)
319; RV32IFD-NEXT:    sw a3, 12(sp)
320; RV32IFD-NEXT:    fld ft1, 8(sp)
321; RV32IFD-NEXT:    flt.d a0, ft1, ft0
322; RV32IFD-NEXT:    xori a0, a0, 1
323; RV32IFD-NEXT:    bnez a0, .LBB12_2
324; RV32IFD-NEXT:  # %bb.1:
325; RV32IFD-NEXT:    fmv.d ft0, ft1
326; RV32IFD-NEXT:  .LBB12_2:
327; RV32IFD-NEXT:    fsd ft0, 8(sp)
328; RV32IFD-NEXT:    lw a0, 8(sp)
329; RV32IFD-NEXT:    lw a1, 12(sp)
330; RV32IFD-NEXT:    addi sp, sp, 16
331; RV32IFD-NEXT:    ret
332  %1 = fcmp ule double %a, %b
333  %2 = select i1 %1, double %a, double %b
334  ret double %2
335}
336
337define double @select_fcmp_une(double %a, double %b) nounwind {
338; RV32IFD-LABEL: select_fcmp_une:
339; RV32IFD:       # %bb.0:
340; RV32IFD-NEXT:    addi sp, sp, -16
341; RV32IFD-NEXT:    sw a2, 8(sp)
342; RV32IFD-NEXT:    sw a3, 12(sp)
343; RV32IFD-NEXT:    fld ft0, 8(sp)
344; RV32IFD-NEXT:    sw a0, 8(sp)
345; RV32IFD-NEXT:    sw a1, 12(sp)
346; RV32IFD-NEXT:    fld ft1, 8(sp)
347; RV32IFD-NEXT:    feq.d a0, ft1, ft0
348; RV32IFD-NEXT:    xori a0, a0, 1
349; RV32IFD-NEXT:    bnez a0, .LBB13_2
350; RV32IFD-NEXT:  # %bb.1:
351; RV32IFD-NEXT:    fmv.d ft1, ft0
352; RV32IFD-NEXT:  .LBB13_2:
353; RV32IFD-NEXT:    fsd ft1, 8(sp)
354; RV32IFD-NEXT:    lw a0, 8(sp)
355; RV32IFD-NEXT:    lw a1, 12(sp)
356; RV32IFD-NEXT:    addi sp, sp, 16
357; RV32IFD-NEXT:    ret
358  %1 = fcmp une double %a, %b
359  %2 = select i1 %1, double %a, double %b
360  ret double %2
361}
362
363define double @select_fcmp_uno(double %a, double %b) nounwind {
364; TODO: sltiu+bne could be optimized
365; RV32IFD-LABEL: select_fcmp_uno:
366; RV32IFD:       # %bb.0:
367; RV32IFD-NEXT:    addi sp, sp, -16
368; RV32IFD-NEXT:    sw a0, 8(sp)
369; RV32IFD-NEXT:    sw a1, 12(sp)
370; RV32IFD-NEXT:    fld ft0, 8(sp)
371; RV32IFD-NEXT:    sw a2, 8(sp)
372; RV32IFD-NEXT:    sw a3, 12(sp)
373; RV32IFD-NEXT:    fld ft1, 8(sp)
374; RV32IFD-NEXT:    feq.d a0, ft1, ft1
375; RV32IFD-NEXT:    feq.d a1, ft0, ft0
376; RV32IFD-NEXT:    and a0, a1, a0
377; RV32IFD-NEXT:    seqz a0, a0
378; RV32IFD-NEXT:    bnez a0, .LBB14_2
379; RV32IFD-NEXT:  # %bb.1:
380; RV32IFD-NEXT:    fmv.d ft0, ft1
381; RV32IFD-NEXT:  .LBB14_2:
382; RV32IFD-NEXT:    fsd ft0, 8(sp)
383; RV32IFD-NEXT:    lw a0, 8(sp)
384; RV32IFD-NEXT:    lw a1, 12(sp)
385; RV32IFD-NEXT:    addi sp, sp, 16
386; RV32IFD-NEXT:    ret
387  %1 = fcmp uno double %a, %b
388  %2 = select i1 %1, double %a, double %b
389  ret double %2
390}
391
392define double @select_fcmp_true(double %a, double %b) nounwind {
393; RV32IFD-LABEL: select_fcmp_true:
394; RV32IFD:       # %bb.0:
395; RV32IFD-NEXT:    ret
396  %1 = fcmp true double %a, %b
397  %2 = select i1 %1, double %a, double %b
398  ret double %2
399}
400
401; Ensure that ISel succeeds for a select+fcmp that has an i32 result type.
402define i32 @i32_select_fcmp_oeq(double %a, double %b, i32 %c, i32 %d) nounwind {
403; RV32IFD-LABEL: i32_select_fcmp_oeq:
404; RV32IFD:       # %bb.0:
405; RV32IFD-NEXT:    addi sp, sp, -16
406; RV32IFD-NEXT:    sw a2, 8(sp)
407; RV32IFD-NEXT:    sw a3, 12(sp)
408; RV32IFD-NEXT:    fld ft0, 8(sp)
409; RV32IFD-NEXT:    sw a0, 8(sp)
410; RV32IFD-NEXT:    sw a1, 12(sp)
411; RV32IFD-NEXT:    fld ft1, 8(sp)
412; RV32IFD-NEXT:    feq.d a0, ft1, ft0
413; RV32IFD-NEXT:    bnez a0, .LBB16_2
414; RV32IFD-NEXT:  # %bb.1:
415; RV32IFD-NEXT:    mv a4, a5
416; RV32IFD-NEXT:  .LBB16_2:
417; RV32IFD-NEXT:    mv a0, a4
418; RV32IFD-NEXT:    addi sp, sp, 16
419; RV32IFD-NEXT:    ret
420  %1 = fcmp oeq double %a, %b
421  %2 = select i1 %1, i32 %c, i32 %d
422  ret i32 %2
423}
424