xref: /llvm-project/llvm/test/CodeGen/RISCV/rvv/frm-insert.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs -target-abi=lp64d < %s | FileCheck %s
3; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs -target-abi=lp64d \
4; RUN: -riscv-disable-frm-insert-opt < %s | FileCheck %s --check-prefix=UNOPT
5
6declare <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
7  <vscale x 1 x float>,
8  <vscale x 1 x float>,
9  <vscale x 1 x float>,
10  i64, i64)
11
12; Test only save/restore frm once.
13define <vscale x 1 x float> @test(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
14; CHECK-LABEL: test:
15; CHECK:       # %bb.0: # %entry
16; CHECK-NEXT:    fsrmi a1, 0
17; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
18; CHECK-NEXT:    vfadd.vv v8, v8, v9
19; CHECK-NEXT:    vfadd.vv v8, v8, v8
20; CHECK-NEXT:    fsrm a1
21; CHECK-NEXT:    ret
22;
23; UNOPT-LABEL: test:
24; UNOPT:       # %bb.0: # %entry
25; UNOPT-NEXT:    fsrmi a1, 0
26; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
27; UNOPT-NEXT:    vfadd.vv v8, v8, v9
28; UNOPT-NEXT:    fsrm a1
29; UNOPT-NEXT:    fsrmi a0, 0
30; UNOPT-NEXT:    vfadd.vv v8, v8, v8
31; UNOPT-NEXT:    fsrm a0
32; UNOPT-NEXT:    ret
33entry:
34  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
35    <vscale x 1 x float> undef,
36    <vscale x 1 x float> %0,
37    <vscale x 1 x float> %1,
38    i64 0, i64 %2)
39  %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
40    <vscale x 1 x float> undef,
41    <vscale x 1 x float> %a,
42    <vscale x 1 x float> %a,
43    i64 0, i64 %2)
44  ret <vscale x 1 x float> %b
45}
46
47; Test only restore frm once.
48define <vscale x 1 x float> @test2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
49; CHECK-LABEL: test2:
50; CHECK:       # %bb.0: # %entry
51; CHECK-NEXT:    fsrmi a1, 0
52; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
53; CHECK-NEXT:    vfadd.vv v8, v8, v9
54; CHECK-NEXT:    fsrmi 1
55; CHECK-NEXT:    vfadd.vv v8, v8, v8
56; CHECK-NEXT:    fsrm a1
57; CHECK-NEXT:    ret
58;
59; UNOPT-LABEL: test2:
60; UNOPT:       # %bb.0: # %entry
61; UNOPT-NEXT:    fsrmi a1, 0
62; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
63; UNOPT-NEXT:    vfadd.vv v8, v8, v9
64; UNOPT-NEXT:    fsrm a1
65; UNOPT-NEXT:    fsrmi a0, 1
66; UNOPT-NEXT:    vfadd.vv v8, v8, v8
67; UNOPT-NEXT:    fsrm a0
68; UNOPT-NEXT:    ret
69entry:
70  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
71    <vscale x 1 x float> undef,
72    <vscale x 1 x float> %0,
73    <vscale x 1 x float> %1,
74    i64 0, i64 %2)
75  %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
76    <vscale x 1 x float> undef,
77    <vscale x 1 x float> %a,
78    <vscale x 1 x float> %a,
79    i64 1, i64 %2)
80  ret <vscale x 1 x float> %b
81}
82
83declare void @foo()
84define <vscale x 1 x float> @just_call(<vscale x 1 x float> %0) nounwind {
85; CHECK-LABEL: just_call:
86; CHECK:       # %bb.0: # %entry
87; CHECK-NEXT:    addi sp, sp, -48
88; CHECK-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
89; CHECK-NEXT:    csrr a0, vlenb
90; CHECK-NEXT:    sub sp, sp, a0
91; CHECK-NEXT:    addi a0, sp, 32
92; CHECK-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
93; CHECK-NEXT:    call foo
94; CHECK-NEXT:    addi a0, sp, 32
95; CHECK-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
96; CHECK-NEXT:    csrr a0, vlenb
97; CHECK-NEXT:    add sp, sp, a0
98; CHECK-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
99; CHECK-NEXT:    addi sp, sp, 48
100; CHECK-NEXT:    ret
101;
102; UNOPT-LABEL: just_call:
103; UNOPT:       # %bb.0: # %entry
104; UNOPT-NEXT:    addi sp, sp, -48
105; UNOPT-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
106; UNOPT-NEXT:    csrr a0, vlenb
107; UNOPT-NEXT:    sub sp, sp, a0
108; UNOPT-NEXT:    addi a0, sp, 32
109; UNOPT-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
110; UNOPT-NEXT:    call foo
111; UNOPT-NEXT:    addi a0, sp, 32
112; UNOPT-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
113; UNOPT-NEXT:    csrr a0, vlenb
114; UNOPT-NEXT:    add sp, sp, a0
115; UNOPT-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
116; UNOPT-NEXT:    addi sp, sp, 48
117; UNOPT-NEXT:    ret
118entry:
119  call void @foo()
120  ret <vscale x 1 x float> %0
121}
122
123define <vscale x 1 x float> @before_call1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
124; CHECK-LABEL: before_call1:
125; CHECK:       # %bb.0: # %entry
126; CHECK-NEXT:    addi sp, sp, -48
127; CHECK-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
128; CHECK-NEXT:    csrr a1, vlenb
129; CHECK-NEXT:    sub sp, sp, a1
130; CHECK-NEXT:    fsrmi a1, 0
131; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
132; CHECK-NEXT:    vfadd.vv v8, v8, v9
133; CHECK-NEXT:    addi a0, sp, 32
134; CHECK-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
135; CHECK-NEXT:    fsrm a1
136; CHECK-NEXT:    call foo
137; CHECK-NEXT:    addi a0, sp, 32
138; CHECK-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
139; CHECK-NEXT:    csrr a0, vlenb
140; CHECK-NEXT:    add sp, sp, a0
141; CHECK-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
142; CHECK-NEXT:    addi sp, sp, 48
143; CHECK-NEXT:    ret
144;
145; UNOPT-LABEL: before_call1:
146; UNOPT:       # %bb.0: # %entry
147; UNOPT-NEXT:    addi sp, sp, -48
148; UNOPT-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
149; UNOPT-NEXT:    csrr a1, vlenb
150; UNOPT-NEXT:    sub sp, sp, a1
151; UNOPT-NEXT:    fsrmi a1, 0
152; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
153; UNOPT-NEXT:    vfadd.vv v8, v8, v9
154; UNOPT-NEXT:    addi a0, sp, 32
155; UNOPT-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
156; UNOPT-NEXT:    fsrm a1
157; UNOPT-NEXT:    call foo
158; UNOPT-NEXT:    addi a0, sp, 32
159; UNOPT-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
160; UNOPT-NEXT:    csrr a0, vlenb
161; UNOPT-NEXT:    add sp, sp, a0
162; UNOPT-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
163; UNOPT-NEXT:    addi sp, sp, 48
164; UNOPT-NEXT:    ret
165entry:
166  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
167    <vscale x 1 x float> undef,
168    <vscale x 1 x float> %0,
169    <vscale x 1 x float> %1,
170    i64 0, i64 %2)
171  call void @foo()
172  ret <vscale x 1 x float> %a
173}
174
175define <vscale x 1 x float> @before_call2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
176; CHECK-LABEL: before_call2:
177; CHECK:       # %bb.0: # %entry
178; CHECK-NEXT:    addi sp, sp, -48
179; CHECK-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
180; CHECK-NEXT:    csrr a1, vlenb
181; CHECK-NEXT:    sub sp, sp, a1
182; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
183; CHECK-NEXT:    vfadd.vv v8, v8, v9
184; CHECK-NEXT:    addi a0, sp, 32
185; CHECK-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
186; CHECK-NEXT:    call foo
187; CHECK-NEXT:    addi a0, sp, 32
188; CHECK-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
189; CHECK-NEXT:    csrr a0, vlenb
190; CHECK-NEXT:    add sp, sp, a0
191; CHECK-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
192; CHECK-NEXT:    addi sp, sp, 48
193; CHECK-NEXT:    ret
194;
195; UNOPT-LABEL: before_call2:
196; UNOPT:       # %bb.0: # %entry
197; UNOPT-NEXT:    addi sp, sp, -48
198; UNOPT-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
199; UNOPT-NEXT:    csrr a1, vlenb
200; UNOPT-NEXT:    sub sp, sp, a1
201; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
202; UNOPT-NEXT:    vfadd.vv v8, v8, v9
203; UNOPT-NEXT:    addi a0, sp, 32
204; UNOPT-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
205; UNOPT-NEXT:    call foo
206; UNOPT-NEXT:    addi a0, sp, 32
207; UNOPT-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
208; UNOPT-NEXT:    csrr a0, vlenb
209; UNOPT-NEXT:    add sp, sp, a0
210; UNOPT-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
211; UNOPT-NEXT:    addi sp, sp, 48
212; UNOPT-NEXT:    ret
213entry:
214  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
215    <vscale x 1 x float> undef,
216    <vscale x 1 x float> %0,
217    <vscale x 1 x float> %1,
218    i64 7, i64 %2)
219  call void @foo()
220  ret <vscale x 1 x float> %a
221}
222
223define <vscale x 1 x float> @after_call1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
224; CHECK-LABEL: after_call1:
225; CHECK:       # %bb.0: # %entry
226; CHECK-NEXT:    addi sp, sp, -48
227; CHECK-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
228; CHECK-NEXT:    csrr a1, vlenb
229; CHECK-NEXT:    sub sp, sp, a1
230; CHECK-NEXT:    fsrmi a1, 0
231; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
232; CHECK-NEXT:    vfadd.vv v8, v8, v9
233; CHECK-NEXT:    addi a0, sp, 32
234; CHECK-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
235; CHECK-NEXT:    fsrm a1
236; CHECK-NEXT:    call foo
237; CHECK-NEXT:    addi a0, sp, 32
238; CHECK-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
239; CHECK-NEXT:    csrr a0, vlenb
240; CHECK-NEXT:    add sp, sp, a0
241; CHECK-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
242; CHECK-NEXT:    addi sp, sp, 48
243; CHECK-NEXT:    ret
244;
245; UNOPT-LABEL: after_call1:
246; UNOPT:       # %bb.0: # %entry
247; UNOPT-NEXT:    addi sp, sp, -48
248; UNOPT-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
249; UNOPT-NEXT:    csrr a1, vlenb
250; UNOPT-NEXT:    sub sp, sp, a1
251; UNOPT-NEXT:    fsrmi a1, 0
252; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
253; UNOPT-NEXT:    vfadd.vv v8, v8, v9
254; UNOPT-NEXT:    addi a0, sp, 32
255; UNOPT-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
256; UNOPT-NEXT:    fsrm a1
257; UNOPT-NEXT:    call foo
258; UNOPT-NEXT:    addi a0, sp, 32
259; UNOPT-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
260; UNOPT-NEXT:    csrr a0, vlenb
261; UNOPT-NEXT:    add sp, sp, a0
262; UNOPT-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
263; UNOPT-NEXT:    addi sp, sp, 48
264; UNOPT-NEXT:    ret
265entry:
266  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
267    <vscale x 1 x float> undef,
268    <vscale x 1 x float> %0,
269    <vscale x 1 x float> %1,
270    i64 0, i64 %2)
271  call void @foo()
272  ret <vscale x 1 x float> %a
273}
274
275define <vscale x 1 x float> @after_call2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
276; CHECK-LABEL: after_call2:
277; CHECK:       # %bb.0: # %entry
278; CHECK-NEXT:    addi sp, sp, -48
279; CHECK-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
280; CHECK-NEXT:    csrr a1, vlenb
281; CHECK-NEXT:    sub sp, sp, a1
282; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
283; CHECK-NEXT:    vfadd.vv v8, v8, v9
284; CHECK-NEXT:    addi a0, sp, 32
285; CHECK-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
286; CHECK-NEXT:    call foo
287; CHECK-NEXT:    addi a0, sp, 32
288; CHECK-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
289; CHECK-NEXT:    csrr a0, vlenb
290; CHECK-NEXT:    add sp, sp, a0
291; CHECK-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
292; CHECK-NEXT:    addi sp, sp, 48
293; CHECK-NEXT:    ret
294;
295; UNOPT-LABEL: after_call2:
296; UNOPT:       # %bb.0: # %entry
297; UNOPT-NEXT:    addi sp, sp, -48
298; UNOPT-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
299; UNOPT-NEXT:    csrr a1, vlenb
300; UNOPT-NEXT:    sub sp, sp, a1
301; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
302; UNOPT-NEXT:    vfadd.vv v8, v8, v9
303; UNOPT-NEXT:    addi a0, sp, 32
304; UNOPT-NEXT:    vs1r.v v8, (a0) # Unknown-size Folded Spill
305; UNOPT-NEXT:    call foo
306; UNOPT-NEXT:    addi a0, sp, 32
307; UNOPT-NEXT:    vl1r.v v8, (a0) # Unknown-size Folded Reload
308; UNOPT-NEXT:    csrr a0, vlenb
309; UNOPT-NEXT:    add sp, sp, a0
310; UNOPT-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
311; UNOPT-NEXT:    addi sp, sp, 48
312; UNOPT-NEXT:    ret
313entry:
314  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
315    <vscale x 1 x float> undef,
316    <vscale x 1 x float> %0,
317    <vscale x 1 x float> %1,
318    i64 7, i64 %2)
319  call void @foo()
320  ret <vscale x 1 x float> %a
321}
322
323define <vscale x 1 x float> @just_asm(<vscale x 1 x float> %0) nounwind {
324; CHECK-LABEL: just_asm:
325; CHECK:       # %bb.0: # %entry
326; CHECK-NEXT:    #APP
327; CHECK-NEXT:    #NO_APP
328; CHECK-NEXT:    ret
329;
330; UNOPT-LABEL: just_asm:
331; UNOPT:       # %bb.0: # %entry
332; UNOPT-NEXT:    #APP
333; UNOPT-NEXT:    #NO_APP
334; UNOPT-NEXT:    ret
335entry:
336  call void asm sideeffect "", ""()
337  ret <vscale x 1 x float> %0
338}
339
340define <vscale x 1 x float> @before_asm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
341; CHECK-LABEL: before_asm1:
342; CHECK:       # %bb.0: # %entry
343; CHECK-NEXT:    fsrmi a1, 0
344; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
345; CHECK-NEXT:    vfadd.vv v8, v8, v9
346; CHECK-NEXT:    fsrm a1
347; CHECK-NEXT:    #APP
348; CHECK-NEXT:    #NO_APP
349; CHECK-NEXT:    ret
350;
351; UNOPT-LABEL: before_asm1:
352; UNOPT:       # %bb.0: # %entry
353; UNOPT-NEXT:    fsrmi a1, 0
354; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
355; UNOPT-NEXT:    vfadd.vv v8, v8, v9
356; UNOPT-NEXT:    fsrm a1
357; UNOPT-NEXT:    #APP
358; UNOPT-NEXT:    #NO_APP
359; UNOPT-NEXT:    ret
360entry:
361  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
362    <vscale x 1 x float> undef,
363    <vscale x 1 x float> %0,
364    <vscale x 1 x float> %1,
365    i64 0, i64 %2)
366  call void asm sideeffect "", ""()
367  ret <vscale x 1 x float> %a
368}
369
370define <vscale x 1 x float> @before_asm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
371; CHECK-LABEL: before_asm2:
372; CHECK:       # %bb.0: # %entry
373; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
374; CHECK-NEXT:    vfadd.vv v8, v8, v9
375; CHECK-NEXT:    #APP
376; CHECK-NEXT:    #NO_APP
377; CHECK-NEXT:    ret
378;
379; UNOPT-LABEL: before_asm2:
380; UNOPT:       # %bb.0: # %entry
381; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
382; UNOPT-NEXT:    vfadd.vv v8, v8, v9
383; UNOPT-NEXT:    #APP
384; UNOPT-NEXT:    #NO_APP
385; UNOPT-NEXT:    ret
386entry:
387  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
388    <vscale x 1 x float> undef,
389    <vscale x 1 x float> %0,
390    <vscale x 1 x float> %1,
391    i64 7, i64 %2)
392  call void asm sideeffect "", ""()
393  ret <vscale x 1 x float> %a
394}
395
396define <vscale x 1 x float> @after_asm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
397; CHECK-LABEL: after_asm1:
398; CHECK:       # %bb.0: # %entry
399; CHECK-NEXT:    fsrmi a1, 0
400; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
401; CHECK-NEXT:    vfadd.vv v8, v8, v9
402; CHECK-NEXT:    fsrm a1
403; CHECK-NEXT:    #APP
404; CHECK-NEXT:    #NO_APP
405; CHECK-NEXT:    ret
406;
407; UNOPT-LABEL: after_asm1:
408; UNOPT:       # %bb.0: # %entry
409; UNOPT-NEXT:    fsrmi a1, 0
410; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
411; UNOPT-NEXT:    vfadd.vv v8, v8, v9
412; UNOPT-NEXT:    fsrm a1
413; UNOPT-NEXT:    #APP
414; UNOPT-NEXT:    #NO_APP
415; UNOPT-NEXT:    ret
416entry:
417  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
418    <vscale x 1 x float> undef,
419    <vscale x 1 x float> %0,
420    <vscale x 1 x float> %1,
421    i64 0, i64 %2)
422  call void asm sideeffect "", ""()
423  ret <vscale x 1 x float> %a
424}
425
426define <vscale x 1 x float> @after_asm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
427; CHECK-LABEL: after_asm2:
428; CHECK:       # %bb.0: # %entry
429; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
430; CHECK-NEXT:    vfadd.vv v8, v8, v9
431; CHECK-NEXT:    #APP
432; CHECK-NEXT:    #NO_APP
433; CHECK-NEXT:    ret
434;
435; UNOPT-LABEL: after_asm2:
436; UNOPT:       # %bb.0: # %entry
437; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
438; UNOPT-NEXT:    vfadd.vv v8, v8, v9
439; UNOPT-NEXT:    #APP
440; UNOPT-NEXT:    #NO_APP
441; UNOPT-NEXT:    ret
442entry:
443  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
444    <vscale x 1 x float> undef,
445    <vscale x 1 x float> %0,
446    <vscale x 1 x float> %1,
447    i64 7, i64 %2)
448  call void asm sideeffect "", ""()
449  ret <vscale x 1 x float> %a
450}
451
452; Test restoring frm before reading frm and doing nothing with following
453; dynamic rounding mode operations.
454; TODO: The frrm could be elided.
455declare i32 @llvm.get.rounding()
456define <vscale x 1 x float> @test5(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2, ptr %p) nounwind {
457; CHECK-LABEL: test5:
458; CHECK:       # %bb.0: # %entry
459; CHECK-NEXT:    fsrmi a2, 0
460; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
461; CHECK-NEXT:    vfadd.vv v8, v8, v9
462; CHECK-NEXT:    lui a0, 66
463; CHECK-NEXT:    fsrm a2
464; CHECK-NEXT:    addiw a0, a0, 769
465; CHECK-NEXT:    frrm a2
466; CHECK-NEXT:    slli a2, a2, 2
467; CHECK-NEXT:    srl a0, a0, a2
468; CHECK-NEXT:    andi a0, a0, 7
469; CHECK-NEXT:    vfadd.vv v8, v8, v8
470; CHECK-NEXT:    sw a0, 0(a1)
471; CHECK-NEXT:    ret
472;
473; UNOPT-LABEL: test5:
474; UNOPT:       # %bb.0: # %entry
475; UNOPT-NEXT:    fsrmi a2, 0
476; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
477; UNOPT-NEXT:    vfadd.vv v8, v8, v9
478; UNOPT-NEXT:    lui a0, 66
479; UNOPT-NEXT:    fsrm a2
480; UNOPT-NEXT:    addiw a0, a0, 769
481; UNOPT-NEXT:    frrm a2
482; UNOPT-NEXT:    slli a2, a2, 2
483; UNOPT-NEXT:    srl a0, a0, a2
484; UNOPT-NEXT:    andi a0, a0, 7
485; UNOPT-NEXT:    vfadd.vv v8, v8, v8
486; UNOPT-NEXT:    sw a0, 0(a1)
487; UNOPT-NEXT:    ret
488entry:
489  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
490    <vscale x 1 x float> undef,
491    <vscale x 1 x float> %0,
492    <vscale x 1 x float> %1,
493    i64 0, i64 %2)
494  %rm = call i32 @llvm.get.rounding()
495  store i32 %rm, ptr %p, align 4
496  %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
497    <vscale x 1 x float> undef,
498    <vscale x 1 x float> %a,
499    <vscale x 1 x float> %a,
500    i64 7, i64 %2)
501  ret <vscale x 1 x float> %b
502}
503
504; Test not set FRM for vfadd with DYN after WriteFRMImm.
505declare void @llvm.set.rounding(i32)
506define <vscale x 1 x float> @after_fsrm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
507; CHECK-LABEL: after_fsrm1:
508; CHECK:       # %bb.0: # %entry
509; CHECK-NEXT:    fsrmi 4
510; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
511; CHECK-NEXT:    vfadd.vv v8, v8, v9
512; CHECK-NEXT:    ret
513;
514; UNOPT-LABEL: after_fsrm1:
515; UNOPT:       # %bb.0: # %entry
516; UNOPT-NEXT:    fsrmi 4
517; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
518; UNOPT-NEXT:    vfadd.vv v8, v8, v9
519; UNOPT-NEXT:    ret
520entry:
521  call void @llvm.set.rounding(i32 4)
522  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
523    <vscale x 1 x float> undef,
524    <vscale x 1 x float> %0,
525    <vscale x 1 x float> %1,
526    i64 7, i64 %2)
527  ret <vscale x 1 x float> %a
528}
529
530; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm.
531define <vscale x 1 x float> @after_fsrm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
532; CHECK-LABEL: after_fsrm2:
533; CHECK:       # %bb.0: # %entry
534; CHECK-NEXT:    fsrmi 4
535; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
536; CHECK-NEXT:    vfadd.vv v8, v8, v9
537; CHECK-NEXT:    ret
538;
539; UNOPT-LABEL: after_fsrm2:
540; UNOPT:       # %bb.0: # %entry
541; UNOPT-NEXT:    fsrmi 4
542; UNOPT-NEXT:    fsrmi a1, 4
543; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
544; UNOPT-NEXT:    vfadd.vv v8, v8, v9
545; UNOPT-NEXT:    fsrm a1
546; UNOPT-NEXT:    ret
547entry:
548  call void @llvm.set.rounding(i32 4)
549  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
550    <vscale x 1 x float> undef,
551    <vscale x 1 x float> %0,
552    <vscale x 1 x float> %1,
553    i64 4, i64 %2)
554  ret <vscale x 1 x float> %a
555}
556
557; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm.
558define <vscale x 1 x float> @after_fsrm3(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
559; CHECK-LABEL: after_fsrm3:
560; CHECK:       # %bb.0: # %entry
561; CHECK-NEXT:    fsrmi 4
562; CHECK-NEXT:    fsrmi a1, 3
563; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
564; CHECK-NEXT:    vfadd.vv v8, v8, v9
565; CHECK-NEXT:    fsrm a1
566; CHECK-NEXT:    ret
567;
568; UNOPT-LABEL: after_fsrm3:
569; UNOPT:       # %bb.0: # %entry
570; UNOPT-NEXT:    fsrmi 4
571; UNOPT-NEXT:    fsrmi a1, 3
572; UNOPT-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
573; UNOPT-NEXT:    vfadd.vv v8, v8, v9
574; UNOPT-NEXT:    fsrm a1
575; UNOPT-NEXT:    ret
576entry:
577  call void @llvm.set.rounding(i32 4)
578  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
579    <vscale x 1 x float> undef,
580    <vscale x 1 x float> %0,
581    <vscale x 1 x float> %1,
582    i64 3, i64 %2)
583  ret <vscale x 1 x float> %a
584}
585
586; Test not set FRM for the vfadd after WriteFRM.
587define <vscale x 1 x float> @after_fsrm4(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i32 %rm, i64 %2) nounwind {
588; CHECK-LABEL: after_fsrm4:
589; CHECK:       # %bb.0: # %entry
590; CHECK-NEXT:    slli a0, a0, 32
591; CHECK-NEXT:    lui a2, 66
592; CHECK-NEXT:    srli a0, a0, 30
593; CHECK-NEXT:    addiw a2, a2, 769
594; CHECK-NEXT:    srl a0, a2, a0
595; CHECK-NEXT:    andi a0, a0, 7
596; CHECK-NEXT:    fsrm a0
597; CHECK-NEXT:    vsetvli zero, a1, e32, mf2, ta, ma
598; CHECK-NEXT:    vfadd.vv v8, v8, v9
599; CHECK-NEXT:    ret
600;
601; UNOPT-LABEL: after_fsrm4:
602; UNOPT:       # %bb.0: # %entry
603; UNOPT-NEXT:    slli a0, a0, 32
604; UNOPT-NEXT:    lui a2, 66
605; UNOPT-NEXT:    srli a0, a0, 30
606; UNOPT-NEXT:    addiw a2, a2, 769
607; UNOPT-NEXT:    srl a0, a2, a0
608; UNOPT-NEXT:    andi a0, a0, 7
609; UNOPT-NEXT:    fsrm a0
610; UNOPT-NEXT:    vsetvli zero, a1, e32, mf2, ta, ma
611; UNOPT-NEXT:    vfadd.vv v8, v8, v9
612; UNOPT-NEXT:    ret
613entry:
614  call void @llvm.set.rounding(i32 %rm)
615  %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
616    <vscale x 1 x float> undef,
617    <vscale x 1 x float> %0,
618    <vscale x 1 x float> %1,
619    i64 7, i64 %2)
620  ret <vscale x 1 x float> %a
621}
622