[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / CodeGen / RISCV / fold-addi-loadstore.ll
blobb8dc7804c490823b148bb99a407b59df16c902a0
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -code-model=medium < %s \
5 ; RUN:   | FileCheck -check-prefix=RV32I-MEDIUM %s
6 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefix=RV64I %s
8 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -code-model=medium < %s \
9 ; RUN:   | FileCheck -check-prefix=RV64I-MEDIUM %s
10 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -code-model=large < %s \
11 ; RUN:   | FileCheck -check-prefix=RV64I-LARGE %s
13 ; We can often fold an ADDI into the offset of load/store instructions:
14 ;   (load (addi base, off1), off2) -> (load base, off1+off2)
15 ;   (store val, (addi base, off1), off2) -> (store val, base, off1+off2)
16 ; This is possible when the off1+off2 continues to fit the 12-bit immediate.
17 ; Check if we do the fold under various conditions. If off1 is (the low part of)
18 ; an address the fold's safety depends on the variable's alignment.
20 @g_0 = dso_local global i64 0
21 @g_1 = dso_local global i64 0, align 1
22 @g_2 = dso_local global i64 0, align 2
23 @g_4 = dso_local global i64 0, align 4
24 @g_8 = dso_local global i64 0, align 8
25 @g_16 = dso_local global i64 0, align 16
27 define dso_local i64 @load_g_0() nounwind {
28 ; RV32I-LABEL: load_g_0:
29 ; RV32I:       # %bb.0: # %entry
30 ; RV32I-NEXT:    lui a1, %hi(g_0)
31 ; RV32I-NEXT:    lw a0, %lo(g_0)(a1)
32 ; RV32I-NEXT:    lw a1, %lo(g_0+4)(a1)
33 ; RV32I-NEXT:    ret
35 ; RV32I-MEDIUM-LABEL: load_g_0:
36 ; RV32I-MEDIUM:       # %bb.0: # %entry
37 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi0:
38 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_0)
39 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi0)
40 ; RV32I-MEDIUM-NEXT:    lw a0, 0(a1)
41 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
42 ; RV32I-MEDIUM-NEXT:    ret
44 ; RV64I-LABEL: load_g_0:
45 ; RV64I:       # %bb.0: # %entry
46 ; RV64I-NEXT:    lui a0, %hi(g_0)
47 ; RV64I-NEXT:    ld a0, %lo(g_0)(a0)
48 ; RV64I-NEXT:    ret
50 ; RV64I-MEDIUM-LABEL: load_g_0:
51 ; RV64I-MEDIUM:       # %bb.0: # %entry
52 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi0:
53 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_0)
54 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
55 ; RV64I-MEDIUM-NEXT:    ret
57 ; RV64I-LARGE-LABEL: load_g_0:
58 ; RV64I-LARGE:       # %bb.0: # %entry
59 ; RV64I-LARGE-NEXT:  .Lpcrel_hi0:
60 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI0_0)
61 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
62 ; RV64I-LARGE-NEXT:    ld a0, 0(a0)
63 ; RV64I-LARGE-NEXT:    ret
64 entry:
65   %0 = load i64, ptr @g_0
66   ret i64 %0
69 define dso_local i64 @load_g_1() nounwind {
70 ; RV32I-LABEL: load_g_1:
71 ; RV32I:       # %bb.0: # %entry
72 ; RV32I-NEXT:    lui a1, %hi(g_1)
73 ; RV32I-NEXT:    lw a0, %lo(g_1)(a1)
74 ; RV32I-NEXT:    addi a1, a1, %lo(g_1)
75 ; RV32I-NEXT:    lw a1, 4(a1)
76 ; RV32I-NEXT:    ret
78 ; RV32I-MEDIUM-LABEL: load_g_1:
79 ; RV32I-MEDIUM:       # %bb.0: # %entry
80 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi1:
81 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_1)
82 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi1)
83 ; RV32I-MEDIUM-NEXT:    lw a0, 0(a1)
84 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
85 ; RV32I-MEDIUM-NEXT:    ret
87 ; RV64I-LABEL: load_g_1:
88 ; RV64I:       # %bb.0: # %entry
89 ; RV64I-NEXT:    lui a0, %hi(g_1)
90 ; RV64I-NEXT:    ld a0, %lo(g_1)(a0)
91 ; RV64I-NEXT:    ret
93 ; RV64I-MEDIUM-LABEL: load_g_1:
94 ; RV64I-MEDIUM:       # %bb.0: # %entry
95 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi1:
96 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_1)
97 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
98 ; RV64I-MEDIUM-NEXT:    ret
100 ; RV64I-LARGE-LABEL: load_g_1:
101 ; RV64I-LARGE:       # %bb.0: # %entry
102 ; RV64I-LARGE-NEXT:  .Lpcrel_hi1:
103 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI1_0)
104 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
105 ; RV64I-LARGE-NEXT:    ld a0, 0(a0)
106 ; RV64I-LARGE-NEXT:    ret
107 entry:
108   %0 = load i64, ptr @g_1
109   ret i64 %0
112 define dso_local i64 @load_g_2() nounwind {
113 ; RV32I-LABEL: load_g_2:
114 ; RV32I:       # %bb.0: # %entry
115 ; RV32I-NEXT:    lui a1, %hi(g_2)
116 ; RV32I-NEXT:    lw a0, %lo(g_2)(a1)
117 ; RV32I-NEXT:    addi a1, a1, %lo(g_2)
118 ; RV32I-NEXT:    lw a1, 4(a1)
119 ; RV32I-NEXT:    ret
121 ; RV32I-MEDIUM-LABEL: load_g_2:
122 ; RV32I-MEDIUM:       # %bb.0: # %entry
123 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi2:
124 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_2)
125 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi2)
126 ; RV32I-MEDIUM-NEXT:    lw a0, 0(a1)
127 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
128 ; RV32I-MEDIUM-NEXT:    ret
130 ; RV64I-LABEL: load_g_2:
131 ; RV64I:       # %bb.0: # %entry
132 ; RV64I-NEXT:    lui a0, %hi(g_2)
133 ; RV64I-NEXT:    ld a0, %lo(g_2)(a0)
134 ; RV64I-NEXT:    ret
136 ; RV64I-MEDIUM-LABEL: load_g_2:
137 ; RV64I-MEDIUM:       # %bb.0: # %entry
138 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi2:
139 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_2)
140 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
141 ; RV64I-MEDIUM-NEXT:    ret
143 ; RV64I-LARGE-LABEL: load_g_2:
144 ; RV64I-LARGE:       # %bb.0: # %entry
145 ; RV64I-LARGE-NEXT:  .Lpcrel_hi2:
146 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI2_0)
147 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
148 ; RV64I-LARGE-NEXT:    ld a0, 0(a0)
149 ; RV64I-LARGE-NEXT:    ret
150 entry:
151   %0 = load i64, ptr @g_2
152   ret i64 %0
155 define dso_local i64 @load_g_4() nounwind {
156 ; RV32I-LABEL: load_g_4:
157 ; RV32I:       # %bb.0: # %entry
158 ; RV32I-NEXT:    lui a1, %hi(g_4)
159 ; RV32I-NEXT:    lw a0, %lo(g_4)(a1)
160 ; RV32I-NEXT:    addi a1, a1, %lo(g_4)
161 ; RV32I-NEXT:    lw a1, 4(a1)
162 ; RV32I-NEXT:    ret
164 ; RV32I-MEDIUM-LABEL: load_g_4:
165 ; RV32I-MEDIUM:       # %bb.0: # %entry
166 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi3:
167 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_4)
168 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi3)
169 ; RV32I-MEDIUM-NEXT:    lw a0, 0(a1)
170 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
171 ; RV32I-MEDIUM-NEXT:    ret
173 ; RV64I-LABEL: load_g_4:
174 ; RV64I:       # %bb.0: # %entry
175 ; RV64I-NEXT:    lui a0, %hi(g_4)
176 ; RV64I-NEXT:    ld a0, %lo(g_4)(a0)
177 ; RV64I-NEXT:    ret
179 ; RV64I-MEDIUM-LABEL: load_g_4:
180 ; RV64I-MEDIUM:       # %bb.0: # %entry
181 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi3:
182 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_4)
183 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
184 ; RV64I-MEDIUM-NEXT:    ret
186 ; RV64I-LARGE-LABEL: load_g_4:
187 ; RV64I-LARGE:       # %bb.0: # %entry
188 ; RV64I-LARGE-NEXT:  .Lpcrel_hi3:
189 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI3_0)
190 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
191 ; RV64I-LARGE-NEXT:    ld a0, 0(a0)
192 ; RV64I-LARGE-NEXT:    ret
193 entry:
194   %0 = load i64, ptr @g_4
195   ret i64 %0
198 define dso_local i64 @load_g_8() nounwind {
199 ; RV32I-LABEL: load_g_8:
200 ; RV32I:       # %bb.0: # %entry
201 ; RV32I-NEXT:    lui a1, %hi(g_8)
202 ; RV32I-NEXT:    lw a0, %lo(g_8)(a1)
203 ; RV32I-NEXT:    lw a1, %lo(g_8+4)(a1)
204 ; RV32I-NEXT:    ret
206 ; RV32I-MEDIUM-LABEL: load_g_8:
207 ; RV32I-MEDIUM:       # %bb.0: # %entry
208 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi4:
209 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_8)
210 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi4)
211 ; RV32I-MEDIUM-NEXT:    lw a0, 0(a1)
212 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
213 ; RV32I-MEDIUM-NEXT:    ret
215 ; RV64I-LABEL: load_g_8:
216 ; RV64I:       # %bb.0: # %entry
217 ; RV64I-NEXT:    lui a0, %hi(g_8)
218 ; RV64I-NEXT:    ld a0, %lo(g_8)(a0)
219 ; RV64I-NEXT:    ret
221 ; RV64I-MEDIUM-LABEL: load_g_8:
222 ; RV64I-MEDIUM:       # %bb.0: # %entry
223 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi4:
224 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_8)
225 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
226 ; RV64I-MEDIUM-NEXT:    ret
228 ; RV64I-LARGE-LABEL: load_g_8:
229 ; RV64I-LARGE:       # %bb.0: # %entry
230 ; RV64I-LARGE-NEXT:  .Lpcrel_hi4:
231 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI4_0)
232 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
233 ; RV64I-LARGE-NEXT:    ld a0, 0(a0)
234 ; RV64I-LARGE-NEXT:    ret
235 entry:
236   %0 = load i64, ptr @g_8
237   ret i64 %0
240 define dso_local i64 @load_g_16() nounwind {
241 ; RV32I-LABEL: load_g_16:
242 ; RV32I:       # %bb.0: # %entry
243 ; RV32I-NEXT:    lui a1, %hi(g_16)
244 ; RV32I-NEXT:    lw a0, %lo(g_16)(a1)
245 ; RV32I-NEXT:    lw a1, %lo(g_16+4)(a1)
246 ; RV32I-NEXT:    ret
248 ; RV32I-MEDIUM-LABEL: load_g_16:
249 ; RV32I-MEDIUM:       # %bb.0: # %entry
250 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi5:
251 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_16)
252 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi5)
253 ; RV32I-MEDIUM-NEXT:    lw a0, 0(a1)
254 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
255 ; RV32I-MEDIUM-NEXT:    ret
257 ; RV64I-LABEL: load_g_16:
258 ; RV64I:       # %bb.0: # %entry
259 ; RV64I-NEXT:    lui a0, %hi(g_16)
260 ; RV64I-NEXT:    ld a0, %lo(g_16)(a0)
261 ; RV64I-NEXT:    ret
263 ; RV64I-MEDIUM-LABEL: load_g_16:
264 ; RV64I-MEDIUM:       # %bb.0: # %entry
265 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi5:
266 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_16)
267 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
268 ; RV64I-MEDIUM-NEXT:    ret
270 ; RV64I-LARGE-LABEL: load_g_16:
271 ; RV64I-LARGE:       # %bb.0: # %entry
272 ; RV64I-LARGE-NEXT:  .Lpcrel_hi5:
273 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI5_0)
274 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
275 ; RV64I-LARGE-NEXT:    ld a0, 0(a0)
276 ; RV64I-LARGE-NEXT:    ret
277 entry:
278   %0 = load i64, ptr @g_16
279   ret i64 %0
282 define dso_local void @store_g_4() nounwind {
283 ; RV32I-LABEL: store_g_4:
284 ; RV32I:       # %bb.0: # %entry
285 ; RV32I-NEXT:    lui a0, %hi(g_4)
286 ; RV32I-NEXT:    sw zero, %lo(g_4)(a0)
287 ; RV32I-NEXT:    addi a0, a0, %lo(g_4)
288 ; RV32I-NEXT:    sw zero, 4(a0)
289 ; RV32I-NEXT:    ret
291 ; RV32I-MEDIUM-LABEL: store_g_4:
292 ; RV32I-MEDIUM:       # %bb.0: # %entry
293 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi6:
294 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_4)
295 ; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi6)
296 ; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
297 ; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
298 ; RV32I-MEDIUM-NEXT:    ret
300 ; RV64I-LABEL: store_g_4:
301 ; RV64I:       # %bb.0: # %entry
302 ; RV64I-NEXT:    lui a0, %hi(g_4)
303 ; RV64I-NEXT:    sd zero, %lo(g_4)(a0)
304 ; RV64I-NEXT:    ret
306 ; RV64I-MEDIUM-LABEL: store_g_4:
307 ; RV64I-MEDIUM:       # %bb.0: # %entry
308 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi6:
309 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_4)
310 ; RV64I-MEDIUM-NEXT:    sd zero, %pcrel_lo(.Lpcrel_hi6)(a0)
311 ; RV64I-MEDIUM-NEXT:    ret
313 ; RV64I-LARGE-LABEL: store_g_4:
314 ; RV64I-LARGE:       # %bb.0: # %entry
315 ; RV64I-LARGE-NEXT:  .Lpcrel_hi6:
316 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI6_0)
317 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi6)(a0)
318 ; RV64I-LARGE-NEXT:    sd zero, 0(a0)
319 ; RV64I-LARGE-NEXT:    ret
320 entry:
321    store i64 0, ptr @g_4
322    ret void
325 define dso_local void @store_g_8() nounwind {
326 ; RV32I-LABEL: store_g_8:
327 ; RV32I:       # %bb.0: # %entry
328 ; RV32I-NEXT:    lui a0, %hi(g_8)
329 ; RV32I-NEXT:    sw zero, %lo(g_8+4)(a0)
330 ; RV32I-NEXT:    sw zero, %lo(g_8)(a0)
331 ; RV32I-NEXT:    ret
333 ; RV32I-MEDIUM-LABEL: store_g_8:
334 ; RV32I-MEDIUM:       # %bb.0: # %entry
335 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi7:
336 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_8)
337 ; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi7)
338 ; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
339 ; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
340 ; RV32I-MEDIUM-NEXT:    ret
342 ; RV64I-LABEL: store_g_8:
343 ; RV64I:       # %bb.0: # %entry
344 ; RV64I-NEXT:    lui a0, %hi(g_8)
345 ; RV64I-NEXT:    sd zero, %lo(g_8)(a0)
346 ; RV64I-NEXT:    ret
348 ; RV64I-MEDIUM-LABEL: store_g_8:
349 ; RV64I-MEDIUM:       # %bb.0: # %entry
350 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi7:
351 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_8)
352 ; RV64I-MEDIUM-NEXT:    sd zero, %pcrel_lo(.Lpcrel_hi7)(a0)
353 ; RV64I-MEDIUM-NEXT:    ret
355 ; RV64I-LARGE-LABEL: store_g_8:
356 ; RV64I-LARGE:       # %bb.0: # %entry
357 ; RV64I-LARGE-NEXT:  .Lpcrel_hi7:
358 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI7_0)
359 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi7)(a0)
360 ; RV64I-LARGE-NEXT:    sd zero, 0(a0)
361 ; RV64I-LARGE-NEXT:    ret
362 entry:
363    store i64 0, ptr @g_8
364    ret void
367 ; Check if we can fold ADDI into the offset of store instructions,
368 ; when store instructions is the root node in DAG.
370 @g_4_i32 = global i32 0, align 4
372 define dso_local void @inc_g_i32() nounwind {
373 ; RV32I-LABEL: inc_g_i32:
374 ; RV32I:       # %bb.0: # %entry
375 ; RV32I-NEXT:    lui a0, %hi(g_4_i32)
376 ; RV32I-NEXT:    lw a1, %lo(g_4_i32)(a0)
377 ; RV32I-NEXT:    addi a1, a1, 1
378 ; RV32I-NEXT:    sw a1, %lo(g_4_i32)(a0)
379 ; RV32I-NEXT:    ret
381 ; RV32I-MEDIUM-LABEL: inc_g_i32:
382 ; RV32I-MEDIUM:       # %bb.0: # %entry
383 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi8:
384 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_4_i32)
385 ; RV32I-MEDIUM-NEXT:    lw a1, %pcrel_lo(.Lpcrel_hi8)(a0)
386 ; RV32I-MEDIUM-NEXT:    addi a1, a1, 1
387 ; RV32I-MEDIUM-NEXT:    sw a1, %pcrel_lo(.Lpcrel_hi8)(a0)
388 ; RV32I-MEDIUM-NEXT:    ret
390 ; RV64I-LABEL: inc_g_i32:
391 ; RV64I:       # %bb.0: # %entry
392 ; RV64I-NEXT:    lui a0, %hi(g_4_i32)
393 ; RV64I-NEXT:    lw a1, %lo(g_4_i32)(a0)
394 ; RV64I-NEXT:    addi a1, a1, 1
395 ; RV64I-NEXT:    sw a1, %lo(g_4_i32)(a0)
396 ; RV64I-NEXT:    ret
398 ; RV64I-MEDIUM-LABEL: inc_g_i32:
399 ; RV64I-MEDIUM:       # %bb.0: # %entry
400 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi8:
401 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g_4_i32)
402 ; RV64I-MEDIUM-NEXT:    lw a1, %pcrel_lo(.Lpcrel_hi8)(a0)
403 ; RV64I-MEDIUM-NEXT:    addi a1, a1, 1
404 ; RV64I-MEDIUM-NEXT:    sw a1, %pcrel_lo(.Lpcrel_hi8)(a0)
405 ; RV64I-MEDIUM-NEXT:    ret
407 ; RV64I-LARGE-LABEL: inc_g_i32:
408 ; RV64I-LARGE:       # %bb.0: # %entry
409 ; RV64I-LARGE-NEXT:  .Lpcrel_hi8:
410 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI8_0)
411 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi8)(a0)
412 ; RV64I-LARGE-NEXT:    lw a1, 0(a0)
413 ; RV64I-LARGE-NEXT:    addi a1, a1, 1
414 ; RV64I-LARGE-NEXT:    sw a1, 0(a0)
415 ; RV64I-LARGE-NEXT:    ret
416 entry:
417   %0 = load i32, ptr @g_4_i32
418   %inc = add i32 %0, 1
419   store i32 %inc, ptr @g_4_i32
420   br label %if.end
422 if.end:
423   ret void
426 ; Check for folds in accesses to elements of an i32 array.
428 @ga = dso_local local_unnamed_addr global [2 x i32] zeroinitializer, align 4
430 define dso_local i32 @load_ga() local_unnamed_addr #0 {
431 ; RV32I-LABEL: load_ga:
432 ; RV32I:       # %bb.0:
433 ; RV32I-NEXT:    lui a0, %hi(ga+4)
434 ; RV32I-NEXT:    lw a0, %lo(ga+4)(a0)
435 ; RV32I-NEXT:    ret
437 ; RV32I-MEDIUM-LABEL: load_ga:
438 ; RV32I-MEDIUM:       # %bb.0:
439 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi9:
440 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(ga+4)
441 ; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi9)(a0)
442 ; RV32I-MEDIUM-NEXT:    ret
444 ; RV64I-LABEL: load_ga:
445 ; RV64I:       # %bb.0:
446 ; RV64I-NEXT:    lui a0, %hi(ga+4)
447 ; RV64I-NEXT:    lw a0, %lo(ga+4)(a0)
448 ; RV64I-NEXT:    ret
450 ; RV64I-MEDIUM-LABEL: load_ga:
451 ; RV64I-MEDIUM:       # %bb.0:
452 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi9:
453 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(ga+4)
454 ; RV64I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi9)(a0)
455 ; RV64I-MEDIUM-NEXT:    ret
457 ; RV64I-LARGE-LABEL: load_ga:
458 ; RV64I-LARGE:       # %bb.0:
459 ; RV64I-LARGE-NEXT:  .Lpcrel_hi9:
460 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI9_0)
461 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi9)(a0)
462 ; RV64I-LARGE-NEXT:    lw a0, 4(a0)
463 ; RV64I-LARGE-NEXT:    ret
464   %1 = load i32, ptr getelementptr inbounds ([2 x i32], ptr @ga, i32 0, i32 1), align 4
465   ret i32 %1
468 ; Check for folds in accesses to the second element of an i64 array.
470 @ga_8 = dso_local local_unnamed_addr global [2 x i64] zeroinitializer, align 8
471 @ga_16 = dso_local local_unnamed_addr global [2 x i64] zeroinitializer, align 16
473 define dso_local i64 @load_ga_8() nounwind {
474 ; RV32I-LABEL: load_ga_8:
475 ; RV32I:       # %bb.0: # %entry
476 ; RV32I-NEXT:    lui a1, %hi(ga_8)
477 ; RV32I-NEXT:    addi a1, a1, %lo(ga_8)
478 ; RV32I-NEXT:    lw a0, 8(a1)
479 ; RV32I-NEXT:    lw a1, 12(a1)
480 ; RV32I-NEXT:    ret
482 ; RV32I-MEDIUM-LABEL: load_ga_8:
483 ; RV32I-MEDIUM:       # %bb.0: # %entry
484 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi10:
485 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(ga_8)
486 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi10)
487 ; RV32I-MEDIUM-NEXT:    lw a0, 8(a1)
488 ; RV32I-MEDIUM-NEXT:    lw a1, 12(a1)
489 ; RV32I-MEDIUM-NEXT:    ret
491 ; RV64I-LABEL: load_ga_8:
492 ; RV64I:       # %bb.0: # %entry
493 ; RV64I-NEXT:    lui a0, %hi(ga_8+8)
494 ; RV64I-NEXT:    ld a0, %lo(ga_8+8)(a0)
495 ; RV64I-NEXT:    ret
497 ; RV64I-MEDIUM-LABEL: load_ga_8:
498 ; RV64I-MEDIUM:       # %bb.0: # %entry
499 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi10:
500 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(ga_8+8)
501 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi10)(a0)
502 ; RV64I-MEDIUM-NEXT:    ret
504 ; RV64I-LARGE-LABEL: load_ga_8:
505 ; RV64I-LARGE:       # %bb.0: # %entry
506 ; RV64I-LARGE-NEXT:  .Lpcrel_hi10:
507 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI10_0)
508 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi10)(a0)
509 ; RV64I-LARGE-NEXT:    ld a0, 8(a0)
510 ; RV64I-LARGE-NEXT:    ret
511 entry:
512   %0 = load i64, ptr getelementptr inbounds ([2 x i64], ptr @ga_8, i32 0, i32 1)
513   ret i64 %0
516 define dso_local i64 @load_ga_16() nounwind {
517 ; RV32I-LABEL: load_ga_16:
518 ; RV32I:       # %bb.0: # %entry
519 ; RV32I-NEXT:    lui a1, %hi(ga_16)
520 ; RV32I-NEXT:    lw a0, %lo(ga_16+8)(a1)
521 ; RV32I-NEXT:    lw a1, %lo(ga_16+12)(a1)
522 ; RV32I-NEXT:    ret
524 ; RV32I-MEDIUM-LABEL: load_ga_16:
525 ; RV32I-MEDIUM:       # %bb.0: # %entry
526 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi11:
527 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(ga_16)
528 ; RV32I-MEDIUM-NEXT:    addi a1, a0, %pcrel_lo(.Lpcrel_hi11)
529 ; RV32I-MEDIUM-NEXT:    lw a0, 8(a1)
530 ; RV32I-MEDIUM-NEXT:    lw a1, 12(a1)
531 ; RV32I-MEDIUM-NEXT:    ret
533 ; RV64I-LABEL: load_ga_16:
534 ; RV64I:       # %bb.0: # %entry
535 ; RV64I-NEXT:    lui a0, %hi(ga_16)
536 ; RV64I-NEXT:    ld a0, %lo(ga_16+8)(a0)
537 ; RV64I-NEXT:    ret
539 ; RV64I-MEDIUM-LABEL: load_ga_16:
540 ; RV64I-MEDIUM:       # %bb.0: # %entry
541 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi11:
542 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(ga_16+8)
543 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi11)(a0)
544 ; RV64I-MEDIUM-NEXT:    ret
546 ; RV64I-LARGE-LABEL: load_ga_16:
547 ; RV64I-LARGE:       # %bb.0: # %entry
548 ; RV64I-LARGE-NEXT:  .Lpcrel_hi11:
549 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.LCPI11_0)
550 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi11)(a0)
551 ; RV64I-LARGE-NEXT:    ld a0, 8(a0)
552 ; RV64I-LARGE-NEXT:    ret
553 entry:
554   %0 = load i64, ptr getelementptr inbounds ([2 x i64], ptr @ga_16, i32 0, i32 1)
555   ret i64 %0
558 ; Check for folds in accesses to block address.
559 define dso_local ptr @load_ba_1() nounwind {
560 ; RV32I-LABEL: load_ba_1:
561 ; RV32I:       # %bb.0: # %entry
562 ; RV32I-NEXT:  .Ltmp0: # Block address taken
563 ; RV32I-NEXT:  # %bb.1: # %label
564 ; RV32I-NEXT:    lui a0, %hi(.Ltmp0)
565 ; RV32I-NEXT:    lw a0, %lo(.Ltmp0)(a0)
566 ; RV32I-NEXT:    ret
568 ; RV32I-MEDIUM-LABEL: load_ba_1:
569 ; RV32I-MEDIUM:       # %bb.0: # %entry
570 ; RV32I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
571 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
572 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi12:
573 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
574 ; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi12)(a0)
575 ; RV32I-MEDIUM-NEXT:    ret
577 ; RV64I-LABEL: load_ba_1:
578 ; RV64I:       # %bb.0: # %entry
579 ; RV64I-NEXT:  .Ltmp0: # Block address taken
580 ; RV64I-NEXT:  # %bb.1: # %label
581 ; RV64I-NEXT:    lui a0, %hi(.Ltmp0)
582 ; RV64I-NEXT:    ld a0, %lo(.Ltmp0)(a0)
583 ; RV64I-NEXT:    ret
585 ; RV64I-MEDIUM-LABEL: load_ba_1:
586 ; RV64I-MEDIUM:       # %bb.0: # %entry
587 ; RV64I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
588 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
589 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi12:
590 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
591 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi12)(a0)
592 ; RV64I-MEDIUM-NEXT:    ret
594 ; RV64I-LARGE-LABEL: load_ba_1:
595 ; RV64I-LARGE:       # %bb.0: # %entry
596 ; RV64I-LARGE-NEXT:  .Ltmp0: # Block address taken
597 ; RV64I-LARGE-NEXT:  # %bb.1: # %label
598 ; RV64I-LARGE-NEXT:  .Lpcrel_hi12:
599 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
600 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi12)(a0)
601 ; RV64I-LARGE-NEXT:    ret
602 entry:
603   br label %label
604 label:
605   %0 = load ptr, ptr blockaddress(@load_ba_1, %label)
606   ret ptr %0
609 define dso_local ptr @load_ba_2() nounwind {
610 ; RV32I-LABEL: load_ba_2:
611 ; RV32I:       # %bb.0: # %entry
612 ; RV32I-NEXT:  .Ltmp1: # Block address taken
613 ; RV32I-NEXT:  # %bb.1: # %label
614 ; RV32I-NEXT:    lui a0, %hi(.Ltmp1+8)
615 ; RV32I-NEXT:    lw a0, %lo(.Ltmp1+8)(a0)
616 ; RV32I-NEXT:    ret
618 ; RV32I-MEDIUM-LABEL: load_ba_2:
619 ; RV32I-MEDIUM:       # %bb.0: # %entry
620 ; RV32I-MEDIUM-NEXT:  .Ltmp1: # Block address taken
621 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
622 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi13:
623 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+8)
624 ; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi13)(a0)
625 ; RV32I-MEDIUM-NEXT:    ret
627 ; RV64I-LABEL: load_ba_2:
628 ; RV64I:       # %bb.0: # %entry
629 ; RV64I-NEXT:  .Ltmp1: # Block address taken
630 ; RV64I-NEXT:  # %bb.1: # %label
631 ; RV64I-NEXT:    lui a0, %hi(.Ltmp1+8)
632 ; RV64I-NEXT:    ld a0, %lo(.Ltmp1+8)(a0)
633 ; RV64I-NEXT:    ret
635 ; RV64I-MEDIUM-LABEL: load_ba_2:
636 ; RV64I-MEDIUM:       # %bb.0: # %entry
637 ; RV64I-MEDIUM-NEXT:  .Ltmp1: # Block address taken
638 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
639 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi13:
640 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+8)
641 ; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
642 ; RV64I-MEDIUM-NEXT:    ret
644 ; RV64I-LARGE-LABEL: load_ba_2:
645 ; RV64I-LARGE:       # %bb.0: # %entry
646 ; RV64I-LARGE-NEXT:  .Ltmp1: # Block address taken
647 ; RV64I-LARGE-NEXT:  # %bb.1: # %label
648 ; RV64I-LARGE-NEXT:  .Lpcrel_hi13:
649 ; RV64I-LARGE-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+8)
650 ; RV64I-LARGE-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
651 ; RV64I-LARGE-NEXT:    ret
652 entry:
653   br label %label
654 label:
655   %0 = load ptr, ptr getelementptr inbounds (i8, ptr blockaddress(@load_ba_2, %label), i32 8)
656   ret ptr %0
659 ; Check for folds in accesses to thread-local variables.
661 @tl_4 = dso_local thread_local global i64 0, align 4
662 @tl_8 = dso_local thread_local global i64 0, align 8
664 define dso_local i64 @load_tl_4() nounwind {
665 ; RV32I-LABEL: load_tl_4:
666 ; RV32I:       # %bb.0: # %entry
667 ; RV32I-NEXT:    lui a0, %tprel_hi(tl_4)
668 ; RV32I-NEXT:    add a1, a0, tp, %tprel_add(tl_4)
669 ; RV32I-NEXT:    lw a0, %tprel_lo(tl_4)(a1)
670 ; RV32I-NEXT:    addi a1, a1, %tprel_lo(tl_4)
671 ; RV32I-NEXT:    lw a1, 4(a1)
672 ; RV32I-NEXT:    ret
674 ; RV32I-MEDIUM-LABEL: load_tl_4:
675 ; RV32I-MEDIUM:       # %bb.0: # %entry
676 ; RV32I-MEDIUM-NEXT:    lui a0, %tprel_hi(tl_4)
677 ; RV32I-MEDIUM-NEXT:    add a1, a0, tp, %tprel_add(tl_4)
678 ; RV32I-MEDIUM-NEXT:    lw a0, %tprel_lo(tl_4)(a1)
679 ; RV32I-MEDIUM-NEXT:    addi a1, a1, %tprel_lo(tl_4)
680 ; RV32I-MEDIUM-NEXT:    lw a1, 4(a1)
681 ; RV32I-MEDIUM-NEXT:    ret
683 ; RV64I-LABEL: load_tl_4:
684 ; RV64I:       # %bb.0: # %entry
685 ; RV64I-NEXT:    lui a0, %tprel_hi(tl_4)
686 ; RV64I-NEXT:    add a0, a0, tp, %tprel_add(tl_4)
687 ; RV64I-NEXT:    ld a0, %tprel_lo(tl_4)(a0)
688 ; RV64I-NEXT:    ret
690 ; RV64I-MEDIUM-LABEL: load_tl_4:
691 ; RV64I-MEDIUM:       # %bb.0: # %entry
692 ; RV64I-MEDIUM-NEXT:    lui a0, %tprel_hi(tl_4)
693 ; RV64I-MEDIUM-NEXT:    add a0, a0, tp, %tprel_add(tl_4)
694 ; RV64I-MEDIUM-NEXT:    ld a0, %tprel_lo(tl_4)(a0)
695 ; RV64I-MEDIUM-NEXT:    ret
697 ; RV64I-LARGE-LABEL: load_tl_4:
698 ; RV64I-LARGE:       # %bb.0: # %entry
699 ; RV64I-LARGE-NEXT:    lui a0, %tprel_hi(tl_4)
700 ; RV64I-LARGE-NEXT:    add a0, a0, tp, %tprel_add(tl_4)
701 ; RV64I-LARGE-NEXT:    ld a0, %tprel_lo(tl_4)(a0)
702 ; RV64I-LARGE-NEXT:    ret
703 entry:
704   %0 = load i64, ptr @tl_4
705   ret i64 %0
708 define dso_local i64 @load_tl_8() nounwind {
709 ; RV32I-LABEL: load_tl_8:
710 ; RV32I:       # %bb.0: # %entry
711 ; RV32I-NEXT:    lui a0, %tprel_hi(tl_8)
712 ; RV32I-NEXT:    add a1, a0, tp, %tprel_add(tl_8)
713 ; RV32I-NEXT:    lw a0, %tprel_lo(tl_8)(a1)
714 ; RV32I-NEXT:    lw a1, %tprel_lo(tl_8+4)(a1)
715 ; RV32I-NEXT:    ret
717 ; RV32I-MEDIUM-LABEL: load_tl_8:
718 ; RV32I-MEDIUM:       # %bb.0: # %entry
719 ; RV32I-MEDIUM-NEXT:    lui a0, %tprel_hi(tl_8)
720 ; RV32I-MEDIUM-NEXT:    add a1, a0, tp, %tprel_add(tl_8)
721 ; RV32I-MEDIUM-NEXT:    lw a0, %tprel_lo(tl_8)(a1)
722 ; RV32I-MEDIUM-NEXT:    lw a1, %tprel_lo(tl_8+4)(a1)
723 ; RV32I-MEDIUM-NEXT:    ret
725 ; RV64I-LABEL: load_tl_8:
726 ; RV64I:       # %bb.0: # %entry
727 ; RV64I-NEXT:    lui a0, %tprel_hi(tl_8)
728 ; RV64I-NEXT:    add a0, a0, tp, %tprel_add(tl_8)
729 ; RV64I-NEXT:    ld a0, %tprel_lo(tl_8)(a0)
730 ; RV64I-NEXT:    ret
732 ; RV64I-MEDIUM-LABEL: load_tl_8:
733 ; RV64I-MEDIUM:       # %bb.0: # %entry
734 ; RV64I-MEDIUM-NEXT:    lui a0, %tprel_hi(tl_8)
735 ; RV64I-MEDIUM-NEXT:    add a0, a0, tp, %tprel_add(tl_8)
736 ; RV64I-MEDIUM-NEXT:    ld a0, %tprel_lo(tl_8)(a0)
737 ; RV64I-MEDIUM-NEXT:    ret
739 ; RV64I-LARGE-LABEL: load_tl_8:
740 ; RV64I-LARGE:       # %bb.0: # %entry
741 ; RV64I-LARGE-NEXT:    lui a0, %tprel_hi(tl_8)
742 ; RV64I-LARGE-NEXT:    add a0, a0, tp, %tprel_add(tl_8)
743 ; RV64I-LARGE-NEXT:    ld a0, %tprel_lo(tl_8)(a0)
744 ; RV64I-LARGE-NEXT:    ret
745 entry:
746   %0 = load i64, ptr @tl_8
747   ret i64 %0
750 define dso_local i64 @load_const_ok() nounwind {
751 ; RV32I-LABEL: load_const_ok:
752 ; RV32I:       # %bb.0: # %entry
753 ; RV32I-NEXT:    lw a0, 2040(zero)
754 ; RV32I-NEXT:    lw a1, 2044(zero)
755 ; RV32I-NEXT:    ret
757 ; RV32I-MEDIUM-LABEL: load_const_ok:
758 ; RV32I-MEDIUM:       # %bb.0: # %entry
759 ; RV32I-MEDIUM-NEXT:    lw a0, 2040(zero)
760 ; RV32I-MEDIUM-NEXT:    lw a1, 2044(zero)
761 ; RV32I-MEDIUM-NEXT:    ret
763 ; RV64I-LABEL: load_const_ok:
764 ; RV64I:       # %bb.0: # %entry
765 ; RV64I-NEXT:    ld a0, 2040(zero)
766 ; RV64I-NEXT:    ret
768 ; RV64I-MEDIUM-LABEL: load_const_ok:
769 ; RV64I-MEDIUM:       # %bb.0: # %entry
770 ; RV64I-MEDIUM-NEXT:    ld a0, 2040(zero)
771 ; RV64I-MEDIUM-NEXT:    ret
773 ; RV64I-LARGE-LABEL: load_const_ok:
774 ; RV64I-LARGE:       # %bb.0: # %entry
775 ; RV64I-LARGE-NEXT:    ld a0, 2040(zero)
776 ; RV64I-LARGE-NEXT:    ret
777 entry:
778   %0 = load i64, ptr inttoptr (i32 2040 to ptr)
779   ret i64 %0
782 define dso_local i64 @load_cost_overflow() nounwind {
783 ; RV32I-LABEL: load_cost_overflow:
784 ; RV32I:       # %bb.0: # %entry
785 ; RV32I-NEXT:    lui a0, 1
786 ; RV32I-NEXT:    lw a1, -2048(a0)
787 ; RV32I-NEXT:    lw a0, 2044(zero)
788 ; RV32I-NEXT:    ret
790 ; RV32I-MEDIUM-LABEL: load_cost_overflow:
791 ; RV32I-MEDIUM:       # %bb.0: # %entry
792 ; RV32I-MEDIUM-NEXT:    lui a0, 1
793 ; RV32I-MEDIUM-NEXT:    lw a1, -2048(a0)
794 ; RV32I-MEDIUM-NEXT:    lw a0, 2044(zero)
795 ; RV32I-MEDIUM-NEXT:    ret
797 ; RV64I-LABEL: load_cost_overflow:
798 ; RV64I:       # %bb.0: # %entry
799 ; RV64I-NEXT:    ld a0, 2044(zero)
800 ; RV64I-NEXT:    ret
802 ; RV64I-MEDIUM-LABEL: load_cost_overflow:
803 ; RV64I-MEDIUM:       # %bb.0: # %entry
804 ; RV64I-MEDIUM-NEXT:    ld a0, 2044(zero)
805 ; RV64I-MEDIUM-NEXT:    ret
807 ; RV64I-LARGE-LABEL: load_cost_overflow:
808 ; RV64I-LARGE:       # %bb.0: # %entry
809 ; RV64I-LARGE-NEXT:    ld a0, 2044(zero)
810 ; RV64I-LARGE-NEXT:    ret
811 entry:
812   %0 = load i64, ptr inttoptr (i64 2044 to ptr)
813   ret i64 %0
816 define dso_local i32 @load_const_medium() nounwind {
817 ; RV32I-LABEL: load_const_medium:
818 ; RV32I:       # %bb.0: # %entry
819 ; RV32I-NEXT:    lui a0, 1
820 ; RV32I-NEXT:    lw a0, -16(a0)
821 ; RV32I-NEXT:    ret
823 ; RV32I-MEDIUM-LABEL: load_const_medium:
824 ; RV32I-MEDIUM:       # %bb.0: # %entry
825 ; RV32I-MEDIUM-NEXT:    lui a0, 1
826 ; RV32I-MEDIUM-NEXT:    lw a0, -16(a0)
827 ; RV32I-MEDIUM-NEXT:    ret
829 ; RV64I-LABEL: load_const_medium:
830 ; RV64I:       # %bb.0: # %entry
831 ; RV64I-NEXT:    lui a0, 1
832 ; RV64I-NEXT:    lw a0, -16(a0)
833 ; RV64I-NEXT:    ret
835 ; RV64I-MEDIUM-LABEL: load_const_medium:
836 ; RV64I-MEDIUM:       # %bb.0: # %entry
837 ; RV64I-MEDIUM-NEXT:    lui a0, 1
838 ; RV64I-MEDIUM-NEXT:    lw a0, -16(a0)
839 ; RV64I-MEDIUM-NEXT:    ret
841 ; RV64I-LARGE-LABEL: load_const_medium:
842 ; RV64I-LARGE:       # %bb.0: # %entry
843 ; RV64I-LARGE-NEXT:    lui a0, 1
844 ; RV64I-LARGE-NEXT:    lw a0, -16(a0)
845 ; RV64I-LARGE-NEXT:    ret
846 entry:
847   %0 = load i32, ptr inttoptr (i64 4080 to ptr)
848   ret i32 %0
851 ; The constant here is 0x7ffff800, this value requires LUI+ADDIW on RV64,
852 ; LUI+ADDI would produce a different constant so we can't fold into the load
853 ; offset.
854 define dso_local i32 @load_const_large() nounwind {
855 ; RV32I-LABEL: load_const_large:
856 ; RV32I:       # %bb.0: # %entry
857 ; RV32I-NEXT:    lui a0, 524288
858 ; RV32I-NEXT:    lw a0, -2048(a0)
859 ; RV32I-NEXT:    ret
861 ; RV32I-MEDIUM-LABEL: load_const_large:
862 ; RV32I-MEDIUM:       # %bb.0: # %entry
863 ; RV32I-MEDIUM-NEXT:    lui a0, 524288
864 ; RV32I-MEDIUM-NEXT:    lw a0, -2048(a0)
865 ; RV32I-MEDIUM-NEXT:    ret
867 ; RV64I-LABEL: load_const_large:
868 ; RV64I:       # %bb.0: # %entry
869 ; RV64I-NEXT:    lui a0, 524288
870 ; RV64I-NEXT:    addiw a0, a0, -2048
871 ; RV64I-NEXT:    lw a0, 0(a0)
872 ; RV64I-NEXT:    ret
874 ; RV64I-MEDIUM-LABEL: load_const_large:
875 ; RV64I-MEDIUM:       # %bb.0: # %entry
876 ; RV64I-MEDIUM-NEXT:    lui a0, 524288
877 ; RV64I-MEDIUM-NEXT:    addiw a0, a0, -2048
878 ; RV64I-MEDIUM-NEXT:    lw a0, 0(a0)
879 ; RV64I-MEDIUM-NEXT:    ret
881 ; RV64I-LARGE-LABEL: load_const_large:
882 ; RV64I-LARGE:       # %bb.0: # %entry
883 ; RV64I-LARGE-NEXT:    lui a0, 524288
884 ; RV64I-LARGE-NEXT:    addiw a0, a0, -2048
885 ; RV64I-LARGE-NEXT:    lw a0, 0(a0)
886 ; RV64I-LARGE-NEXT:    ret
887 entry:
888   %0 = load i32, ptr inttoptr (i64 2147481600 to ptr)
889   ret i32 %0
892 %struct.S = type { i64, i64 }
894 define i64 @fold_addi_from_different_bb(i64 %k, i64 %n, ptr %a) nounwind {
895 ; RV32I-LABEL: fold_addi_from_different_bb:
896 ; RV32I:       # %bb.0: # %entry
897 ; RV32I-NEXT:    addi sp, sp, -48
898 ; RV32I-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
899 ; RV32I-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
900 ; RV32I-NEXT:    sw s1, 36(sp) # 4-byte Folded Spill
901 ; RV32I-NEXT:    sw s2, 32(sp) # 4-byte Folded Spill
902 ; RV32I-NEXT:    sw s3, 28(sp) # 4-byte Folded Spill
903 ; RV32I-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
904 ; RV32I-NEXT:    sw s5, 20(sp) # 4-byte Folded Spill
905 ; RV32I-NEXT:    sw s6, 16(sp) # 4-byte Folded Spill
906 ; RV32I-NEXT:    sw s7, 12(sp) # 4-byte Folded Spill
907 ; RV32I-NEXT:    mv s0, a4
908 ; RV32I-NEXT:    mv s1, a3
909 ; RV32I-NEXT:    mv s2, a2
910 ; RV32I-NEXT:    beqz a3, .LBB20_3
911 ; RV32I-NEXT:  # %bb.1: # %entry
912 ; RV32I-NEXT:    slti a1, s1, 0
913 ; RV32I-NEXT:    beqz a1, .LBB20_4
914 ; RV32I-NEXT:  .LBB20_2:
915 ; RV32I-NEXT:    li s3, 0
916 ; RV32I-NEXT:    li s4, 0
917 ; RV32I-NEXT:    j .LBB20_6
918 ; RV32I-NEXT:  .LBB20_3:
919 ; RV32I-NEXT:    seqz a1, s2
920 ; RV32I-NEXT:    bnez a1, .LBB20_2
921 ; RV32I-NEXT:  .LBB20_4: # %for.body.lr.ph
922 ; RV32I-NEXT:    li s5, 0
923 ; RV32I-NEXT:    li s6, 0
924 ; RV32I-NEXT:    li s3, 0
925 ; RV32I-NEXT:    li s4, 0
926 ; RV32I-NEXT:    slli a0, a0, 4
927 ; RV32I-NEXT:    add s7, s0, a0
928 ; RV32I-NEXT:  .LBB20_5: # %for.body
929 ; RV32I-NEXT:    # =>This Inner Loop Header: Depth=1
930 ; RV32I-NEXT:    mv a0, s0
931 ; RV32I-NEXT:    call f
932 ; RV32I-NEXT:    lw a0, 8(s7)
933 ; RV32I-NEXT:    lw a1, 12(s7)
934 ; RV32I-NEXT:    addi s5, s5, 1
935 ; RV32I-NEXT:    seqz a2, s5
936 ; RV32I-NEXT:    add s6, s6, a2
937 ; RV32I-NEXT:    xor a2, s5, s2
938 ; RV32I-NEXT:    add a1, a1, s4
939 ; RV32I-NEXT:    xor a3, s6, s1
940 ; RV32I-NEXT:    or a2, a2, a3
941 ; RV32I-NEXT:    add s3, a0, s3
942 ; RV32I-NEXT:    sltu s4, s3, a0
943 ; RV32I-NEXT:    add s4, a1, s4
944 ; RV32I-NEXT:    bnez a2, .LBB20_5
945 ; RV32I-NEXT:  .LBB20_6: # %for.cond.cleanup
946 ; RV32I-NEXT:    mv a0, s3
947 ; RV32I-NEXT:    mv a1, s4
948 ; RV32I-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
949 ; RV32I-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
950 ; RV32I-NEXT:    lw s1, 36(sp) # 4-byte Folded Reload
951 ; RV32I-NEXT:    lw s2, 32(sp) # 4-byte Folded Reload
952 ; RV32I-NEXT:    lw s3, 28(sp) # 4-byte Folded Reload
953 ; RV32I-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
954 ; RV32I-NEXT:    lw s5, 20(sp) # 4-byte Folded Reload
955 ; RV32I-NEXT:    lw s6, 16(sp) # 4-byte Folded Reload
956 ; RV32I-NEXT:    lw s7, 12(sp) # 4-byte Folded Reload
957 ; RV32I-NEXT:    addi sp, sp, 48
958 ; RV32I-NEXT:    ret
960 ; RV32I-MEDIUM-LABEL: fold_addi_from_different_bb:
961 ; RV32I-MEDIUM:       # %bb.0: # %entry
962 ; RV32I-MEDIUM-NEXT:    addi sp, sp, -48
963 ; RV32I-MEDIUM-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
964 ; RV32I-MEDIUM-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
965 ; RV32I-MEDIUM-NEXT:    sw s1, 36(sp) # 4-byte Folded Spill
966 ; RV32I-MEDIUM-NEXT:    sw s2, 32(sp) # 4-byte Folded Spill
967 ; RV32I-MEDIUM-NEXT:    sw s3, 28(sp) # 4-byte Folded Spill
968 ; RV32I-MEDIUM-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
969 ; RV32I-MEDIUM-NEXT:    sw s5, 20(sp) # 4-byte Folded Spill
970 ; RV32I-MEDIUM-NEXT:    sw s6, 16(sp) # 4-byte Folded Spill
971 ; RV32I-MEDIUM-NEXT:    sw s7, 12(sp) # 4-byte Folded Spill
972 ; RV32I-MEDIUM-NEXT:    mv s0, a4
973 ; RV32I-MEDIUM-NEXT:    mv s1, a3
974 ; RV32I-MEDIUM-NEXT:    mv s2, a2
975 ; RV32I-MEDIUM-NEXT:    beqz a3, .LBB20_3
976 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %entry
977 ; RV32I-MEDIUM-NEXT:    slti a1, s1, 0
978 ; RV32I-MEDIUM-NEXT:    beqz a1, .LBB20_4
979 ; RV32I-MEDIUM-NEXT:  .LBB20_2:
980 ; RV32I-MEDIUM-NEXT:    li s3, 0
981 ; RV32I-MEDIUM-NEXT:    li s4, 0
982 ; RV32I-MEDIUM-NEXT:    j .LBB20_6
983 ; RV32I-MEDIUM-NEXT:  .LBB20_3:
984 ; RV32I-MEDIUM-NEXT:    seqz a1, s2
985 ; RV32I-MEDIUM-NEXT:    bnez a1, .LBB20_2
986 ; RV32I-MEDIUM-NEXT:  .LBB20_4: # %for.body.lr.ph
987 ; RV32I-MEDIUM-NEXT:    li s5, 0
988 ; RV32I-MEDIUM-NEXT:    li s6, 0
989 ; RV32I-MEDIUM-NEXT:    li s3, 0
990 ; RV32I-MEDIUM-NEXT:    li s4, 0
991 ; RV32I-MEDIUM-NEXT:    slli a0, a0, 4
992 ; RV32I-MEDIUM-NEXT:    add s7, s0, a0
993 ; RV32I-MEDIUM-NEXT:  .LBB20_5: # %for.body
994 ; RV32I-MEDIUM-NEXT:    # =>This Inner Loop Header: Depth=1
995 ; RV32I-MEDIUM-NEXT:    mv a0, s0
996 ; RV32I-MEDIUM-NEXT:    call f
997 ; RV32I-MEDIUM-NEXT:    lw a0, 8(s7)
998 ; RV32I-MEDIUM-NEXT:    lw a1, 12(s7)
999 ; RV32I-MEDIUM-NEXT:    addi s5, s5, 1
1000 ; RV32I-MEDIUM-NEXT:    seqz a2, s5
1001 ; RV32I-MEDIUM-NEXT:    add s6, s6, a2
1002 ; RV32I-MEDIUM-NEXT:    xor a2, s5, s2
1003 ; RV32I-MEDIUM-NEXT:    add a1, a1, s4
1004 ; RV32I-MEDIUM-NEXT:    xor a3, s6, s1
1005 ; RV32I-MEDIUM-NEXT:    or a2, a2, a3
1006 ; RV32I-MEDIUM-NEXT:    add s3, a0, s3
1007 ; RV32I-MEDIUM-NEXT:    sltu s4, s3, a0
1008 ; RV32I-MEDIUM-NEXT:    add s4, a1, s4
1009 ; RV32I-MEDIUM-NEXT:    bnez a2, .LBB20_5
1010 ; RV32I-MEDIUM-NEXT:  .LBB20_6: # %for.cond.cleanup
1011 ; RV32I-MEDIUM-NEXT:    mv a0, s3
1012 ; RV32I-MEDIUM-NEXT:    mv a1, s4
1013 ; RV32I-MEDIUM-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
1014 ; RV32I-MEDIUM-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
1015 ; RV32I-MEDIUM-NEXT:    lw s1, 36(sp) # 4-byte Folded Reload
1016 ; RV32I-MEDIUM-NEXT:    lw s2, 32(sp) # 4-byte Folded Reload
1017 ; RV32I-MEDIUM-NEXT:    lw s3, 28(sp) # 4-byte Folded Reload
1018 ; RV32I-MEDIUM-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
1019 ; RV32I-MEDIUM-NEXT:    lw s5, 20(sp) # 4-byte Folded Reload
1020 ; RV32I-MEDIUM-NEXT:    lw s6, 16(sp) # 4-byte Folded Reload
1021 ; RV32I-MEDIUM-NEXT:    lw s7, 12(sp) # 4-byte Folded Reload
1022 ; RV32I-MEDIUM-NEXT:    addi sp, sp, 48
1023 ; RV32I-MEDIUM-NEXT:    ret
1025 ; RV64I-LABEL: fold_addi_from_different_bb:
1026 ; RV64I:       # %bb.0: # %entry
1027 ; RV64I-NEXT:    addi sp, sp, -48
1028 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1029 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1030 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1031 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1032 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1033 ; RV64I-NEXT:    blez a1, .LBB20_3
1034 ; RV64I-NEXT:  # %bb.1: # %for.body.lr.ph
1035 ; RV64I-NEXT:    mv s0, a2
1036 ; RV64I-NEXT:    mv s1, a1
1037 ; RV64I-NEXT:    li s2, 0
1038 ; RV64I-NEXT:    slli a0, a0, 4
1039 ; RV64I-NEXT:    add s3, a2, a0
1040 ; RV64I-NEXT:  .LBB20_2: # %for.body
1041 ; RV64I-NEXT:    # =>This Inner Loop Header: Depth=1
1042 ; RV64I-NEXT:    mv a0, s0
1043 ; RV64I-NEXT:    call f
1044 ; RV64I-NEXT:    ld a0, 8(s3)
1045 ; RV64I-NEXT:    addi s1, s1, -1
1046 ; RV64I-NEXT:    add s2, a0, s2
1047 ; RV64I-NEXT:    bnez s1, .LBB20_2
1048 ; RV64I-NEXT:    j .LBB20_4
1049 ; RV64I-NEXT:  .LBB20_3:
1050 ; RV64I-NEXT:    li s2, 0
1051 ; RV64I-NEXT:  .LBB20_4: # %for.cond.cleanup
1052 ; RV64I-NEXT:    mv a0, s2
1053 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1054 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1055 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1056 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1057 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1058 ; RV64I-NEXT:    addi sp, sp, 48
1059 ; RV64I-NEXT:    ret
1061 ; RV64I-MEDIUM-LABEL: fold_addi_from_different_bb:
1062 ; RV64I-MEDIUM:       # %bb.0: # %entry
1063 ; RV64I-MEDIUM-NEXT:    addi sp, sp, -48
1064 ; RV64I-MEDIUM-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1065 ; RV64I-MEDIUM-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1066 ; RV64I-MEDIUM-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1067 ; RV64I-MEDIUM-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1068 ; RV64I-MEDIUM-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1069 ; RV64I-MEDIUM-NEXT:    blez a1, .LBB20_3
1070 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %for.body.lr.ph
1071 ; RV64I-MEDIUM-NEXT:    mv s0, a2
1072 ; RV64I-MEDIUM-NEXT:    mv s1, a1
1073 ; RV64I-MEDIUM-NEXT:    li s2, 0
1074 ; RV64I-MEDIUM-NEXT:    slli a0, a0, 4
1075 ; RV64I-MEDIUM-NEXT:    add s3, a2, a0
1076 ; RV64I-MEDIUM-NEXT:  .LBB20_2: # %for.body
1077 ; RV64I-MEDIUM-NEXT:    # =>This Inner Loop Header: Depth=1
1078 ; RV64I-MEDIUM-NEXT:    mv a0, s0
1079 ; RV64I-MEDIUM-NEXT:    call f
1080 ; RV64I-MEDIUM-NEXT:    ld a0, 8(s3)
1081 ; RV64I-MEDIUM-NEXT:    addi s1, s1, -1
1082 ; RV64I-MEDIUM-NEXT:    add s2, a0, s2
1083 ; RV64I-MEDIUM-NEXT:    bnez s1, .LBB20_2
1084 ; RV64I-MEDIUM-NEXT:    j .LBB20_4
1085 ; RV64I-MEDIUM-NEXT:  .LBB20_3:
1086 ; RV64I-MEDIUM-NEXT:    li s2, 0
1087 ; RV64I-MEDIUM-NEXT:  .LBB20_4: # %for.cond.cleanup
1088 ; RV64I-MEDIUM-NEXT:    mv a0, s2
1089 ; RV64I-MEDIUM-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1090 ; RV64I-MEDIUM-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1091 ; RV64I-MEDIUM-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1092 ; RV64I-MEDIUM-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1093 ; RV64I-MEDIUM-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1094 ; RV64I-MEDIUM-NEXT:    addi sp, sp, 48
1095 ; RV64I-MEDIUM-NEXT:    ret
1097 ; RV64I-LARGE-LABEL: fold_addi_from_different_bb:
1098 ; RV64I-LARGE:       # %bb.0: # %entry
1099 ; RV64I-LARGE-NEXT:    addi sp, sp, -48
1100 ; RV64I-LARGE-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1101 ; RV64I-LARGE-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1102 ; RV64I-LARGE-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1103 ; RV64I-LARGE-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1104 ; RV64I-LARGE-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1105 ; RV64I-LARGE-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1106 ; RV64I-LARGE-NEXT:    blez a1, .LBB20_3
1107 ; RV64I-LARGE-NEXT:  # %bb.1: # %for.body.lr.ph
1108 ; RV64I-LARGE-NEXT:    mv s0, a2
1109 ; RV64I-LARGE-NEXT:    mv s1, a1
1110 ; RV64I-LARGE-NEXT:    li s2, 0
1111 ; RV64I-LARGE-NEXT:  .Lpcrel_hi14:
1112 ; RV64I-LARGE-NEXT:    auipc a1, %pcrel_hi(.LCPI20_0)
1113 ; RV64I-LARGE-NEXT:    ld s3, %pcrel_lo(.Lpcrel_hi14)(a1)
1114 ; RV64I-LARGE-NEXT:    slli a0, a0, 4
1115 ; RV64I-LARGE-NEXT:    add s4, a2, a0
1116 ; RV64I-LARGE-NEXT:  .LBB20_2: # %for.body
1117 ; RV64I-LARGE-NEXT:    # =>This Inner Loop Header: Depth=1
1118 ; RV64I-LARGE-NEXT:    mv a0, s0
1119 ; RV64I-LARGE-NEXT:    jalr s3
1120 ; RV64I-LARGE-NEXT:    ld a0, 8(s4)
1121 ; RV64I-LARGE-NEXT:    addi s1, s1, -1
1122 ; RV64I-LARGE-NEXT:    add s2, a0, s2
1123 ; RV64I-LARGE-NEXT:    bnez s1, .LBB20_2
1124 ; RV64I-LARGE-NEXT:    j .LBB20_4
1125 ; RV64I-LARGE-NEXT:  .LBB20_3:
1126 ; RV64I-LARGE-NEXT:    li s2, 0
1127 ; RV64I-LARGE-NEXT:  .LBB20_4: # %for.cond.cleanup
1128 ; RV64I-LARGE-NEXT:    mv a0, s2
1129 ; RV64I-LARGE-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1130 ; RV64I-LARGE-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1131 ; RV64I-LARGE-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1132 ; RV64I-LARGE-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1133 ; RV64I-LARGE-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1134 ; RV64I-LARGE-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1135 ; RV64I-LARGE-NEXT:    addi sp, sp, 48
1136 ; RV64I-LARGE-NEXT:    ret
1137 entry:
1138   %cmp4 = icmp sgt i64 %n, 0
1139   br i1 %cmp4, label %for.body.lr.ph, label %for.cond.cleanup
1141 for.body.lr.ph:                                   ; preds = %entry
1142   ; TODO: when this GEP is expanded, the resulting `addi` should be folded
1143   ; into the load in the loop body.
1144   %y = getelementptr inbounds %struct.S, ptr %a, i64 %k, i32 1
1145   br label %for.body
1147 for.cond.cleanup:                                 ; preds = %for.body, %entry
1148   %s.0.lcssa = phi i64 [ 0, %entry ], [ %add, %for.body ]
1149   ret i64 %s.0.lcssa
1151 for.body:                                         ; preds = %for.body.lr.ph, %for.body
1152   %i.06 = phi i64 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
1153   %s.05 = phi i64 [ 0, %for.body.lr.ph ], [ %add, %for.body ]
1154   call void @f(ptr %a)
1155   %0 = load i64, ptr %y, align 8
1156   %add = add nsw i64 %0, %s.05
1157   %inc = add nuw nsw i64 %i.06, 1
1158   %exitcond.not = icmp eq i64 %inc, %n
1159   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1162 declare void @f(ptr)
1164 @g = external dso_local global [100 x [100 x i8]]
1166 ; This test used to crash due to calling getVRegDef on X0.
1167 define i32 @crash() {
1168 ; RV32I-LABEL: crash:
1169 ; RV32I:       # %bb.0: # %entry
1170 ; RV32I-NEXT:    lui a0, %hi(g+401)
1171 ; RV32I-NEXT:    lbu a0, %lo(g+401)(a0)
1172 ; RV32I-NEXT:    seqz a0, a0
1173 ; RV32I-NEXT:    sw a0, 0(zero)
1174 ; RV32I-NEXT:    li a0, 0
1175 ; RV32I-NEXT:    ret
1177 ; RV32I-MEDIUM-LABEL: crash:
1178 ; RV32I-MEDIUM:       # %bb.0: # %entry
1179 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi14:
1180 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g+401)
1181 ; RV32I-MEDIUM-NEXT:    lbu a0, %pcrel_lo(.Lpcrel_hi14)(a0)
1182 ; RV32I-MEDIUM-NEXT:    seqz a0, a0
1183 ; RV32I-MEDIUM-NEXT:    sw a0, 0(zero)
1184 ; RV32I-MEDIUM-NEXT:    li a0, 0
1185 ; RV32I-MEDIUM-NEXT:    ret
1187 ; RV64I-LABEL: crash:
1188 ; RV64I:       # %bb.0: # %entry
1189 ; RV64I-NEXT:    lui a0, %hi(g+401)
1190 ; RV64I-NEXT:    lbu a0, %lo(g+401)(a0)
1191 ; RV64I-NEXT:    seqz a0, a0
1192 ; RV64I-NEXT:    sw a0, 0(zero)
1193 ; RV64I-NEXT:    li a0, 0
1194 ; RV64I-NEXT:    ret
1196 ; RV64I-MEDIUM-LABEL: crash:
1197 ; RV64I-MEDIUM:       # %bb.0: # %entry
1198 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi14:
1199 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(g+401)
1200 ; RV64I-MEDIUM-NEXT:    lbu a0, %pcrel_lo(.Lpcrel_hi14)(a0)
1201 ; RV64I-MEDIUM-NEXT:    seqz a0, a0
1202 ; RV64I-MEDIUM-NEXT:    sw a0, 0(zero)
1203 ; RV64I-MEDIUM-NEXT:    li a0, 0
1204 ; RV64I-MEDIUM-NEXT:    ret
1206 ; RV64I-LARGE-LABEL: crash:
1207 ; RV64I-LARGE:       # %bb.0: # %entry
1208 ; RV64I-LARGE-NEXT:    li a0, 1
1209 ; RV64I-LARGE-NEXT:  .Lpcrel_hi15:
1210 ; RV64I-LARGE-NEXT:    auipc a1, %pcrel_hi(.LCPI21_0)
1211 ; RV64I-LARGE-NEXT:    ld a1, %pcrel_lo(.Lpcrel_hi15)(a1)
1212 ; RV64I-LARGE-NEXT:    add a0, a1, a0
1213 ; RV64I-LARGE-NEXT:    lbu a0, 400(a0)
1214 ; RV64I-LARGE-NEXT:    seqz a0, a0
1215 ; RV64I-LARGE-NEXT:    sw a0, 0(zero)
1216 ; RV64I-LARGE-NEXT:    li a0, 0
1217 ; RV64I-LARGE-NEXT:    ret
1218 entry:
1219   %idxprom7.peel = sext i32 1 to i64
1220   br label %for.inc.peel
1222 for.inc.peel:                                     ; preds = %entry
1223   %arrayidx8.3.peel = getelementptr [100 x [100 x i8]], ptr @g, i64 0, i64 4, i64 %idxprom7.peel
1224   %0 = load i8, ptr %arrayidx8.3.peel, align 1
1225   %tobool.not.3.peel = icmp eq i8 %0, 0
1226   %spec.select = select i1 %tobool.not.3.peel, i32 1, i32 0
1227   store i32 %spec.select, ptr null, align 4
1228   ret i32 0