Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / float-mem.ll
blob3779d39a753e1e0f5a1a8616810dc637f4d2f938
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 {
12 ; CHECKIF-LABEL: flw:
13 ; CHECKIF:       # %bb.0:
14 ; CHECKIF-NEXT:    flw fa5, 0(a0)
15 ; CHECKIF-NEXT:    flw fa4, 12(a0)
16 ; CHECKIF-NEXT:    fadd.s fa0, fa5, fa4
17 ; CHECKIF-NEXT:    ret
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
29 ; soft float ABI
30   %4 = fadd float %1, %3
31   ret float %4
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
37 ; CHECKIF-LABEL: fsw:
38 ; CHECKIF:       # %bb.0:
39 ; CHECKIF-NEXT:    fadd.s fa5, fa0, fa1
40 ; CHECKIF-NEXT:    fsw fa5, 0(a0)
41 ; CHECKIF-NEXT:    fsw fa5, 32(a0)
42 ; CHECKIF-NEXT:    ret
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
54   ret void
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:
64 ; CHECKIF:       # %bb.0:
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)
72 ; CHECKIF-NEXT:    ret
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
90   ret float %1
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:
96 ; RV32IF:       # %bb.0:
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)
101 ; RV32IF-NEXT:    ret
103 ; RV64IF-LABEL: flw_fsw_constant:
104 ; RV64IF:       # %bb.0:
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)
110 ; RV64IF-NEXT:    ret
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
132   ret float %3
135 declare void @notdead(ptr)
137 define dso_local float @flw_stack(float %a) nounwind {
138 ; RV32IF-LABEL: flw_stack:
139 ; RV32IF:       # %bb.0:
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
151 ; RV32IF-NEXT:    ret
153 ; RV64IF-LABEL: flw_stack:
154 ; RV64IF:       # %bb.0:
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
166 ; RV64IF-NEXT:    ret
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
201   ret float %3
204 define dso_local void @fsw_stack(float %a, float %b) nounwind {
205 ; RV32IF-LABEL: fsw_stack:
206 ; RV32IF:       # %bb.0:
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
215 ; RV32IF-NEXT:    ret
217 ; RV64IF-LABEL: fsw_stack:
218 ; RV64IF:       # %bb.0:
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
227 ; RV64IF-NEXT:    ret
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)
256   ret void