xref: /llvm-project/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
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
12
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.
19
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
26
27define 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
34;
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
43;
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
49;
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
56;
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
64entry:
65  %0 = load i64, ptr @g_0
66  ret i64 %0
67}
68
69define 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
77;
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
86;
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
92;
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
99;
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
107entry:
108  %0 = load i64, ptr @g_1
109  ret i64 %0
110}
111
112define 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
120;
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
129;
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
135;
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
142;
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
150entry:
151  %0 = load i64, ptr @g_2
152  ret i64 %0
153}
154
155define 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
163;
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
172;
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
178;
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
185;
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
193entry:
194  %0 = load i64, ptr @g_4
195  ret i64 %0
196}
197
198define 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
205;
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
214;
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
220;
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
227;
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
235entry:
236  %0 = load i64, ptr @g_8
237  ret i64 %0
238}
239
240define 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
247;
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
256;
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
262;
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
269;
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
277entry:
278  %0 = load i64, ptr @g_16
279  ret i64 %0
280}
281
282define 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
290;
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
299;
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
305;
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
312;
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
320entry:
321   store i64 0, ptr @g_4
322   ret void
323}
324
325define 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
332;
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
341;
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
347;
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
354;
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
362entry:
363   store i64 0, ptr @g_8
364   ret void
365}
366
367; Check if we can fold ADDI into the offset of store instructions,
368; when store instructions is the root node in DAG.
369
370@g_4_i32 = global i32 0, align 4
371
372define 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
380;
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
389;
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
397;
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
406;
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
416entry:
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
421
422if.end:
423  ret void
424}
425
426; Check for folds in accesses to elements of an i32 array.
427
428@ga = dso_local local_unnamed_addr global [2 x i32] zeroinitializer, align 4
429
430define 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
436;
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
443;
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
449;
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
456;
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
466}
467
468; Check for folds in accesses to the second element of an i64 array.
469
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
472
473define 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
481;
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
490;
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
496;
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
503;
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
511entry:
512  %0 = load i64, ptr getelementptr inbounds ([2 x i64], ptr @ga_8, i32 0, i32 1)
513  ret i64 %0
514}
515
516define 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
523;
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
532;
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
538;
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
545;
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
553entry:
554  %0 = load i64, ptr getelementptr inbounds ([2 x i64], ptr @ga_16, i32 0, i32 1)
555  ret i64 %0
556}
557
558; Check for folds in accesses to block address.
559define 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
567;
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
576;
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
584;
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
593;
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
602entry:
603  br label %label
604label:
605  %0 = load ptr, ptr blockaddress(@load_ba_1, %label)
606  ret ptr %0
607}
608
609define 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
617;
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
626;
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
634;
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
643;
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
652entry:
653  br label %label
654label:
655  %0 = load ptr, ptr getelementptr inbounds (i8, ptr blockaddress(@load_ba_2, %label), i32 8)
656  ret ptr %0
657}
658
659; Check for folds in accesses to thread-local variables.
660
661@tl_4 = dso_local thread_local global i64 0, align 4
662@tl_8 = dso_local thread_local global i64 0, align 8
663
664define 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
673;
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
682;
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
689;
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
696;
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
703entry:
704  %0 = load i64, ptr @tl_4
705  ret i64 %0
706}
707
708define 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
716;
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
724;
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
731;
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
738;
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
745entry:
746  %0 = load i64, ptr @tl_8
747  ret i64 %0
748}
749
750define 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
756;
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
762;
763; RV64I-LABEL: load_const_ok:
764; RV64I:       # %bb.0: # %entry
765; RV64I-NEXT:    ld a0, 2040(zero)
766; RV64I-NEXT:    ret
767;
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
772;
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
777entry:
778  %0 = load i64, ptr inttoptr (i32 2040 to ptr)
779  ret i64 %0
780}
781
782define 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
789;
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
796;
797; RV64I-LABEL: load_cost_overflow:
798; RV64I:       # %bb.0: # %entry
799; RV64I-NEXT:    ld a0, 2044(zero)
800; RV64I-NEXT:    ret
801;
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
806;
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
811entry:
812  %0 = load i64, ptr inttoptr (i64 2044 to ptr)
813  ret i64 %0
814}
815
816define 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
822;
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
828;
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
834;
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
840;
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
846entry:
847  %0 = load i32, ptr inttoptr (i64 4080 to ptr)
848  ret i32 %0
849}
850
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.
854define 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
860;
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
866;
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
873;
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
880;
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
887entry:
888  %0 = load i32, ptr inttoptr (i64 2147481600 to ptr)
889  ret i32 %0
890}
891
892%struct.S = type { i64, i64 }
893
894define 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
959;
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
1024;
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
1060;
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
1096;
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
1137entry:
1138  %cmp4 = icmp sgt i64 %n, 0
1139  br i1 %cmp4, label %for.body.lr.ph, label %for.cond.cleanup
1140
1141for.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
1146
1147for.cond.cleanup:                                 ; preds = %for.body, %entry
1148  %s.0.lcssa = phi i64 [ 0, %entry ], [ %add, %for.body ]
1149  ret i64 %s.0.lcssa
1150
1151for.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
1160}
1161
1162declare void @f(ptr)
1163
1164@g = external dso_local global [100 x [100 x i8]]
1165
1166; This test used to crash due to calling getVRegDef on X0.
1167define 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
1176;
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
1186;
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
1195;
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
1205;
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
1218entry:
1219  %idxprom7.peel = sext i32 1 to i64
1220  br label %for.inc.peel
1221
1222for.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
1229}
1230