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; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefix=RV64IF %s
6
7declare void @abort()
8declare void @exit(i32)
9declare float @dummy(float)
10
11define void @br_fcmp_false(float %a, float %b) nounwind {
12; RV32IF-LABEL: br_fcmp_false:
13; RV32IF:       # %bb.0:
14; RV32IF-NEXT:    addi sp, sp, -16
15; RV32IF-NEXT:    sw ra, 12(sp)
16; RV32IF-NEXT:    addi a0, zero, 1
17; RV32IF-NEXT:    bnez a0, .LBB0_2
18; RV32IF-NEXT:  # %bb.1: # %if.then
19; RV32IF-NEXT:    lw ra, 12(sp)
20; RV32IF-NEXT:    addi sp, sp, 16
21; RV32IF-NEXT:    ret
22; RV32IF-NEXT:  .LBB0_2: # %if.else
23; RV32IF-NEXT:    call abort
24;
25; RV64IF-LABEL: br_fcmp_false:
26; RV64IF:       # %bb.0:
27; RV64IF-NEXT:    addi sp, sp, -16
28; RV64IF-NEXT:    sd ra, 8(sp)
29; RV64IF-NEXT:    addi a0, zero, 1
30; RV64IF-NEXT:    bnez a0, .LBB0_2
31; RV64IF-NEXT:  # %bb.1: # %if.then
32; RV64IF-NEXT:    ld ra, 8(sp)
33; RV64IF-NEXT:    addi sp, sp, 16
34; RV64IF-NEXT:    ret
35; RV64IF-NEXT:  .LBB0_2: # %if.else
36; RV64IF-NEXT:    call abort
37  %1 = fcmp false float %a, %b
38  br i1 %1, label %if.then, label %if.else
39if.then:
40  ret void
41if.else:
42  tail call void @abort()
43  unreachable
44}
45
46define void @br_fcmp_oeq(float %a, float %b) nounwind {
47; RV32IF-LABEL: br_fcmp_oeq:
48; RV32IF:       # %bb.0:
49; RV32IF-NEXT:    addi sp, sp, -16
50; RV32IF-NEXT:    sw ra, 12(sp)
51; RV32IF-NEXT:    fmv.w.x ft0, a1
52; RV32IF-NEXT:    fmv.w.x ft1, a0
53; RV32IF-NEXT:    feq.s a0, ft1, ft0
54; RV32IF-NEXT:    bnez a0, .LBB1_2
55; RV32IF-NEXT:  # %bb.1: # %if.else
56; RV32IF-NEXT:    lw ra, 12(sp)
57; RV32IF-NEXT:    addi sp, sp, 16
58; RV32IF-NEXT:    ret
59; RV32IF-NEXT:  .LBB1_2: # %if.then
60; RV32IF-NEXT:    call abort
61;
62; RV64IF-LABEL: br_fcmp_oeq:
63; RV64IF:       # %bb.0:
64; RV64IF-NEXT:    addi sp, sp, -16
65; RV64IF-NEXT:    sd ra, 8(sp)
66; RV64IF-NEXT:    fmv.w.x ft0, a1
67; RV64IF-NEXT:    fmv.w.x ft1, a0
68; RV64IF-NEXT:    feq.s a0, ft1, ft0
69; RV64IF-NEXT:    bnez a0, .LBB1_2
70; RV64IF-NEXT:  # %bb.1: # %if.else
71; RV64IF-NEXT:    ld ra, 8(sp)
72; RV64IF-NEXT:    addi sp, sp, 16
73; RV64IF-NEXT:    ret
74; RV64IF-NEXT:  .LBB1_2: # %if.then
75; RV64IF-NEXT:    call abort
76  %1 = fcmp oeq float %a, %b
77  br i1 %1, label %if.then, label %if.else
78if.else:
79  ret void
80if.then:
81  tail call void @abort()
82  unreachable
83}
84
85; TODO: generated code quality for this is very poor due to
86; DAGCombiner::visitXOR converting the legal setoeq to setune, which requires
87; expansion.
88define void @br_fcmp_oeq_alt(float %a, float %b) nounwind {
89; RV32IF-LABEL: br_fcmp_oeq_alt:
90; RV32IF:       # %bb.0:
91; RV32IF-NEXT:    addi sp, sp, -16
92; RV32IF-NEXT:    sw ra, 12(sp)
93; RV32IF-NEXT:    fmv.w.x ft0, a1
94; RV32IF-NEXT:    fmv.w.x ft1, a0
95; RV32IF-NEXT:    feq.s a0, ft1, ft0
96; RV32IF-NEXT:    xori a0, a0, 1
97; RV32IF-NEXT:    beqz a0, .LBB2_2
98; RV32IF-NEXT:  # %bb.1: # %if.else
99; RV32IF-NEXT:    lw ra, 12(sp)
100; RV32IF-NEXT:    addi sp, sp, 16
101; RV32IF-NEXT:    ret
102; RV32IF-NEXT:  .LBB2_2: # %if.then
103; RV32IF-NEXT:    call abort
104;
105; RV64IF-LABEL: br_fcmp_oeq_alt:
106; RV64IF:       # %bb.0:
107; RV64IF-NEXT:    addi sp, sp, -16
108; RV64IF-NEXT:    sd ra, 8(sp)
109; RV64IF-NEXT:    fmv.w.x ft0, a1
110; RV64IF-NEXT:    fmv.w.x ft1, a0
111; RV64IF-NEXT:    feq.s a0, ft1, ft0
112; RV64IF-NEXT:    xori a0, a0, 1
113; RV64IF-NEXT:    beqz a0, .LBB2_2
114; RV64IF-NEXT:  # %bb.1: # %if.else
115; RV64IF-NEXT:    ld ra, 8(sp)
116; RV64IF-NEXT:    addi sp, sp, 16
117; RV64IF-NEXT:    ret
118; RV64IF-NEXT:  .LBB2_2: # %if.then
119; RV64IF-NEXT:    call abort
120  %1 = fcmp oeq float %a, %b
121  br i1 %1, label %if.then, label %if.else
122if.then:
123  tail call void @abort()
124  unreachable
125if.else:
126  ret void
127}
128
129define void @br_fcmp_ogt(float %a, float %b) nounwind {
130; RV32IF-LABEL: br_fcmp_ogt:
131; RV32IF:       # %bb.0:
132; RV32IF-NEXT:    addi sp, sp, -16
133; RV32IF-NEXT:    sw ra, 12(sp)
134; RV32IF-NEXT:    fmv.w.x ft0, a0
135; RV32IF-NEXT:    fmv.w.x ft1, a1
136; RV32IF-NEXT:    flt.s a0, ft1, ft0
137; RV32IF-NEXT:    bnez a0, .LBB3_2
138; RV32IF-NEXT:  # %bb.1: # %if.else
139; RV32IF-NEXT:    lw ra, 12(sp)
140; RV32IF-NEXT:    addi sp, sp, 16
141; RV32IF-NEXT:    ret
142; RV32IF-NEXT:  .LBB3_2: # %if.then
143; RV32IF-NEXT:    call abort
144;
145; RV64IF-LABEL: br_fcmp_ogt:
146; RV64IF:       # %bb.0:
147; RV64IF-NEXT:    addi sp, sp, -16
148; RV64IF-NEXT:    sd ra, 8(sp)
149; RV64IF-NEXT:    fmv.w.x ft0, a0
150; RV64IF-NEXT:    fmv.w.x ft1, a1
151; RV64IF-NEXT:    flt.s a0, ft1, ft0
152; RV64IF-NEXT:    bnez a0, .LBB3_2
153; RV64IF-NEXT:  # %bb.1: # %if.else
154; RV64IF-NEXT:    ld ra, 8(sp)
155; RV64IF-NEXT:    addi sp, sp, 16
156; RV64IF-NEXT:    ret
157; RV64IF-NEXT:  .LBB3_2: # %if.then
158; RV64IF-NEXT:    call abort
159  %1 = fcmp ogt float %a, %b
160  br i1 %1, label %if.then, label %if.else
161if.else:
162  ret void
163if.then:
164  tail call void @abort()
165  unreachable
166}
167
168define void @br_fcmp_oge(float %a, float %b) nounwind {
169; RV32IF-LABEL: br_fcmp_oge:
170; RV32IF:       # %bb.0:
171; RV32IF-NEXT:    addi sp, sp, -16
172; RV32IF-NEXT:    sw ra, 12(sp)
173; RV32IF-NEXT:    fmv.w.x ft0, a0
174; RV32IF-NEXT:    fmv.w.x ft1, a1
175; RV32IF-NEXT:    fle.s a0, ft1, ft0
176; RV32IF-NEXT:    bnez a0, .LBB4_2
177; RV32IF-NEXT:  # %bb.1: # %if.else
178; RV32IF-NEXT:    lw ra, 12(sp)
179; RV32IF-NEXT:    addi sp, sp, 16
180; RV32IF-NEXT:    ret
181; RV32IF-NEXT:  .LBB4_2: # %if.then
182; RV32IF-NEXT:    call abort
183;
184; RV64IF-LABEL: br_fcmp_oge:
185; RV64IF:       # %bb.0:
186; RV64IF-NEXT:    addi sp, sp, -16
187; RV64IF-NEXT:    sd ra, 8(sp)
188; RV64IF-NEXT:    fmv.w.x ft0, a0
189; RV64IF-NEXT:    fmv.w.x ft1, a1
190; RV64IF-NEXT:    fle.s a0, ft1, ft0
191; RV64IF-NEXT:    bnez a0, .LBB4_2
192; RV64IF-NEXT:  # %bb.1: # %if.else
193; RV64IF-NEXT:    ld ra, 8(sp)
194; RV64IF-NEXT:    addi sp, sp, 16
195; RV64IF-NEXT:    ret
196; RV64IF-NEXT:  .LBB4_2: # %if.then
197; RV64IF-NEXT:    call abort
198  %1 = fcmp oge float %a, %b
199  br i1 %1, label %if.then, label %if.else
200if.else:
201  ret void
202if.then:
203  tail call void @abort()
204  unreachable
205}
206
207define void @br_fcmp_olt(float %a, float %b) nounwind {
208; RV32IF-LABEL: br_fcmp_olt:
209; RV32IF:       # %bb.0:
210; RV32IF-NEXT:    addi sp, sp, -16
211; RV32IF-NEXT:    sw ra, 12(sp)
212; RV32IF-NEXT:    fmv.w.x ft0, a1
213; RV32IF-NEXT:    fmv.w.x ft1, a0
214; RV32IF-NEXT:    flt.s a0, ft1, ft0
215; RV32IF-NEXT:    bnez a0, .LBB5_2
216; RV32IF-NEXT:  # %bb.1: # %if.else
217; RV32IF-NEXT:    lw ra, 12(sp)
218; RV32IF-NEXT:    addi sp, sp, 16
219; RV32IF-NEXT:    ret
220; RV32IF-NEXT:  .LBB5_2: # %if.then
221; RV32IF-NEXT:    call abort
222;
223; RV64IF-LABEL: br_fcmp_olt:
224; RV64IF:       # %bb.0:
225; RV64IF-NEXT:    addi sp, sp, -16
226; RV64IF-NEXT:    sd ra, 8(sp)
227; RV64IF-NEXT:    fmv.w.x ft0, a1
228; RV64IF-NEXT:    fmv.w.x ft1, a0
229; RV64IF-NEXT:    flt.s a0, ft1, ft0
230; RV64IF-NEXT:    bnez a0, .LBB5_2
231; RV64IF-NEXT:  # %bb.1: # %if.else
232; RV64IF-NEXT:    ld ra, 8(sp)
233; RV64IF-NEXT:    addi sp, sp, 16
234; RV64IF-NEXT:    ret
235; RV64IF-NEXT:  .LBB5_2: # %if.then
236; RV64IF-NEXT:    call abort
237  %1 = fcmp olt float %a, %b
238  br i1 %1, label %if.then, label %if.else
239if.else:
240  ret void
241if.then:
242  tail call void @abort()
243  unreachable
244}
245
246define void @br_fcmp_ole(float %a, float %b) nounwind {
247; RV32IF-LABEL: br_fcmp_ole:
248; RV32IF:       # %bb.0:
249; RV32IF-NEXT:    addi sp, sp, -16
250; RV32IF-NEXT:    sw ra, 12(sp)
251; RV32IF-NEXT:    fmv.w.x ft0, a1
252; RV32IF-NEXT:    fmv.w.x ft1, a0
253; RV32IF-NEXT:    fle.s a0, ft1, ft0
254; RV32IF-NEXT:    bnez a0, .LBB6_2
255; RV32IF-NEXT:  # %bb.1: # %if.else
256; RV32IF-NEXT:    lw ra, 12(sp)
257; RV32IF-NEXT:    addi sp, sp, 16
258; RV32IF-NEXT:    ret
259; RV32IF-NEXT:  .LBB6_2: # %if.then
260; RV32IF-NEXT:    call abort
261;
262; RV64IF-LABEL: br_fcmp_ole:
263; RV64IF:       # %bb.0:
264; RV64IF-NEXT:    addi sp, sp, -16
265; RV64IF-NEXT:    sd ra, 8(sp)
266; RV64IF-NEXT:    fmv.w.x ft0, a1
267; RV64IF-NEXT:    fmv.w.x ft1, a0
268; RV64IF-NEXT:    fle.s a0, ft1, ft0
269; RV64IF-NEXT:    bnez a0, .LBB6_2
270; RV64IF-NEXT:  # %bb.1: # %if.else
271; RV64IF-NEXT:    ld ra, 8(sp)
272; RV64IF-NEXT:    addi sp, sp, 16
273; RV64IF-NEXT:    ret
274; RV64IF-NEXT:  .LBB6_2: # %if.then
275; RV64IF-NEXT:    call abort
276  %1 = fcmp ole float %a, %b
277  br i1 %1, label %if.then, label %if.else
278if.else:
279  ret void
280if.then:
281  tail call void @abort()
282  unreachable
283}
284
285; TODO: feq.s+sltiu+bne -> feq.s+beq
286define void @br_fcmp_one(float %a, float %b) nounwind {
287; RV32IF-LABEL: br_fcmp_one:
288; RV32IF:       # %bb.0:
289; RV32IF-NEXT:    addi sp, sp, -16
290; RV32IF-NEXT:    sw ra, 12(sp)
291; RV32IF-NEXT:    fmv.w.x ft0, a0
292; RV32IF-NEXT:    fmv.w.x ft1, a1
293; RV32IF-NEXT:    feq.s a0, ft1, ft1
294; RV32IF-NEXT:    feq.s a1, ft0, ft0
295; RV32IF-NEXT:    and a0, a1, a0
296; RV32IF-NEXT:    feq.s a1, ft0, ft1
297; RV32IF-NEXT:    not a1, a1
298; RV32IF-NEXT:    and a0, a1, a0
299; RV32IF-NEXT:    bnez a0, .LBB7_2
300; RV32IF-NEXT:  # %bb.1: # %if.else
301; RV32IF-NEXT:    lw ra, 12(sp)
302; RV32IF-NEXT:    addi sp, sp, 16
303; RV32IF-NEXT:    ret
304; RV32IF-NEXT:  .LBB7_2: # %if.then
305; RV32IF-NEXT:    call abort
306;
307; RV64IF-LABEL: br_fcmp_one:
308; RV64IF:       # %bb.0:
309; RV64IF-NEXT:    addi sp, sp, -16
310; RV64IF-NEXT:    sd ra, 8(sp)
311; RV64IF-NEXT:    fmv.w.x ft0, a0
312; RV64IF-NEXT:    fmv.w.x ft1, a1
313; RV64IF-NEXT:    feq.s a0, ft1, ft1
314; RV64IF-NEXT:    feq.s a1, ft0, ft0
315; RV64IF-NEXT:    and a0, a1, a0
316; RV64IF-NEXT:    feq.s a1, ft0, ft1
317; RV64IF-NEXT:    not a1, a1
318; RV64IF-NEXT:    and a0, a1, a0
319; RV64IF-NEXT:    bnez a0, .LBB7_2
320; RV64IF-NEXT:  # %bb.1: # %if.else
321; RV64IF-NEXT:    ld ra, 8(sp)
322; RV64IF-NEXT:    addi sp, sp, 16
323; RV64IF-NEXT:    ret
324; RV64IF-NEXT:  .LBB7_2: # %if.then
325; RV64IF-NEXT:    call abort
326  %1 = fcmp one float %a, %b
327  br i1 %1, label %if.then, label %if.else
328if.else:
329  ret void
330if.then:
331  tail call void @abort()
332  unreachable
333}
334
335define void @br_fcmp_ord(float %a, float %b) nounwind {
336; RV32IF-LABEL: br_fcmp_ord:
337; RV32IF:       # %bb.0:
338; RV32IF-NEXT:    addi sp, sp, -16
339; RV32IF-NEXT:    sw ra, 12(sp)
340; RV32IF-NEXT:    fmv.w.x ft0, a0
341; RV32IF-NEXT:    fmv.w.x ft1, a1
342; RV32IF-NEXT:    feq.s a0, ft1, ft1
343; RV32IF-NEXT:    feq.s a1, ft0, ft0
344; RV32IF-NEXT:    and a0, a1, a0
345; RV32IF-NEXT:    bnez a0, .LBB8_2
346; RV32IF-NEXT:  # %bb.1: # %if.else
347; RV32IF-NEXT:    lw ra, 12(sp)
348; RV32IF-NEXT:    addi sp, sp, 16
349; RV32IF-NEXT:    ret
350; RV32IF-NEXT:  .LBB8_2: # %if.then
351; RV32IF-NEXT:    call abort
352;
353; RV64IF-LABEL: br_fcmp_ord:
354; RV64IF:       # %bb.0:
355; RV64IF-NEXT:    addi sp, sp, -16
356; RV64IF-NEXT:    sd ra, 8(sp)
357; RV64IF-NEXT:    fmv.w.x ft0, a0
358; RV64IF-NEXT:    fmv.w.x ft1, a1
359; RV64IF-NEXT:    feq.s a0, ft1, ft1
360; RV64IF-NEXT:    feq.s a1, ft0, ft0
361; RV64IF-NEXT:    and a0, a1, a0
362; RV64IF-NEXT:    bnez a0, .LBB8_2
363; RV64IF-NEXT:  # %bb.1: # %if.else
364; RV64IF-NEXT:    ld ra, 8(sp)
365; RV64IF-NEXT:    addi sp, sp, 16
366; RV64IF-NEXT:    ret
367; RV64IF-NEXT:  .LBB8_2: # %if.then
368; RV64IF-NEXT:    call abort
369  %1 = fcmp ord float %a, %b
370  br i1 %1, label %if.then, label %if.else
371if.else:
372  ret void
373if.then:
374  tail call void @abort()
375  unreachable
376}
377
378define void @br_fcmp_ueq(float %a, float %b) nounwind {
379; RV32IF-LABEL: br_fcmp_ueq:
380; RV32IF:       # %bb.0:
381; RV32IF-NEXT:    addi sp, sp, -16
382; RV32IF-NEXT:    sw ra, 12(sp)
383; RV32IF-NEXT:    fmv.w.x ft0, a1
384; RV32IF-NEXT:    fmv.w.x ft1, a0
385; RV32IF-NEXT:    feq.s a0, ft1, ft0
386; RV32IF-NEXT:    feq.s a1, ft0, ft0
387; RV32IF-NEXT:    feq.s a2, ft1, ft1
388; RV32IF-NEXT:    and a1, a2, a1
389; RV32IF-NEXT:    seqz a1, a1
390; RV32IF-NEXT:    or a0, a0, a1
391; RV32IF-NEXT:    bnez a0, .LBB9_2
392; RV32IF-NEXT:  # %bb.1: # %if.else
393; RV32IF-NEXT:    lw ra, 12(sp)
394; RV32IF-NEXT:    addi sp, sp, 16
395; RV32IF-NEXT:    ret
396; RV32IF-NEXT:  .LBB9_2: # %if.then
397; RV32IF-NEXT:    call abort
398;
399; RV64IF-LABEL: br_fcmp_ueq:
400; RV64IF:       # %bb.0:
401; RV64IF-NEXT:    addi sp, sp, -16
402; RV64IF-NEXT:    sd ra, 8(sp)
403; RV64IF-NEXT:    fmv.w.x ft0, a1
404; RV64IF-NEXT:    fmv.w.x ft1, a0
405; RV64IF-NEXT:    feq.s a0, ft1, ft0
406; RV64IF-NEXT:    feq.s a1, ft0, ft0
407; RV64IF-NEXT:    feq.s a2, ft1, ft1
408; RV64IF-NEXT:    and a1, a2, a1
409; RV64IF-NEXT:    seqz a1, a1
410; RV64IF-NEXT:    or a0, a0, a1
411; RV64IF-NEXT:    bnez a0, .LBB9_2
412; RV64IF-NEXT:  # %bb.1: # %if.else
413; RV64IF-NEXT:    ld ra, 8(sp)
414; RV64IF-NEXT:    addi sp, sp, 16
415; RV64IF-NEXT:    ret
416; RV64IF-NEXT:  .LBB9_2: # %if.then
417; RV64IF-NEXT:    call abort
418  %1 = fcmp ueq float %a, %b
419  br i1 %1, label %if.then, label %if.else
420if.else:
421  ret void
422if.then:
423  tail call void @abort()
424  unreachable
425}
426
427define void @br_fcmp_ugt(float %a, float %b) nounwind {
428; RV32IF-LABEL: br_fcmp_ugt:
429; RV32IF:       # %bb.0:
430; RV32IF-NEXT:    addi sp, sp, -16
431; RV32IF-NEXT:    sw ra, 12(sp)
432; RV32IF-NEXT:    fmv.w.x ft0, a1
433; RV32IF-NEXT:    fmv.w.x ft1, a0
434; RV32IF-NEXT:    fle.s a0, ft1, ft0
435; RV32IF-NEXT:    xori a0, a0, 1
436; RV32IF-NEXT:    bnez a0, .LBB10_2
437; RV32IF-NEXT:  # %bb.1: # %if.else
438; RV32IF-NEXT:    lw ra, 12(sp)
439; RV32IF-NEXT:    addi sp, sp, 16
440; RV32IF-NEXT:    ret
441; RV32IF-NEXT:  .LBB10_2: # %if.then
442; RV32IF-NEXT:    call abort
443;
444; RV64IF-LABEL: br_fcmp_ugt:
445; RV64IF:       # %bb.0:
446; RV64IF-NEXT:    addi sp, sp, -16
447; RV64IF-NEXT:    sd ra, 8(sp)
448; RV64IF-NEXT:    fmv.w.x ft0, a1
449; RV64IF-NEXT:    fmv.w.x ft1, a0
450; RV64IF-NEXT:    fle.s a0, ft1, ft0
451; RV64IF-NEXT:    xori a0, a0, 1
452; RV64IF-NEXT:    bnez a0, .LBB10_2
453; RV64IF-NEXT:  # %bb.1: # %if.else
454; RV64IF-NEXT:    ld ra, 8(sp)
455; RV64IF-NEXT:    addi sp, sp, 16
456; RV64IF-NEXT:    ret
457; RV64IF-NEXT:  .LBB10_2: # %if.then
458; RV64IF-NEXT:    call abort
459  %1 = fcmp ugt float %a, %b
460  br i1 %1, label %if.then, label %if.else
461if.else:
462  ret void
463if.then:
464  tail call void @abort()
465  unreachable
466}
467
468define void @br_fcmp_uge(float %a, float %b) nounwind {
469; RV32IF-LABEL: br_fcmp_uge:
470; RV32IF:       # %bb.0:
471; RV32IF-NEXT:    addi sp, sp, -16
472; RV32IF-NEXT:    sw ra, 12(sp)
473; RV32IF-NEXT:    fmv.w.x ft0, a1
474; RV32IF-NEXT:    fmv.w.x ft1, a0
475; RV32IF-NEXT:    flt.s a0, ft1, ft0
476; RV32IF-NEXT:    xori a0, a0, 1
477; RV32IF-NEXT:    bnez a0, .LBB11_2
478; RV32IF-NEXT:  # %bb.1: # %if.else
479; RV32IF-NEXT:    lw ra, 12(sp)
480; RV32IF-NEXT:    addi sp, sp, 16
481; RV32IF-NEXT:    ret
482; RV32IF-NEXT:  .LBB11_2: # %if.then
483; RV32IF-NEXT:    call abort
484;
485; RV64IF-LABEL: br_fcmp_uge:
486; RV64IF:       # %bb.0:
487; RV64IF-NEXT:    addi sp, sp, -16
488; RV64IF-NEXT:    sd ra, 8(sp)
489; RV64IF-NEXT:    fmv.w.x ft0, a1
490; RV64IF-NEXT:    fmv.w.x ft1, a0
491; RV64IF-NEXT:    flt.s a0, ft1, ft0
492; RV64IF-NEXT:    xori a0, a0, 1
493; RV64IF-NEXT:    bnez a0, .LBB11_2
494; RV64IF-NEXT:  # %bb.1: # %if.else
495; RV64IF-NEXT:    ld ra, 8(sp)
496; RV64IF-NEXT:    addi sp, sp, 16
497; RV64IF-NEXT:    ret
498; RV64IF-NEXT:  .LBB11_2: # %if.then
499; RV64IF-NEXT:    call abort
500  %1 = fcmp uge float %a, %b
501  br i1 %1, label %if.then, label %if.else
502if.else:
503  ret void
504if.then:
505  tail call void @abort()
506  unreachable
507}
508
509define void @br_fcmp_ult(float %a, float %b) nounwind {
510; RV32IF-LABEL: br_fcmp_ult:
511; RV32IF:       # %bb.0:
512; RV32IF-NEXT:    addi sp, sp, -16
513; RV32IF-NEXT:    sw ra, 12(sp)
514; RV32IF-NEXT:    fmv.w.x ft0, a0
515; RV32IF-NEXT:    fmv.w.x ft1, a1
516; RV32IF-NEXT:    fle.s a0, ft1, ft0
517; RV32IF-NEXT:    xori a0, a0, 1
518; RV32IF-NEXT:    bnez a0, .LBB12_2
519; RV32IF-NEXT:  # %bb.1: # %if.else
520; RV32IF-NEXT:    lw ra, 12(sp)
521; RV32IF-NEXT:    addi sp, sp, 16
522; RV32IF-NEXT:    ret
523; RV32IF-NEXT:  .LBB12_2: # %if.then
524; RV32IF-NEXT:    call abort
525;
526; RV64IF-LABEL: br_fcmp_ult:
527; RV64IF:       # %bb.0:
528; RV64IF-NEXT:    addi sp, sp, -16
529; RV64IF-NEXT:    sd ra, 8(sp)
530; RV64IF-NEXT:    fmv.w.x ft0, a0
531; RV64IF-NEXT:    fmv.w.x ft1, a1
532; RV64IF-NEXT:    fle.s a0, ft1, ft0
533; RV64IF-NEXT:    xori a0, a0, 1
534; RV64IF-NEXT:    bnez a0, .LBB12_2
535; RV64IF-NEXT:  # %bb.1: # %if.else
536; RV64IF-NEXT:    ld ra, 8(sp)
537; RV64IF-NEXT:    addi sp, sp, 16
538; RV64IF-NEXT:    ret
539; RV64IF-NEXT:  .LBB12_2: # %if.then
540; RV64IF-NEXT:    call abort
541  %1 = fcmp ult float %a, %b
542  br i1 %1, label %if.then, label %if.else
543if.else:
544  ret void
545if.then:
546  tail call void @abort()
547  unreachable
548}
549
550define void @br_fcmp_ule(float %a, float %b) nounwind {
551; RV32IF-LABEL: br_fcmp_ule:
552; RV32IF:       # %bb.0:
553; RV32IF-NEXT:    addi sp, sp, -16
554; RV32IF-NEXT:    sw ra, 12(sp)
555; RV32IF-NEXT:    fmv.w.x ft0, a0
556; RV32IF-NEXT:    fmv.w.x ft1, a1
557; RV32IF-NEXT:    flt.s a0, ft1, ft0
558; RV32IF-NEXT:    xori a0, a0, 1
559; RV32IF-NEXT:    bnez a0, .LBB13_2
560; RV32IF-NEXT:  # %bb.1: # %if.else
561; RV32IF-NEXT:    lw ra, 12(sp)
562; RV32IF-NEXT:    addi sp, sp, 16
563; RV32IF-NEXT:    ret
564; RV32IF-NEXT:  .LBB13_2: # %if.then
565; RV32IF-NEXT:    call abort
566;
567; RV64IF-LABEL: br_fcmp_ule:
568; RV64IF:       # %bb.0:
569; RV64IF-NEXT:    addi sp, sp, -16
570; RV64IF-NEXT:    sd ra, 8(sp)
571; RV64IF-NEXT:    fmv.w.x ft0, a0
572; RV64IF-NEXT:    fmv.w.x ft1, a1
573; RV64IF-NEXT:    flt.s a0, ft1, ft0
574; RV64IF-NEXT:    xori a0, a0, 1
575; RV64IF-NEXT:    bnez a0, .LBB13_2
576; RV64IF-NEXT:  # %bb.1: # %if.else
577; RV64IF-NEXT:    ld ra, 8(sp)
578; RV64IF-NEXT:    addi sp, sp, 16
579; RV64IF-NEXT:    ret
580; RV64IF-NEXT:  .LBB13_2: # %if.then
581; RV64IF-NEXT:    call abort
582  %1 = fcmp ule float %a, %b
583  br i1 %1, label %if.then, label %if.else
584if.else:
585  ret void
586if.then:
587  tail call void @abort()
588  unreachable
589}
590
591define void @br_fcmp_une(float %a, float %b) nounwind {
592; RV32IF-LABEL: br_fcmp_une:
593; RV32IF:       # %bb.0:
594; RV32IF-NEXT:    addi sp, sp, -16
595; RV32IF-NEXT:    sw ra, 12(sp)
596; RV32IF-NEXT:    fmv.w.x ft0, a1
597; RV32IF-NEXT:    fmv.w.x ft1, a0
598; RV32IF-NEXT:    feq.s a0, ft1, ft0
599; RV32IF-NEXT:    xori a0, a0, 1
600; RV32IF-NEXT:    bnez a0, .LBB14_2
601; RV32IF-NEXT:  # %bb.1: # %if.else
602; RV32IF-NEXT:    lw ra, 12(sp)
603; RV32IF-NEXT:    addi sp, sp, 16
604; RV32IF-NEXT:    ret
605; RV32IF-NEXT:  .LBB14_2: # %if.then
606; RV32IF-NEXT:    call abort
607;
608; RV64IF-LABEL: br_fcmp_une:
609; RV64IF:       # %bb.0:
610; RV64IF-NEXT:    addi sp, sp, -16
611; RV64IF-NEXT:    sd ra, 8(sp)
612; RV64IF-NEXT:    fmv.w.x ft0, a1
613; RV64IF-NEXT:    fmv.w.x ft1, a0
614; RV64IF-NEXT:    feq.s a0, ft1, ft0
615; RV64IF-NEXT:    xori a0, a0, 1
616; RV64IF-NEXT:    bnez a0, .LBB14_2
617; RV64IF-NEXT:  # %bb.1: # %if.else
618; RV64IF-NEXT:    ld ra, 8(sp)
619; RV64IF-NEXT:    addi sp, sp, 16
620; RV64IF-NEXT:    ret
621; RV64IF-NEXT:  .LBB14_2: # %if.then
622; RV64IF-NEXT:    call abort
623  %1 = fcmp une float %a, %b
624  br i1 %1, label %if.then, label %if.else
625if.else:
626  ret void
627if.then:
628  tail call void @abort()
629  unreachable
630}
631
632define void @br_fcmp_uno(float %a, float %b) nounwind {
633; TODO: sltiu+bne -> beq
634; RV32IF-LABEL: br_fcmp_uno:
635; RV32IF:       # %bb.0:
636; RV32IF-NEXT:    addi sp, sp, -16
637; RV32IF-NEXT:    sw ra, 12(sp)
638; RV32IF-NEXT:    fmv.w.x ft0, a0
639; RV32IF-NEXT:    fmv.w.x ft1, a1
640; RV32IF-NEXT:    feq.s a0, ft1, ft1
641; RV32IF-NEXT:    feq.s a1, ft0, ft0
642; RV32IF-NEXT:    and a0, a1, a0
643; RV32IF-NEXT:    seqz a0, a0
644; RV32IF-NEXT:    bnez a0, .LBB15_2
645; RV32IF-NEXT:  # %bb.1: # %if.else
646; RV32IF-NEXT:    lw ra, 12(sp)
647; RV32IF-NEXT:    addi sp, sp, 16
648; RV32IF-NEXT:    ret
649; RV32IF-NEXT:  .LBB15_2: # %if.then
650; RV32IF-NEXT:    call abort
651;
652; RV64IF-LABEL: br_fcmp_uno:
653; RV64IF:       # %bb.0:
654; RV64IF-NEXT:    addi sp, sp, -16
655; RV64IF-NEXT:    sd ra, 8(sp)
656; RV64IF-NEXT:    fmv.w.x ft0, a0
657; RV64IF-NEXT:    fmv.w.x ft1, a1
658; RV64IF-NEXT:    feq.s a0, ft1, ft1
659; RV64IF-NEXT:    feq.s a1, ft0, ft0
660; RV64IF-NEXT:    and a0, a1, a0
661; RV64IF-NEXT:    seqz a0, a0
662; RV64IF-NEXT:    bnez a0, .LBB15_2
663; RV64IF-NEXT:  # %bb.1: # %if.else
664; RV64IF-NEXT:    ld ra, 8(sp)
665; RV64IF-NEXT:    addi sp, sp, 16
666; RV64IF-NEXT:    ret
667; RV64IF-NEXT:  .LBB15_2: # %if.then
668; RV64IF-NEXT:    call abort
669  %1 = fcmp uno float %a, %b
670  br i1 %1, label %if.then, label %if.else
671if.else:
672  ret void
673if.then:
674  tail call void @abort()
675  unreachable
676}
677
678define void @br_fcmp_true(float %a, float %b) nounwind {
679; RV32IF-LABEL: br_fcmp_true:
680; RV32IF:       # %bb.0:
681; RV32IF-NEXT:    addi sp, sp, -16
682; RV32IF-NEXT:    sw ra, 12(sp)
683; RV32IF-NEXT:    addi a0, zero, 1
684; RV32IF-NEXT:    bnez a0, .LBB16_2
685; RV32IF-NEXT:  # %bb.1: # %if.else
686; RV32IF-NEXT:    lw ra, 12(sp)
687; RV32IF-NEXT:    addi sp, sp, 16
688; RV32IF-NEXT:    ret
689; RV32IF-NEXT:  .LBB16_2: # %if.then
690; RV32IF-NEXT:    call abort
691;
692; RV64IF-LABEL: br_fcmp_true:
693; RV64IF:       # %bb.0:
694; RV64IF-NEXT:    addi sp, sp, -16
695; RV64IF-NEXT:    sd ra, 8(sp)
696; RV64IF-NEXT:    addi a0, zero, 1
697; RV64IF-NEXT:    bnez a0, .LBB16_2
698; RV64IF-NEXT:  # %bb.1: # %if.else
699; RV64IF-NEXT:    ld ra, 8(sp)
700; RV64IF-NEXT:    addi sp, sp, 16
701; RV64IF-NEXT:    ret
702; RV64IF-NEXT:  .LBB16_2: # %if.then
703; RV64IF-NEXT:    call abort
704  %1 = fcmp true float %a, %b
705  br i1 %1, label %if.then, label %if.else
706if.else:
707  ret void
708if.then:
709  tail call void @abort()
710  unreachable
711}
712
713; This test exists primarily to trigger RISCVInstrInfo::storeRegToStackSlot
714; and RISCVInstrInfo::loadRegFromStackSlot
715define i32 @br_fcmp_store_load_stack_slot(float %a, float %b) nounwind {
716; TODO: addi %lo(.LCPI17_0) should be merged in to the following flw
717; RV32IF-LABEL: br_fcmp_store_load_stack_slot:
718; RV32IF:       # %bb.0: # %entry
719; RV32IF-NEXT:    addi sp, sp, -16
720; RV32IF-NEXT:    sw ra, 12(sp)
721; RV32IF-NEXT:    mv a0, zero
722; RV32IF-NEXT:    call dummy
723; RV32IF-NEXT:    fmv.w.x ft0, a0
724; RV32IF-NEXT:    fmv.w.x ft1, zero
725; RV32IF-NEXT:    fsw ft1, 8(sp)
726; RV32IF-NEXT:    feq.s a0, ft0, ft1
727; RV32IF-NEXT:    beqz a0, .LBB17_3
728; RV32IF-NEXT:  # %bb.1: # %if.end
729; RV32IF-NEXT:    mv a0, zero
730; RV32IF-NEXT:    call dummy
731; RV32IF-NEXT:    fmv.w.x ft0, a0
732; RV32IF-NEXT:    flw ft1, 8(sp)
733; RV32IF-NEXT:    feq.s a0, ft0, ft1
734; RV32IF-NEXT:    beqz a0, .LBB17_3
735; RV32IF-NEXT:  # %bb.2: # %if.end4
736; RV32IF-NEXT:    mv a0, zero
737; RV32IF-NEXT:    lw ra, 12(sp)
738; RV32IF-NEXT:    addi sp, sp, 16
739; RV32IF-NEXT:    ret
740; RV32IF-NEXT:  .LBB17_3: # %if.then
741; RV32IF-NEXT:    call abort
742;
743; RV64IF-LABEL: br_fcmp_store_load_stack_slot:
744; RV64IF:       # %bb.0: # %entry
745; RV64IF-NEXT:    addi sp, sp, -32
746; RV64IF-NEXT:    sd ra, 24(sp)
747; RV64IF-NEXT:    sd s0, 16(sp)
748; RV64IF-NEXT:    fmv.w.x ft0, zero
749; RV64IF-NEXT:    fsw ft0, 12(sp)
750; RV64IF-NEXT:    fmv.x.w s0, ft0
751; RV64IF-NEXT:    mv a0, s0
752; RV64IF-NEXT:    call dummy
753; RV64IF-NEXT:    fmv.w.x ft0, a0
754; RV64IF-NEXT:    flw ft1, 12(sp)
755; RV64IF-NEXT:    feq.s a0, ft0, ft1
756; RV64IF-NEXT:    beqz a0, .LBB17_3
757; RV64IF-NEXT:  # %bb.1: # %if.end
758; RV64IF-NEXT:    mv a0, s0
759; RV64IF-NEXT:    call dummy
760; RV64IF-NEXT:    fmv.w.x ft0, a0
761; RV64IF-NEXT:    flw ft1, 12(sp)
762; RV64IF-NEXT:    feq.s a0, ft0, ft1
763; RV64IF-NEXT:    beqz a0, .LBB17_3
764; RV64IF-NEXT:  # %bb.2: # %if.end4
765; RV64IF-NEXT:    mv a0, zero
766; RV64IF-NEXT:    ld s0, 16(sp)
767; RV64IF-NEXT:    ld ra, 24(sp)
768; RV64IF-NEXT:    addi sp, sp, 32
769; RV64IF-NEXT:    ret
770; RV64IF-NEXT:  .LBB17_3: # %if.then
771; RV64IF-NEXT:    call abort
772entry:
773  %call = call float @dummy(float 0.000000e+00)
774  %cmp = fcmp une float %call, 0.000000e+00
775  br i1 %cmp, label %if.then, label %if.end
776
777if.then:
778  call void @abort()
779  unreachable
780
781if.end:
782  %call1 = call float @dummy(float 0.000000e+00)
783  %cmp2 = fcmp une float %call1, 0.000000e+00
784  br i1 %cmp2, label %if.then3, label %if.end4
785
786if.then3:
787  call void @abort()
788  unreachable
789
790if.end4:
791  ret i32 0
792}
793