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: -target-abi=ilp32f | FileCheck -check-prefixes=CHECKIF,RV32IF %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5 ; RUN: -target-abi=lp64f | FileCheck -check-prefixes=CHECKIF,RV64IF %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \
7 ; RUN: -target-abi=ilp32 | FileCheck -check-prefixes=CHECKIZFINX,RV32IZFINX %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \
9 ; RUN: -target-abi=lp64 | FileCheck -check-prefixes=CHECKIZFINX,RV64IZFINX %s
11 define dso_local float @flw(ptr %a) nounwind {
14 ; CHECKIF-NEXT: flw fa5, 0(a0)
15 ; CHECKIF-NEXT: flw fa4, 12(a0)
16 ; CHECKIF-NEXT: fadd.s fa0, fa5, fa4
19 ; CHECKIZFINX-LABEL: flw:
20 ; CHECKIZFINX: # %bb.0:
21 ; CHECKIZFINX-NEXT: lw a1, 0(a0)
22 ; CHECKIZFINX-NEXT: lw a0, 12(a0)
23 ; CHECKIZFINX-NEXT: fadd.s a0, a1, a0
24 ; CHECKIZFINX-NEXT: ret
25 %1 = load float, ptr %a
26 %2 = getelementptr float, ptr %a, i32 3
27 %3 = load float, ptr %2
28 ; Use both loaded values in an FP op to ensure an flw is used, even for the
30 %4 = fadd float %1, %3
34 define dso_local void @fsw(ptr %a, float %b, float %c) nounwind {
35 ; Use %b and %c in an FP op to ensure floating point registers are used, even
36 ; for the soft float ABI
39 ; CHECKIF-NEXT: fadd.s fa5, fa0, fa1
40 ; CHECKIF-NEXT: fsw fa5, 0(a0)
41 ; CHECKIF-NEXT: fsw fa5, 32(a0)
44 ; CHECKIZFINX-LABEL: fsw:
45 ; CHECKIZFINX: # %bb.0:
46 ; CHECKIZFINX-NEXT: fadd.s a1, a1, a2
47 ; CHECKIZFINX-NEXT: sw a1, 0(a0)
48 ; CHECKIZFINX-NEXT: sw a1, 32(a0)
49 ; CHECKIZFINX-NEXT: ret
50 %1 = fadd float %b, %c
51 store float %1, ptr %a
52 %2 = getelementptr float, ptr %a, i32 8
53 store float %1, ptr %2
57 ; Check load and store to a global
58 @G = dso_local global float 0.0
60 define dso_local float @flw_fsw_global(float %a, float %b) nounwind {
61 ; Use %a and %b in an FP op to ensure floating point registers are used, even
62 ; for the soft float ABI
63 ; CHECKIF-LABEL: flw_fsw_global:
65 ; CHECKIF-NEXT: fadd.s fa0, fa0, fa1
66 ; CHECKIF-NEXT: lui a0, %hi(G)
67 ; CHECKIF-NEXT: flw fa5, %lo(G)(a0)
68 ; CHECKIF-NEXT: addi a1, a0, %lo(G)
69 ; CHECKIF-NEXT: fsw fa0, %lo(G)(a0)
70 ; CHECKIF-NEXT: flw fa5, 36(a1)
71 ; CHECKIF-NEXT: fsw fa0, 36(a1)
74 ; CHECKIZFINX-LABEL: flw_fsw_global:
75 ; CHECKIZFINX: # %bb.0:
76 ; CHECKIZFINX-NEXT: fadd.s a0, a0, a1
77 ; CHECKIZFINX-NEXT: lui a1, %hi(G)
78 ; CHECKIZFINX-NEXT: lw zero, %lo(G)(a1)
79 ; CHECKIZFINX-NEXT: addi a2, a1, %lo(G)
80 ; CHECKIZFINX-NEXT: sw a0, %lo(G)(a1)
81 ; CHECKIZFINX-NEXT: lw zero, 36(a2)
82 ; CHECKIZFINX-NEXT: sw a0, 36(a2)
83 ; CHECKIZFINX-NEXT: ret
84 %1 = fadd float %a, %b
85 %2 = load volatile float, ptr @G
86 store float %1, ptr @G
87 %3 = getelementptr float, ptr @G, i32 9
88 %4 = load volatile float, ptr %3
89 store float %1, ptr %3
93 ; Ensure that 1 is added to the high 20 bits if bit 11 of the low part is 1
94 define dso_local float @flw_fsw_constant(float %a) nounwind {
95 ; RV32IF-LABEL: flw_fsw_constant:
97 ; RV32IF-NEXT: lui a0, 912092
98 ; RV32IF-NEXT: flw fa5, -273(a0)
99 ; RV32IF-NEXT: fadd.s fa0, fa0, fa5
100 ; RV32IF-NEXT: fsw fa0, -273(a0)
103 ; RV64IF-LABEL: flw_fsw_constant:
105 ; RV64IF-NEXT: lui a0, 228023
106 ; RV64IF-NEXT: slli a0, a0, 2
107 ; RV64IF-NEXT: flw fa5, -273(a0)
108 ; RV64IF-NEXT: fadd.s fa0, fa0, fa5
109 ; RV64IF-NEXT: fsw fa0, -273(a0)
112 ; RV32IZFINX-LABEL: flw_fsw_constant:
113 ; RV32IZFINX: # %bb.0:
114 ; RV32IZFINX-NEXT: lui a1, 912092
115 ; RV32IZFINX-NEXT: lw a2, -273(a1)
116 ; RV32IZFINX-NEXT: fadd.s a0, a0, a2
117 ; RV32IZFINX-NEXT: sw a0, -273(a1)
118 ; RV32IZFINX-NEXT: ret
120 ; RV64IZFINX-LABEL: flw_fsw_constant:
121 ; RV64IZFINX: # %bb.0:
122 ; RV64IZFINX-NEXT: lui a1, 228023
123 ; RV64IZFINX-NEXT: slli a1, a1, 2
124 ; RV64IZFINX-NEXT: lw a2, -273(a1)
125 ; RV64IZFINX-NEXT: fadd.s a0, a0, a2
126 ; RV64IZFINX-NEXT: sw a0, -273(a1)
127 ; RV64IZFINX-NEXT: ret
128 %1 = inttoptr i32 3735928559 to ptr
129 %2 = load volatile float, ptr %1
130 %3 = fadd float %a, %2
131 store float %3, ptr %1
135 declare void @notdead(ptr)
137 define dso_local float @flw_stack(float %a) nounwind {
138 ; RV32IF-LABEL: flw_stack:
140 ; RV32IF-NEXT: addi sp, sp, -16
141 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
142 ; RV32IF-NEXT: fsw fs0, 8(sp) # 4-byte Folded Spill
143 ; RV32IF-NEXT: fmv.s fs0, fa0
144 ; RV32IF-NEXT: addi a0, sp, 4
145 ; RV32IF-NEXT: call notdead
146 ; RV32IF-NEXT: flw fa5, 4(sp)
147 ; RV32IF-NEXT: fadd.s fa0, fa5, fs0
148 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
149 ; RV32IF-NEXT: flw fs0, 8(sp) # 4-byte Folded Reload
150 ; RV32IF-NEXT: addi sp, sp, 16
153 ; RV64IF-LABEL: flw_stack:
155 ; RV64IF-NEXT: addi sp, sp, -16
156 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
157 ; RV64IF-NEXT: fsw fs0, 4(sp) # 4-byte Folded Spill
158 ; RV64IF-NEXT: fmv.s fs0, fa0
159 ; RV64IF-NEXT: mv a0, sp
160 ; RV64IF-NEXT: call notdead
161 ; RV64IF-NEXT: flw fa5, 0(sp)
162 ; RV64IF-NEXT: fadd.s fa0, fa5, fs0
163 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
164 ; RV64IF-NEXT: flw fs0, 4(sp) # 4-byte Folded Reload
165 ; RV64IF-NEXT: addi sp, sp, 16
168 ; RV32IZFINX-LABEL: flw_stack:
169 ; RV32IZFINX: # %bb.0:
170 ; RV32IZFINX-NEXT: addi sp, sp, -16
171 ; RV32IZFINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
172 ; RV32IZFINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
173 ; RV32IZFINX-NEXT: mv s0, a0
174 ; RV32IZFINX-NEXT: addi a0, sp, 4
175 ; RV32IZFINX-NEXT: call notdead
176 ; RV32IZFINX-NEXT: lw a0, 4(sp)
177 ; RV32IZFINX-NEXT: fadd.s a0, a0, s0
178 ; RV32IZFINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
179 ; RV32IZFINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
180 ; RV32IZFINX-NEXT: addi sp, sp, 16
181 ; RV32IZFINX-NEXT: ret
183 ; RV64IZFINX-LABEL: flw_stack:
184 ; RV64IZFINX: # %bb.0:
185 ; RV64IZFINX-NEXT: addi sp, sp, -32
186 ; RV64IZFINX-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
187 ; RV64IZFINX-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
188 ; RV64IZFINX-NEXT: mv s0, a0
189 ; RV64IZFINX-NEXT: addi a0, sp, 12
190 ; RV64IZFINX-NEXT: call notdead
191 ; RV64IZFINX-NEXT: lw a0, 12(sp)
192 ; RV64IZFINX-NEXT: fadd.s a0, a0, s0
193 ; RV64IZFINX-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
194 ; RV64IZFINX-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
195 ; RV64IZFINX-NEXT: addi sp, sp, 32
196 ; RV64IZFINX-NEXT: ret
197 %1 = alloca float, align 4
198 call void @notdead(ptr %1)
199 %2 = load float, ptr %1
200 %3 = fadd float %2, %a ; force load in to FPR32
204 define dso_local void @fsw_stack(float %a, float %b) nounwind {
205 ; RV32IF-LABEL: fsw_stack:
207 ; RV32IF-NEXT: addi sp, sp, -16
208 ; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
209 ; RV32IF-NEXT: fadd.s fa5, fa0, fa1
210 ; RV32IF-NEXT: fsw fa5, 8(sp)
211 ; RV32IF-NEXT: addi a0, sp, 8
212 ; RV32IF-NEXT: call notdead
213 ; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
214 ; RV32IF-NEXT: addi sp, sp, 16
217 ; RV64IF-LABEL: fsw_stack:
219 ; RV64IF-NEXT: addi sp, sp, -16
220 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
221 ; RV64IF-NEXT: fadd.s fa5, fa0, fa1
222 ; RV64IF-NEXT: fsw fa5, 4(sp)
223 ; RV64IF-NEXT: addi a0, sp, 4
224 ; RV64IF-NEXT: call notdead
225 ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
226 ; RV64IF-NEXT: addi sp, sp, 16
229 ; RV32IZFINX-LABEL: fsw_stack:
230 ; RV32IZFINX: # %bb.0:
231 ; RV32IZFINX-NEXT: addi sp, sp, -16
232 ; RV32IZFINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
233 ; RV32IZFINX-NEXT: fadd.s a0, a0, a1
234 ; RV32IZFINX-NEXT: sw a0, 8(sp)
235 ; RV32IZFINX-NEXT: addi a0, sp, 8
236 ; RV32IZFINX-NEXT: call notdead
237 ; RV32IZFINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
238 ; RV32IZFINX-NEXT: addi sp, sp, 16
239 ; RV32IZFINX-NEXT: ret
241 ; RV64IZFINX-LABEL: fsw_stack:
242 ; RV64IZFINX: # %bb.0:
243 ; RV64IZFINX-NEXT: addi sp, sp, -16
244 ; RV64IZFINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
245 ; RV64IZFINX-NEXT: fadd.s a0, a0, a1
246 ; RV64IZFINX-NEXT: sw a0, 4(sp)
247 ; RV64IZFINX-NEXT: addi a0, sp, 4
248 ; RV64IZFINX-NEXT: call notdead
249 ; RV64IZFINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
250 ; RV64IZFINX-NEXT: addi sp, sp, 16
251 ; RV64IZFINX-NEXT: ret
252 %1 = fadd float %a, %b ; force store from FPR32
253 %2 = alloca float, align 4
254 store float %1, ptr %2
255 call void @notdead(ptr %2)