xref: /llvm-project/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll (revision 5cd8d53cac00feafd739dba6215e1f6eed502e46)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs -no-integrated-as < %s \
3; RUN:   | FileCheck -check-prefixes=RV32I %s
4; RUN: llc -mtriple=riscv64 -verify-machineinstrs -no-integrated-as < %s \
5; RUN:   | FileCheck -check-prefixes=RV64I %s
6; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
7; RUN:   | FileCheck -check-prefixes=RV32I-MEDIUM %s
8; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \
9; RUN:   | FileCheck -check-prefixes=RV64I-MEDIUM %s
10
11@eg = external global [4000 x i32], align 4
12@ewg = extern_weak global [4000 x i32], align 4
13
14define void @constraint_m_1(ptr %a) nounwind {
15; RV32I-LABEL: constraint_m_1:
16; RV32I:       # %bb.0:
17; RV32I-NEXT:    #APP
18; RV32I-NEXT:    #NO_APP
19; RV32I-NEXT:    ret
20;
21; RV64I-LABEL: constraint_m_1:
22; RV64I:       # %bb.0:
23; RV64I-NEXT:    #APP
24; RV64I-NEXT:    #NO_APP
25; RV64I-NEXT:    ret
26;
27; RV32I-MEDIUM-LABEL: constraint_m_1:
28; RV32I-MEDIUM:       # %bb.0:
29; RV32I-MEDIUM-NEXT:    #APP
30; RV32I-MEDIUM-NEXT:    #NO_APP
31; RV32I-MEDIUM-NEXT:    ret
32;
33; RV64I-MEDIUM-LABEL: constraint_m_1:
34; RV64I-MEDIUM:       # %bb.0:
35; RV64I-MEDIUM-NEXT:    #APP
36; RV64I-MEDIUM-NEXT:    #NO_APP
37; RV64I-MEDIUM-NEXT:    ret
38  call void asm sideeffect "", "=*m"(ptr elementtype(i32) %a)
39  ret void
40}
41
42define i32 @constraint_m_2(ptr %a) nounwind {
43; RV32I-LABEL: constraint_m_2:
44; RV32I:       # %bb.0:
45; RV32I-NEXT:    #APP
46; RV32I-NEXT:    lw a0, 0(a0)
47; RV32I-NEXT:    #NO_APP
48; RV32I-NEXT:    ret
49;
50; RV64I-LABEL: constraint_m_2:
51; RV64I:       # %bb.0:
52; RV64I-NEXT:    #APP
53; RV64I-NEXT:    lw a0, 0(a0)
54; RV64I-NEXT:    #NO_APP
55; RV64I-NEXT:    ret
56;
57; RV32I-MEDIUM-LABEL: constraint_m_2:
58; RV32I-MEDIUM:       # %bb.0:
59; RV32I-MEDIUM-NEXT:    #APP
60; RV32I-MEDIUM-NEXT:    lw a0, 0(a0)
61; RV32I-MEDIUM-NEXT:    #NO_APP
62; RV32I-MEDIUM-NEXT:    ret
63;
64; RV64I-MEDIUM-LABEL: constraint_m_2:
65; RV64I-MEDIUM:       # %bb.0:
66; RV64I-MEDIUM-NEXT:    #APP
67; RV64I-MEDIUM-NEXT:    lw a0, 0(a0)
68; RV64I-MEDIUM-NEXT:    #NO_APP
69; RV64I-MEDIUM-NEXT:    ret
70  %1 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %a)
71  ret i32 %1
72}
73
74define i32 @constraint_m_with_offset(ptr %a) nounwind {
75; RV32I-LABEL: constraint_m_with_offset:
76; RV32I:       # %bb.0:
77; RV32I-NEXT:    #APP
78; RV32I-NEXT:    lw a0, 4(a0)
79; RV32I-NEXT:    #NO_APP
80; RV32I-NEXT:    ret
81;
82; RV64I-LABEL: constraint_m_with_offset:
83; RV64I:       # %bb.0:
84; RV64I-NEXT:    #APP
85; RV64I-NEXT:    lw a0, 4(a0)
86; RV64I-NEXT:    #NO_APP
87; RV64I-NEXT:    ret
88;
89; RV32I-MEDIUM-LABEL: constraint_m_with_offset:
90; RV32I-MEDIUM:       # %bb.0:
91; RV32I-MEDIUM-NEXT:    #APP
92; RV32I-MEDIUM-NEXT:    lw a0, 4(a0)
93; RV32I-MEDIUM-NEXT:    #NO_APP
94; RV32I-MEDIUM-NEXT:    ret
95;
96; RV64I-MEDIUM-LABEL: constraint_m_with_offset:
97; RV64I-MEDIUM:       # %bb.0:
98; RV64I-MEDIUM-NEXT:    #APP
99; RV64I-MEDIUM-NEXT:    lw a0, 4(a0)
100; RV64I-MEDIUM-NEXT:    #NO_APP
101; RV64I-MEDIUM-NEXT:    ret
102  %1 = getelementptr i32, ptr %a, i32 1
103  %2 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %1)
104  ret i32 %2
105}
106
107define void @constraint_m_with_global_1() nounwind {
108; RV32I-LABEL: constraint_m_with_global_1:
109; RV32I:       # %bb.0:
110; RV32I-NEXT:    lui a0, %hi(eg)
111; RV32I-NEXT:    #APP
112; RV32I-NEXT:    sw zero, %lo(eg)(a0)
113; RV32I-NEXT:    #NO_APP
114; RV32I-NEXT:    ret
115;
116; RV64I-LABEL: constraint_m_with_global_1:
117; RV64I:       # %bb.0:
118; RV64I-NEXT:    lui a0, %hi(eg)
119; RV64I-NEXT:    #APP
120; RV64I-NEXT:    sw zero, %lo(eg)(a0)
121; RV64I-NEXT:    #NO_APP
122; RV64I-NEXT:    ret
123;
124; RV32I-MEDIUM-LABEL: constraint_m_with_global_1:
125; RV32I-MEDIUM:       # %bb.0:
126; RV32I-MEDIUM-NEXT:  .Lpcrel_hi0:
127; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
128; RV32I-MEDIUM-NEXT:    #APP
129; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi0)(a0)
130; RV32I-MEDIUM-NEXT:    #NO_APP
131; RV32I-MEDIUM-NEXT:    ret
132;
133; RV64I-MEDIUM-LABEL: constraint_m_with_global_1:
134; RV64I-MEDIUM:       # %bb.0:
135; RV64I-MEDIUM-NEXT:  .Lpcrel_hi0:
136; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
137; RV64I-MEDIUM-NEXT:    #APP
138; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi0)(a0)
139; RV64I-MEDIUM-NEXT:    #NO_APP
140; RV64I-MEDIUM-NEXT:    ret
141  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
142  ret void
143}
144
145define void @constraint_m_with_global_2() nounwind {
146; RV32I-LABEL: constraint_m_with_global_2:
147; RV32I:       # %bb.0:
148; RV32I-NEXT:    lui a0, %hi(eg+4)
149; RV32I-NEXT:    #APP
150; RV32I-NEXT:    sw zero, %lo(eg+4)(a0)
151; RV32I-NEXT:    #NO_APP
152; RV32I-NEXT:    ret
153;
154; RV64I-LABEL: constraint_m_with_global_2:
155; RV64I:       # %bb.0:
156; RV64I-NEXT:    lui a0, %hi(eg+4)
157; RV64I-NEXT:    #APP
158; RV64I-NEXT:    sw zero, %lo(eg+4)(a0)
159; RV64I-NEXT:    #NO_APP
160; RV64I-NEXT:    ret
161;
162; RV32I-MEDIUM-LABEL: constraint_m_with_global_2:
163; RV32I-MEDIUM:       # %bb.0:
164; RV32I-MEDIUM-NEXT:  .Lpcrel_hi1:
165; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+4)
166; RV32I-MEDIUM-NEXT:    #APP
167; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi1)(a0)
168; RV32I-MEDIUM-NEXT:    #NO_APP
169; RV32I-MEDIUM-NEXT:    ret
170;
171; RV64I-MEDIUM-LABEL: constraint_m_with_global_2:
172; RV64I-MEDIUM:       # %bb.0:
173; RV64I-MEDIUM-NEXT:  .Lpcrel_hi1:
174; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+4)
175; RV64I-MEDIUM-NEXT:    #APP
176; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi1)(a0)
177; RV64I-MEDIUM-NEXT:    #NO_APP
178; RV64I-MEDIUM-NEXT:    ret
179  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 1))
180  ret void
181}
182
183define void @constraint_m_with_global_3() nounwind {
184; RV32I-LABEL: constraint_m_with_global_3:
185; RV32I:       # %bb.0:
186; RV32I-NEXT:    lui a0, %hi(eg+8000)
187; RV32I-NEXT:    #APP
188; RV32I-NEXT:    sw zero, %lo(eg+8000)(a0)
189; RV32I-NEXT:    #NO_APP
190; RV32I-NEXT:    ret
191;
192; RV64I-LABEL: constraint_m_with_global_3:
193; RV64I:       # %bb.0:
194; RV64I-NEXT:    lui a0, %hi(eg+8000)
195; RV64I-NEXT:    #APP
196; RV64I-NEXT:    sw zero, %lo(eg+8000)(a0)
197; RV64I-NEXT:    #NO_APP
198; RV64I-NEXT:    ret
199;
200; RV32I-MEDIUM-LABEL: constraint_m_with_global_3:
201; RV32I-MEDIUM:       # %bb.0:
202; RV32I-MEDIUM-NEXT:  .Lpcrel_hi2:
203; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
204; RV32I-MEDIUM-NEXT:    #APP
205; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi2)(a0)
206; RV32I-MEDIUM-NEXT:    #NO_APP
207; RV32I-MEDIUM-NEXT:    ret
208;
209; RV64I-MEDIUM-LABEL: constraint_m_with_global_3:
210; RV64I-MEDIUM:       # %bb.0:
211; RV64I-MEDIUM-NEXT:  .Lpcrel_hi2:
212; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
213; RV64I-MEDIUM-NEXT:    #APP
214; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi2)(a0)
215; RV64I-MEDIUM-NEXT:    #NO_APP
216; RV64I-MEDIUM-NEXT:    ret
217  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 2000))
218  ret void
219}
220
221define void @constraint_m_with_extern_weak_global_1() nounwind {
222; RV32I-LABEL: constraint_m_with_extern_weak_global_1:
223; RV32I:       # %bb.0:
224; RV32I-NEXT:    lui a0, %hi(ewg)
225; RV32I-NEXT:    #APP
226; RV32I-NEXT:    sw zero, %lo(ewg)(a0)
227; RV32I-NEXT:    #NO_APP
228; RV32I-NEXT:    ret
229;
230; RV64I-LABEL: constraint_m_with_extern_weak_global_1:
231; RV64I:       # %bb.0:
232; RV64I-NEXT:    lui a0, %hi(ewg)
233; RV64I-NEXT:    #APP
234; RV64I-NEXT:    sw zero, %lo(ewg)(a0)
235; RV64I-NEXT:    #NO_APP
236; RV64I-NEXT:    ret
237;
238; RV32I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_1:
239; RV32I-MEDIUM:       # %bb.0:
240; RV32I-MEDIUM-NEXT:  .Lpcrel_hi3:
241; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
242; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi3)(a0)
243; RV32I-MEDIUM-NEXT:    #APP
244; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
245; RV32I-MEDIUM-NEXT:    #NO_APP
246; RV32I-MEDIUM-NEXT:    ret
247;
248; RV64I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_1:
249; RV64I-MEDIUM:       # %bb.0:
250; RV64I-MEDIUM-NEXT:  .Lpcrel_hi3:
251; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
252; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
253; RV64I-MEDIUM-NEXT:    #APP
254; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
255; RV64I-MEDIUM-NEXT:    #NO_APP
256; RV64I-MEDIUM-NEXT:    ret
257  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @ewg)
258  ret void
259}
260
261define void @constraint_m_with_extern_weak_global_2() nounwind {
262; RV32I-LABEL: constraint_m_with_extern_weak_global_2:
263; RV32I:       # %bb.0:
264; RV32I-NEXT:    lui a0, %hi(ewg+4)
265; RV32I-NEXT:    #APP
266; RV32I-NEXT:    sw zero, %lo(ewg+4)(a0)
267; RV32I-NEXT:    #NO_APP
268; RV32I-NEXT:    ret
269;
270; RV64I-LABEL: constraint_m_with_extern_weak_global_2:
271; RV64I:       # %bb.0:
272; RV64I-NEXT:    lui a0, %hi(ewg+4)
273; RV64I-NEXT:    #APP
274; RV64I-NEXT:    sw zero, %lo(ewg+4)(a0)
275; RV64I-NEXT:    #NO_APP
276; RV64I-NEXT:    ret
277;
278; RV32I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_2:
279; RV32I-MEDIUM:       # %bb.0:
280; RV32I-MEDIUM-NEXT:  .Lpcrel_hi4:
281; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
282; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi4)(a0)
283; RV32I-MEDIUM-NEXT:    #APP
284; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
285; RV32I-MEDIUM-NEXT:    #NO_APP
286; RV32I-MEDIUM-NEXT:    ret
287;
288; RV64I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_2:
289; RV64I-MEDIUM:       # %bb.0:
290; RV64I-MEDIUM-NEXT:  .Lpcrel_hi4:
291; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
292; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
293; RV64I-MEDIUM-NEXT:    #APP
294; RV64I-MEDIUM-NEXT:    sw zero, 4(a0)
295; RV64I-MEDIUM-NEXT:    #NO_APP
296; RV64I-MEDIUM-NEXT:    ret
297  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 1))
298  ret void
299}
300
301define void @constraint_m_with_extern_weak_global_3() nounwind {
302; RV32I-LABEL: constraint_m_with_extern_weak_global_3:
303; RV32I:       # %bb.0:
304; RV32I-NEXT:    lui a0, %hi(ewg+8000)
305; RV32I-NEXT:    #APP
306; RV32I-NEXT:    sw zero, %lo(ewg+8000)(a0)
307; RV32I-NEXT:    #NO_APP
308; RV32I-NEXT:    ret
309;
310; RV64I-LABEL: constraint_m_with_extern_weak_global_3:
311; RV64I:       # %bb.0:
312; RV64I-NEXT:    lui a0, %hi(ewg+8000)
313; RV64I-NEXT:    #APP
314; RV64I-NEXT:    sw zero, %lo(ewg+8000)(a0)
315; RV64I-NEXT:    #NO_APP
316; RV64I-NEXT:    ret
317;
318; RV32I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_3:
319; RV32I-MEDIUM:       # %bb.0:
320; RV32I-MEDIUM-NEXT:  .Lpcrel_hi5:
321; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
322; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi5)(a0)
323; RV32I-MEDIUM-NEXT:    lui a1, 2
324; RV32I-MEDIUM-NEXT:    addi a1, a1, -192
325; RV32I-MEDIUM-NEXT:    add a0, a0, a1
326; RV32I-MEDIUM-NEXT:    #APP
327; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
328; RV32I-MEDIUM-NEXT:    #NO_APP
329; RV32I-MEDIUM-NEXT:    ret
330;
331; RV64I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_3:
332; RV64I-MEDIUM:       # %bb.0:
333; RV64I-MEDIUM-NEXT:  .Lpcrel_hi5:
334; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
335; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
336; RV64I-MEDIUM-NEXT:    lui a1, 2
337; RV64I-MEDIUM-NEXT:    addiw a1, a1, -192
338; RV64I-MEDIUM-NEXT:    add a0, a0, a1
339; RV64I-MEDIUM-NEXT:    #APP
340; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
341; RV64I-MEDIUM-NEXT:    #NO_APP
342; RV64I-MEDIUM-NEXT:    ret
343  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 2000))
344  ret void
345}
346
347define void @constraint_m_with_local_1() nounwind {
348; RV32I-LABEL: constraint_m_with_local_1:
349; RV32I:       # %bb.0: # %entry
350; RV32I-NEXT:  .Ltmp0: # Block address taken
351; RV32I-NEXT:  # %bb.1: # %label
352; RV32I-NEXT:    lui a0, %hi(.Ltmp0)
353; RV32I-NEXT:    #APP
354; RV32I-NEXT:    lw zero, %lo(.Ltmp0)(a0)
355; RV32I-NEXT:    #NO_APP
356; RV32I-NEXT:    ret
357;
358; RV64I-LABEL: constraint_m_with_local_1:
359; RV64I:       # %bb.0: # %entry
360; RV64I-NEXT:  .Ltmp0: # Block address taken
361; RV64I-NEXT:  # %bb.1: # %label
362; RV64I-NEXT:    lui a0, %hi(.Ltmp0)
363; RV64I-NEXT:    #APP
364; RV64I-NEXT:    lw zero, %lo(.Ltmp0)(a0)
365; RV64I-NEXT:    #NO_APP
366; RV64I-NEXT:    ret
367;
368; RV32I-MEDIUM-LABEL: constraint_m_with_local_1:
369; RV32I-MEDIUM:       # %bb.0: # %entry
370; RV32I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
371; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
372; RV32I-MEDIUM-NEXT:  .Lpcrel_hi6:
373; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
374; RV32I-MEDIUM-NEXT:    #APP
375; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi6)(a0)
376; RV32I-MEDIUM-NEXT:    #NO_APP
377; RV32I-MEDIUM-NEXT:    ret
378;
379; RV64I-MEDIUM-LABEL: constraint_m_with_local_1:
380; RV64I-MEDIUM:       # %bb.0: # %entry
381; RV64I-MEDIUM-NEXT:  .Ltmp0: # Block address taken
382; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
383; RV64I-MEDIUM-NEXT:  .Lpcrel_hi6:
384; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
385; RV64I-MEDIUM-NEXT:    #APP
386; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi6)(a0)
387; RV64I-MEDIUM-NEXT:    #NO_APP
388; RV64I-MEDIUM-NEXT:    ret
389entry:
390  br label %label
391
392label:
393  tail call void asm sideeffect "lw zero, $0", "*m"(ptr elementtype(ptr) blockaddress(@constraint_m_with_local_1, %label))
394  ret void
395}
396
397define void @constraint_m_with_local_2() nounwind {
398; RV32I-LABEL: constraint_m_with_local_2:
399; RV32I:       # %bb.0: # %entry
400; RV32I-NEXT:  .Ltmp1: # Block address taken
401; RV32I-NEXT:  # %bb.1: # %label
402; RV32I-NEXT:    lui a0, %hi(.Ltmp1+4)
403; RV32I-NEXT:    #APP
404; RV32I-NEXT:    lw zero, %lo(.Ltmp1+4)(a0)
405; RV32I-NEXT:    #NO_APP
406; RV32I-NEXT:    ret
407;
408; RV64I-LABEL: constraint_m_with_local_2:
409; RV64I:       # %bb.0: # %entry
410; RV64I-NEXT:  .Ltmp1: # Block address taken
411; RV64I-NEXT:  # %bb.1: # %label
412; RV64I-NEXT:    lui a0, %hi(.Ltmp1+4)
413; RV64I-NEXT:    #APP
414; RV64I-NEXT:    lw zero, %lo(.Ltmp1+4)(a0)
415; RV64I-NEXT:    #NO_APP
416; RV64I-NEXT:    ret
417;
418; RV32I-MEDIUM-LABEL: constraint_m_with_local_2:
419; RV32I-MEDIUM:       # %bb.0: # %entry
420; RV32I-MEDIUM-NEXT:  .Ltmp1: # Block address taken
421; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
422; RV32I-MEDIUM-NEXT:  .Lpcrel_hi7:
423; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+4)
424; RV32I-MEDIUM-NEXT:    #APP
425; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi7)(a0)
426; RV32I-MEDIUM-NEXT:    #NO_APP
427; RV32I-MEDIUM-NEXT:    ret
428;
429; RV64I-MEDIUM-LABEL: constraint_m_with_local_2:
430; RV64I-MEDIUM:       # %bb.0: # %entry
431; RV64I-MEDIUM-NEXT:  .Ltmp1: # Block address taken
432; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
433; RV64I-MEDIUM-NEXT:  .Lpcrel_hi7:
434; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+4)
435; RV64I-MEDIUM-NEXT:    #APP
436; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi7)(a0)
437; RV64I-MEDIUM-NEXT:    #NO_APP
438; RV64I-MEDIUM-NEXT:    ret
439entry:
440  br label %label
441
442label:
443  call void asm "lw zero, $0", "*m"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_m_with_local_2, %label), i32 4))
444  ret void
445}
446
447define void @constraint_m_with_local_3() nounwind {
448; RV32I-LABEL: constraint_m_with_local_3:
449; RV32I:       # %bb.0: # %entry
450; RV32I-NEXT:  .Ltmp2: # Block address taken
451; RV32I-NEXT:  # %bb.1: # %label
452; RV32I-NEXT:    lui a0, %hi(.Ltmp2+2000)
453; RV32I-NEXT:    #APP
454; RV32I-NEXT:    lw zero, %lo(.Ltmp2+2000)(a0)
455; RV32I-NEXT:    #NO_APP
456; RV32I-NEXT:    ret
457;
458; RV64I-LABEL: constraint_m_with_local_3:
459; RV64I:       # %bb.0: # %entry
460; RV64I-NEXT:  .Ltmp2: # Block address taken
461; RV64I-NEXT:  # %bb.1: # %label
462; RV64I-NEXT:    lui a0, %hi(.Ltmp2+2000)
463; RV64I-NEXT:    #APP
464; RV64I-NEXT:    lw zero, %lo(.Ltmp2+2000)(a0)
465; RV64I-NEXT:    #NO_APP
466; RV64I-NEXT:    ret
467;
468; RV32I-MEDIUM-LABEL: constraint_m_with_local_3:
469; RV32I-MEDIUM:       # %bb.0: # %entry
470; RV32I-MEDIUM-NEXT:  .Ltmp2: # Block address taken
471; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
472; RV32I-MEDIUM-NEXT:  .Lpcrel_hi8:
473; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp2+2000)
474; RV32I-MEDIUM-NEXT:    #APP
475; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi8)(a0)
476; RV32I-MEDIUM-NEXT:    #NO_APP
477; RV32I-MEDIUM-NEXT:    ret
478;
479; RV64I-MEDIUM-LABEL: constraint_m_with_local_3:
480; RV64I-MEDIUM:       # %bb.0: # %entry
481; RV64I-MEDIUM-NEXT:  .Ltmp2: # Block address taken
482; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
483; RV64I-MEDIUM-NEXT:  .Lpcrel_hi8:
484; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp2+2000)
485; RV64I-MEDIUM-NEXT:    #APP
486; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi8)(a0)
487; RV64I-MEDIUM-NEXT:    #NO_APP
488; RV64I-MEDIUM-NEXT:    ret
489entry:
490  br label %label
491
492label:
493  call void asm "lw zero, $0", "*m"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_m_with_local_3, %label), i32 2000))
494  ret void
495}
496
497define void @constraint_m_with_multi_operands() nounwind {
498; RV32I-LABEL: constraint_m_with_multi_operands:
499; RV32I:       # %bb.0:
500; RV32I-NEXT:    lui a0, %hi(eg)
501; RV32I-NEXT:    #APP
502; RV32I-NEXT:    sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
503; RV32I-NEXT:    #NO_APP
504; RV32I-NEXT:    ret
505;
506; RV64I-LABEL: constraint_m_with_multi_operands:
507; RV64I:       # %bb.0:
508; RV64I-NEXT:    lui a0, %hi(eg)
509; RV64I-NEXT:    #APP
510; RV64I-NEXT:    sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
511; RV64I-NEXT:    #NO_APP
512; RV64I-NEXT:    ret
513;
514; RV32I-MEDIUM-LABEL: constraint_m_with_multi_operands:
515; RV32I-MEDIUM:       # %bb.0:
516; RV32I-MEDIUM-NEXT:  .Lpcrel_hi9:
517; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
518; RV32I-MEDIUM-NEXT:    #APP
519; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
520; RV32I-MEDIUM-NEXT:    #NO_APP
521; RV32I-MEDIUM-NEXT:    ret
522;
523; RV64I-MEDIUM-LABEL: constraint_m_with_multi_operands:
524; RV64I-MEDIUM:       # %bb.0:
525; RV64I-MEDIUM-NEXT:  .Lpcrel_hi9:
526; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
527; RV64I-MEDIUM-NEXT:    #APP
528; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
529; RV64I-MEDIUM-NEXT:    #NO_APP
530; RV64I-MEDIUM-NEXT:    ret
531  call void asm "sw zero, $0; sw zero, $1", "=*m,=*m"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
532  ret void
533}
534
535define void @constraint_m_with_multi_asm() nounwind {
536; RV32I-LABEL: constraint_m_with_multi_asm:
537; RV32I:       # %bb.0:
538; RV32I-NEXT:    lui a0, %hi(eg)
539; RV32I-NEXT:    #APP
540; RV32I-NEXT:    sw zero, %lo(eg)(a0)
541; RV32I-NEXT:    #NO_APP
542; RV32I-NEXT:    #APP
543; RV32I-NEXT:    sw zero, %lo(eg)(a0)
544; RV32I-NEXT:    #NO_APP
545; RV32I-NEXT:    ret
546;
547; RV64I-LABEL: constraint_m_with_multi_asm:
548; RV64I:       # %bb.0:
549; RV64I-NEXT:    lui a0, %hi(eg)
550; RV64I-NEXT:    #APP
551; RV64I-NEXT:    sw zero, %lo(eg)(a0)
552; RV64I-NEXT:    #NO_APP
553; RV64I-NEXT:    #APP
554; RV64I-NEXT:    sw zero, %lo(eg)(a0)
555; RV64I-NEXT:    #NO_APP
556; RV64I-NEXT:    ret
557;
558; RV32I-MEDIUM-LABEL: constraint_m_with_multi_asm:
559; RV32I-MEDIUM:       # %bb.0:
560; RV32I-MEDIUM-NEXT:  .Lpcrel_hi10:
561; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
562; RV32I-MEDIUM-NEXT:    #APP
563; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi10)(a0)
564; RV32I-MEDIUM-NEXT:    #NO_APP
565; RV32I-MEDIUM-NEXT:    #APP
566; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi10)(a0)
567; RV32I-MEDIUM-NEXT:    #NO_APP
568; RV32I-MEDIUM-NEXT:    ret
569;
570; RV64I-MEDIUM-LABEL: constraint_m_with_multi_asm:
571; RV64I-MEDIUM:       # %bb.0:
572; RV64I-MEDIUM-NEXT:  .Lpcrel_hi10:
573; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
574; RV64I-MEDIUM-NEXT:    #APP
575; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi10)(a0)
576; RV64I-MEDIUM-NEXT:    #NO_APP
577; RV64I-MEDIUM-NEXT:    #APP
578; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi10)(a0)
579; RV64I-MEDIUM-NEXT:    #NO_APP
580; RV64I-MEDIUM-NEXT:    ret
581  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
582  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
583  ret void
584}
585
586define i32 @constraint_m_with_callbr_multi_operands(i32 %a) {
587; RV32I-LABEL: constraint_m_with_callbr_multi_operands:
588; RV32I:       # %bb.0: # %entry
589; RV32I-NEXT:    lui a1, %hi(eg)
590; RV32I-NEXT:    #APP
591; RV32I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB14_2
592; RV32I-NEXT:    #NO_APP
593; RV32I-NEXT:  # %bb.1: # %normal
594; RV32I-NEXT:    li a0, 0
595; RV32I-NEXT:    ret
596; RV32I-NEXT:  .LBB14_2: # Block address taken
597; RV32I-NEXT:    # %fail
598; RV32I-NEXT:    # Label of block must be emitted
599; RV32I-NEXT:    li a0, 1
600; RV32I-NEXT:    ret
601;
602; RV64I-LABEL: constraint_m_with_callbr_multi_operands:
603; RV64I:       # %bb.0: # %entry
604; RV64I-NEXT:    lui a1, %hi(eg)
605; RV64I-NEXT:    #APP
606; RV64I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB14_2
607; RV64I-NEXT:    #NO_APP
608; RV64I-NEXT:  # %bb.1: # %normal
609; RV64I-NEXT:    li a0, 0
610; RV64I-NEXT:    ret
611; RV64I-NEXT:  .LBB14_2: # Block address taken
612; RV64I-NEXT:    # %fail
613; RV64I-NEXT:    # Label of block must be emitted
614; RV64I-NEXT:    li a0, 1
615; RV64I-NEXT:    ret
616;
617; RV32I-MEDIUM-LABEL: constraint_m_with_callbr_multi_operands:
618; RV32I-MEDIUM:       # %bb.0: # %entry
619; RV32I-MEDIUM-NEXT:  .Lpcrel_hi11:
620; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
621; RV32I-MEDIUM-NEXT:    #APP
622; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); beqz a0, .LBB14_2
623; RV32I-MEDIUM-NEXT:    #NO_APP
624; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal
625; RV32I-MEDIUM-NEXT:    li a0, 0
626; RV32I-MEDIUM-NEXT:    ret
627; RV32I-MEDIUM-NEXT:  .LBB14_2: # Block address taken
628; RV32I-MEDIUM-NEXT:    # %fail
629; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
630; RV32I-MEDIUM-NEXT:    li a0, 1
631; RV32I-MEDIUM-NEXT:    ret
632;
633; RV64I-MEDIUM-LABEL: constraint_m_with_callbr_multi_operands:
634; RV64I-MEDIUM:       # %bb.0: # %entry
635; RV64I-MEDIUM-NEXT:  .Lpcrel_hi11:
636; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
637; RV64I-MEDIUM-NEXT:    #APP
638; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); sw zero, %pcrel_lo(.Lpcrel_hi11)(a1); beqz a0, .LBB14_2
639; RV64I-MEDIUM-NEXT:    #NO_APP
640; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal
641; RV64I-MEDIUM-NEXT:    li a0, 0
642; RV64I-MEDIUM-NEXT:    ret
643; RV64I-MEDIUM-NEXT:  .LBB14_2: # Block address taken
644; RV64I-MEDIUM-NEXT:    # %fail
645; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
646; RV64I-MEDIUM-NEXT:    li a0, 1
647; RV64I-MEDIUM-NEXT:    ret
648entry:
649  callbr void asm "sw zero, $0; sw zero, $1; beqz $2, $3", "=*m,=*m,r,!i"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg, i32 %a) to label %normal [label %fail]
650
651normal:
652  ret i32 0
653
654fail:
655  ret i32 1
656}
657
658define i32 @constraint_m_with_multi_callbr_asm(i32 %a) {
659; RV32I-LABEL: constraint_m_with_multi_callbr_asm:
660; RV32I:       # %bb.0: # %entry
661; RV32I-NEXT:    lui a1, %hi(eg)
662; RV32I-NEXT:    #APP
663; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB15_3
664; RV32I-NEXT:    #NO_APP
665; RV32I-NEXT:  # %bb.1: # %normal0
666; RV32I-NEXT:    #APP
667; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB15_3
668; RV32I-NEXT:    #NO_APP
669; RV32I-NEXT:  # %bb.2: # %normal1
670; RV32I-NEXT:    li a0, 0
671; RV32I-NEXT:    ret
672; RV32I-NEXT:  .LBB15_3: # Block address taken
673; RV32I-NEXT:    # %fail
674; RV32I-NEXT:    # Label of block must be emitted
675; RV32I-NEXT:    li a0, 1
676; RV32I-NEXT:    ret
677;
678; RV64I-LABEL: constraint_m_with_multi_callbr_asm:
679; RV64I:       # %bb.0: # %entry
680; RV64I-NEXT:    lui a1, %hi(eg)
681; RV64I-NEXT:    #APP
682; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB15_3
683; RV64I-NEXT:    #NO_APP
684; RV64I-NEXT:  # %bb.1: # %normal0
685; RV64I-NEXT:    #APP
686; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB15_3
687; RV64I-NEXT:    #NO_APP
688; RV64I-NEXT:  # %bb.2: # %normal1
689; RV64I-NEXT:    li a0, 0
690; RV64I-NEXT:    ret
691; RV64I-NEXT:  .LBB15_3: # Block address taken
692; RV64I-NEXT:    # %fail
693; RV64I-NEXT:    # Label of block must be emitted
694; RV64I-NEXT:    li a0, 1
695; RV64I-NEXT:    ret
696;
697; RV32I-MEDIUM-LABEL: constraint_m_with_multi_callbr_asm:
698; RV32I-MEDIUM:       # %bb.0: # %entry
699; RV32I-MEDIUM-NEXT:  .Lpcrel_hi12:
700; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
701; RV32I-MEDIUM-NEXT:    #APP
702; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi12)(a1); beqz a0, .LBB15_3
703; RV32I-MEDIUM-NEXT:    #NO_APP
704; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal0
705; RV32I-MEDIUM-NEXT:    #APP
706; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi12)(a1); beqz a0, .LBB15_3
707; RV32I-MEDIUM-NEXT:    #NO_APP
708; RV32I-MEDIUM-NEXT:  # %bb.2: # %normal1
709; RV32I-MEDIUM-NEXT:    li a0, 0
710; RV32I-MEDIUM-NEXT:    ret
711; RV32I-MEDIUM-NEXT:  .LBB15_3: # Block address taken
712; RV32I-MEDIUM-NEXT:    # %fail
713; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
714; RV32I-MEDIUM-NEXT:    li a0, 1
715; RV32I-MEDIUM-NEXT:    ret
716;
717; RV64I-MEDIUM-LABEL: constraint_m_with_multi_callbr_asm:
718; RV64I-MEDIUM:       # %bb.0: # %entry
719; RV64I-MEDIUM-NEXT:  .Lpcrel_hi12:
720; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
721; RV64I-MEDIUM-NEXT:    #APP
722; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi12)(a1); beqz a0, .LBB15_3
723; RV64I-MEDIUM-NEXT:    #NO_APP
724; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal0
725; RV64I-MEDIUM-NEXT:    #APP
726; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi12)(a1); beqz a0, .LBB15_3
727; RV64I-MEDIUM-NEXT:    #NO_APP
728; RV64I-MEDIUM-NEXT:  # %bb.2: # %normal1
729; RV64I-MEDIUM-NEXT:    li a0, 0
730; RV64I-MEDIUM-NEXT:    ret
731; RV64I-MEDIUM-NEXT:  .LBB15_3: # Block address taken
732; RV64I-MEDIUM-NEXT:    # %fail
733; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
734; RV64I-MEDIUM-NEXT:    li a0, 1
735; RV64I-MEDIUM-NEXT:    ret
736entry:
737  callbr void asm "sw zero, $0; beqz $1, $2", "=*m,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
738
739normal0:
740  callbr void asm "sw zero, $0; beqz $1, $2", "=*m,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal1 [label %fail]
741
742normal1:
743  ret i32 0
744
745fail:
746  ret i32 1
747}
748
749define void @constraint_o_1(ptr %a) nounwind {
750; RV32I-LABEL: constraint_o_1:
751; RV32I:       # %bb.0:
752; RV32I-NEXT:    #APP
753; RV32I-NEXT:    #NO_APP
754; RV32I-NEXT:    ret
755;
756; RV64I-LABEL: constraint_o_1:
757; RV64I:       # %bb.0:
758; RV64I-NEXT:    #APP
759; RV64I-NEXT:    #NO_APP
760; RV64I-NEXT:    ret
761;
762; RV32I-MEDIUM-LABEL: constraint_o_1:
763; RV32I-MEDIUM:       # %bb.0:
764; RV32I-MEDIUM-NEXT:    #APP
765; RV32I-MEDIUM-NEXT:    #NO_APP
766; RV32I-MEDIUM-NEXT:    ret
767;
768; RV64I-MEDIUM-LABEL: constraint_o_1:
769; RV64I-MEDIUM:       # %bb.0:
770; RV64I-MEDIUM-NEXT:    #APP
771; RV64I-MEDIUM-NEXT:    #NO_APP
772; RV64I-MEDIUM-NEXT:    ret
773  call void asm sideeffect "", "=*o"(ptr elementtype(i32) %a)
774  ret void
775}
776
777define i32 @constraint_o_2(ptr %a) nounwind {
778; RV32I-LABEL: constraint_o_2:
779; RV32I:       # %bb.0:
780; RV32I-NEXT:    #APP
781; RV32I-NEXT:    lw a0, 0(a0)
782; RV32I-NEXT:    #NO_APP
783; RV32I-NEXT:    ret
784;
785; RV64I-LABEL: constraint_o_2:
786; RV64I:       # %bb.0:
787; RV64I-NEXT:    #APP
788; RV64I-NEXT:    lw a0, 0(a0)
789; RV64I-NEXT:    #NO_APP
790; RV64I-NEXT:    ret
791;
792; RV32I-MEDIUM-LABEL: constraint_o_2:
793; RV32I-MEDIUM:       # %bb.0:
794; RV32I-MEDIUM-NEXT:    #APP
795; RV32I-MEDIUM-NEXT:    lw a0, 0(a0)
796; RV32I-MEDIUM-NEXT:    #NO_APP
797; RV32I-MEDIUM-NEXT:    ret
798;
799; RV64I-MEDIUM-LABEL: constraint_o_2:
800; RV64I-MEDIUM:       # %bb.0:
801; RV64I-MEDIUM-NEXT:    #APP
802; RV64I-MEDIUM-NEXT:    lw a0, 0(a0)
803; RV64I-MEDIUM-NEXT:    #NO_APP
804; RV64I-MEDIUM-NEXT:    ret
805  %1 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %a)
806  ret i32 %1
807}
808
809define i32 @constraint_o_with_offset(ptr %a) nounwind {
810; RV32I-LABEL: constraint_o_with_offset:
811; RV32I:       # %bb.0:
812; RV32I-NEXT:    #APP
813; RV32I-NEXT:    lw a0, 4(a0)
814; RV32I-NEXT:    #NO_APP
815; RV32I-NEXT:    ret
816;
817; RV64I-LABEL: constraint_o_with_offset:
818; RV64I:       # %bb.0:
819; RV64I-NEXT:    #APP
820; RV64I-NEXT:    lw a0, 4(a0)
821; RV64I-NEXT:    #NO_APP
822; RV64I-NEXT:    ret
823;
824; RV32I-MEDIUM-LABEL: constraint_o_with_offset:
825; RV32I-MEDIUM:       # %bb.0:
826; RV32I-MEDIUM-NEXT:    #APP
827; RV32I-MEDIUM-NEXT:    lw a0, 4(a0)
828; RV32I-MEDIUM-NEXT:    #NO_APP
829; RV32I-MEDIUM-NEXT:    ret
830;
831; RV64I-MEDIUM-LABEL: constraint_o_with_offset:
832; RV64I-MEDIUM:       # %bb.0:
833; RV64I-MEDIUM-NEXT:    #APP
834; RV64I-MEDIUM-NEXT:    lw a0, 4(a0)
835; RV64I-MEDIUM-NEXT:    #NO_APP
836; RV64I-MEDIUM-NEXT:    ret
837  %1 = getelementptr i32, ptr %a, i32 1
838  %2 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %1)
839  ret i32 %2
840}
841
842define void @constraint_o_with_global_1() nounwind {
843; RV32I-LABEL: constraint_o_with_global_1:
844; RV32I:       # %bb.0:
845; RV32I-NEXT:    lui a0, %hi(eg)
846; RV32I-NEXT:    #APP
847; RV32I-NEXT:    sw zero, %lo(eg)(a0)
848; RV32I-NEXT:    #NO_APP
849; RV32I-NEXT:    ret
850;
851; RV64I-LABEL: constraint_o_with_global_1:
852; RV64I:       # %bb.0:
853; RV64I-NEXT:    lui a0, %hi(eg)
854; RV64I-NEXT:    #APP
855; RV64I-NEXT:    sw zero, %lo(eg)(a0)
856; RV64I-NEXT:    #NO_APP
857; RV64I-NEXT:    ret
858;
859; RV32I-MEDIUM-LABEL: constraint_o_with_global_1:
860; RV32I-MEDIUM:       # %bb.0:
861; RV32I-MEDIUM-NEXT:  .Lpcrel_hi13:
862; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
863; RV32I-MEDIUM-NEXT:    #APP
864; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi13)(a0)
865; RV32I-MEDIUM-NEXT:    #NO_APP
866; RV32I-MEDIUM-NEXT:    ret
867;
868; RV64I-MEDIUM-LABEL: constraint_o_with_global_1:
869; RV64I-MEDIUM:       # %bb.0:
870; RV64I-MEDIUM-NEXT:  .Lpcrel_hi13:
871; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
872; RV64I-MEDIUM-NEXT:    #APP
873; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi13)(a0)
874; RV64I-MEDIUM-NEXT:    #NO_APP
875; RV64I-MEDIUM-NEXT:    ret
876  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
877  ret void
878}
879
880define void @constraint_o_with_global_2() nounwind {
881; RV32I-LABEL: constraint_o_with_global_2:
882; RV32I:       # %bb.0:
883; RV32I-NEXT:    lui a0, %hi(eg+4)
884; RV32I-NEXT:    #APP
885; RV32I-NEXT:    sw zero, %lo(eg+4)(a0)
886; RV32I-NEXT:    #NO_APP
887; RV32I-NEXT:    ret
888;
889; RV64I-LABEL: constraint_o_with_global_2:
890; RV64I:       # %bb.0:
891; RV64I-NEXT:    lui a0, %hi(eg+4)
892; RV64I-NEXT:    #APP
893; RV64I-NEXT:    sw zero, %lo(eg+4)(a0)
894; RV64I-NEXT:    #NO_APP
895; RV64I-NEXT:    ret
896;
897; RV32I-MEDIUM-LABEL: constraint_o_with_global_2:
898; RV32I-MEDIUM:       # %bb.0:
899; RV32I-MEDIUM-NEXT:  .Lpcrel_hi14:
900; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+4)
901; RV32I-MEDIUM-NEXT:    #APP
902; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi14)(a0)
903; RV32I-MEDIUM-NEXT:    #NO_APP
904; RV32I-MEDIUM-NEXT:    ret
905;
906; RV64I-MEDIUM-LABEL: constraint_o_with_global_2:
907; RV64I-MEDIUM:       # %bb.0:
908; RV64I-MEDIUM-NEXT:  .Lpcrel_hi14:
909; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+4)
910; RV64I-MEDIUM-NEXT:    #APP
911; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi14)(a0)
912; RV64I-MEDIUM-NEXT:    #NO_APP
913; RV64I-MEDIUM-NEXT:    ret
914  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 1))
915  ret void
916}
917
918define void @constraint_o_with_global_3() nounwind {
919; RV32I-LABEL: constraint_o_with_global_3:
920; RV32I:       # %bb.0:
921; RV32I-NEXT:    lui a0, %hi(eg+8000)
922; RV32I-NEXT:    #APP
923; RV32I-NEXT:    sw zero, %lo(eg+8000)(a0)
924; RV32I-NEXT:    #NO_APP
925; RV32I-NEXT:    ret
926;
927; RV64I-LABEL: constraint_o_with_global_3:
928; RV64I:       # %bb.0:
929; RV64I-NEXT:    lui a0, %hi(eg+8000)
930; RV64I-NEXT:    #APP
931; RV64I-NEXT:    sw zero, %lo(eg+8000)(a0)
932; RV64I-NEXT:    #NO_APP
933; RV64I-NEXT:    ret
934;
935; RV32I-MEDIUM-LABEL: constraint_o_with_global_3:
936; RV32I-MEDIUM:       # %bb.0:
937; RV32I-MEDIUM-NEXT:  .Lpcrel_hi15:
938; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
939; RV32I-MEDIUM-NEXT:    #APP
940; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi15)(a0)
941; RV32I-MEDIUM-NEXT:    #NO_APP
942; RV32I-MEDIUM-NEXT:    ret
943;
944; RV64I-MEDIUM-LABEL: constraint_o_with_global_3:
945; RV64I-MEDIUM:       # %bb.0:
946; RV64I-MEDIUM-NEXT:  .Lpcrel_hi15:
947; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
948; RV64I-MEDIUM-NEXT:    #APP
949; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi15)(a0)
950; RV64I-MEDIUM-NEXT:    #NO_APP
951; RV64I-MEDIUM-NEXT:    ret
952  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 2000))
953  ret void
954}
955
956define void @constraint_o_with_extern_weak_global_1() nounwind {
957; RV32I-LABEL: constraint_o_with_extern_weak_global_1:
958; RV32I:       # %bb.0:
959; RV32I-NEXT:    lui a0, %hi(ewg)
960; RV32I-NEXT:    #APP
961; RV32I-NEXT:    sw zero, %lo(ewg)(a0)
962; RV32I-NEXT:    #NO_APP
963; RV32I-NEXT:    ret
964;
965; RV64I-LABEL: constraint_o_with_extern_weak_global_1:
966; RV64I:       # %bb.0:
967; RV64I-NEXT:    lui a0, %hi(ewg)
968; RV64I-NEXT:    #APP
969; RV64I-NEXT:    sw zero, %lo(ewg)(a0)
970; RV64I-NEXT:    #NO_APP
971; RV64I-NEXT:    ret
972;
973; RV32I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_1:
974; RV32I-MEDIUM:       # %bb.0:
975; RV32I-MEDIUM-NEXT:  .Lpcrel_hi16:
976; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
977; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi16)(a0)
978; RV32I-MEDIUM-NEXT:    #APP
979; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
980; RV32I-MEDIUM-NEXT:    #NO_APP
981; RV32I-MEDIUM-NEXT:    ret
982;
983; RV64I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_1:
984; RV64I-MEDIUM:       # %bb.0:
985; RV64I-MEDIUM-NEXT:  .Lpcrel_hi16:
986; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
987; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi16)(a0)
988; RV64I-MEDIUM-NEXT:    #APP
989; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
990; RV64I-MEDIUM-NEXT:    #NO_APP
991; RV64I-MEDIUM-NEXT:    ret
992  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @ewg)
993  ret void
994}
995
996define void @constraint_o_with_extern_weak_global_2() nounwind {
997; RV32I-LABEL: constraint_o_with_extern_weak_global_2:
998; RV32I:       # %bb.0:
999; RV32I-NEXT:    lui a0, %hi(ewg+4)
1000; RV32I-NEXT:    #APP
1001; RV32I-NEXT:    sw zero, %lo(ewg+4)(a0)
1002; RV32I-NEXT:    #NO_APP
1003; RV32I-NEXT:    ret
1004;
1005; RV64I-LABEL: constraint_o_with_extern_weak_global_2:
1006; RV64I:       # %bb.0:
1007; RV64I-NEXT:    lui a0, %hi(ewg+4)
1008; RV64I-NEXT:    #APP
1009; RV64I-NEXT:    sw zero, %lo(ewg+4)(a0)
1010; RV64I-NEXT:    #NO_APP
1011; RV64I-NEXT:    ret
1012;
1013; RV32I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_2:
1014; RV32I-MEDIUM:       # %bb.0:
1015; RV32I-MEDIUM-NEXT:  .Lpcrel_hi17:
1016; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1017; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi17)(a0)
1018; RV32I-MEDIUM-NEXT:    #APP
1019; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
1020; RV32I-MEDIUM-NEXT:    #NO_APP
1021; RV32I-MEDIUM-NEXT:    ret
1022;
1023; RV64I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_2:
1024; RV64I-MEDIUM:       # %bb.0:
1025; RV64I-MEDIUM-NEXT:  .Lpcrel_hi17:
1026; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1027; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi17)(a0)
1028; RV64I-MEDIUM-NEXT:    #APP
1029; RV64I-MEDIUM-NEXT:    sw zero, 4(a0)
1030; RV64I-MEDIUM-NEXT:    #NO_APP
1031; RV64I-MEDIUM-NEXT:    ret
1032  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 1))
1033  ret void
1034}
1035
1036define void @constraint_o_with_extern_weak_global_3() nounwind {
1037; RV32I-LABEL: constraint_o_with_extern_weak_global_3:
1038; RV32I:       # %bb.0:
1039; RV32I-NEXT:    lui a0, %hi(ewg+8000)
1040; RV32I-NEXT:    #APP
1041; RV32I-NEXT:    sw zero, %lo(ewg+8000)(a0)
1042; RV32I-NEXT:    #NO_APP
1043; RV32I-NEXT:    ret
1044;
1045; RV64I-LABEL: constraint_o_with_extern_weak_global_3:
1046; RV64I:       # %bb.0:
1047; RV64I-NEXT:    lui a0, %hi(ewg+8000)
1048; RV64I-NEXT:    #APP
1049; RV64I-NEXT:    sw zero, %lo(ewg+8000)(a0)
1050; RV64I-NEXT:    #NO_APP
1051; RV64I-NEXT:    ret
1052;
1053; RV32I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_3:
1054; RV32I-MEDIUM:       # %bb.0:
1055; RV32I-MEDIUM-NEXT:  .Lpcrel_hi18:
1056; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1057; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi18)(a0)
1058; RV32I-MEDIUM-NEXT:    lui a1, 2
1059; RV32I-MEDIUM-NEXT:    addi a1, a1, -192
1060; RV32I-MEDIUM-NEXT:    add a0, a0, a1
1061; RV32I-MEDIUM-NEXT:    #APP
1062; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1063; RV32I-MEDIUM-NEXT:    #NO_APP
1064; RV32I-MEDIUM-NEXT:    ret
1065;
1066; RV64I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_3:
1067; RV64I-MEDIUM:       # %bb.0:
1068; RV64I-MEDIUM-NEXT:  .Lpcrel_hi18:
1069; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1070; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi18)(a0)
1071; RV64I-MEDIUM-NEXT:    lui a1, 2
1072; RV64I-MEDIUM-NEXT:    addiw a1, a1, -192
1073; RV64I-MEDIUM-NEXT:    add a0, a0, a1
1074; RV64I-MEDIUM-NEXT:    #APP
1075; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1076; RV64I-MEDIUM-NEXT:    #NO_APP
1077; RV64I-MEDIUM-NEXT:    ret
1078  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 2000))
1079  ret void
1080}
1081
1082define void @constraint_o_with_multi_operands() nounwind {
1083; RV32I-LABEL: constraint_o_with_multi_operands:
1084; RV32I:       # %bb.0:
1085; RV32I-NEXT:    lui a0, %hi(eg)
1086; RV32I-NEXT:    #APP
1087; RV32I-NEXT:    sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
1088; RV32I-NEXT:    #NO_APP
1089; RV32I-NEXT:    ret
1090;
1091; RV64I-LABEL: constraint_o_with_multi_operands:
1092; RV64I:       # %bb.0:
1093; RV64I-NEXT:    lui a0, %hi(eg)
1094; RV64I-NEXT:    #APP
1095; RV64I-NEXT:    sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
1096; RV64I-NEXT:    #NO_APP
1097; RV64I-NEXT:    ret
1098;
1099; RV32I-MEDIUM-LABEL: constraint_o_with_multi_operands:
1100; RV32I-MEDIUM:       # %bb.0:
1101; RV32I-MEDIUM-NEXT:  .Lpcrel_hi19:
1102; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1103; RV32I-MEDIUM-NEXT:    #APP
1104; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi19)(a0) \n sw zero, %pcrel_lo(.Lpcrel_hi19)(a0)
1105; RV32I-MEDIUM-NEXT:    #NO_APP
1106; RV32I-MEDIUM-NEXT:    ret
1107;
1108; RV64I-MEDIUM-LABEL: constraint_o_with_multi_operands:
1109; RV64I-MEDIUM:       # %bb.0:
1110; RV64I-MEDIUM-NEXT:  .Lpcrel_hi19:
1111; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1112; RV64I-MEDIUM-NEXT:    #APP
1113; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi19)(a0) \n sw zero, %pcrel_lo(.Lpcrel_hi19)(a0)
1114; RV64I-MEDIUM-NEXT:    #NO_APP
1115; RV64I-MEDIUM-NEXT:    ret
1116  call void asm "sw zero, $0 \n sw zero, $1", "=*o,=*o"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
1117  ret void
1118}
1119
1120define void @constraint_o_with_multi_asm() nounwind {
1121; RV32I-LABEL: constraint_o_with_multi_asm:
1122; RV32I:       # %bb.0:
1123; RV32I-NEXT:    lui a0, %hi(eg)
1124; RV32I-NEXT:    #APP
1125; RV32I-NEXT:    sw zero, %lo(eg)(a0)
1126; RV32I-NEXT:    #NO_APP
1127; RV32I-NEXT:    #APP
1128; RV32I-NEXT:    sw zero, %lo(eg)(a0)
1129; RV32I-NEXT:    #NO_APP
1130; RV32I-NEXT:    ret
1131;
1132; RV64I-LABEL: constraint_o_with_multi_asm:
1133; RV64I:       # %bb.0:
1134; RV64I-NEXT:    lui a0, %hi(eg)
1135; RV64I-NEXT:    #APP
1136; RV64I-NEXT:    sw zero, %lo(eg)(a0)
1137; RV64I-NEXT:    #NO_APP
1138; RV64I-NEXT:    #APP
1139; RV64I-NEXT:    sw zero, %lo(eg)(a0)
1140; RV64I-NEXT:    #NO_APP
1141; RV64I-NEXT:    ret
1142;
1143; RV32I-MEDIUM-LABEL: constraint_o_with_multi_asm:
1144; RV32I-MEDIUM:       # %bb.0:
1145; RV32I-MEDIUM-NEXT:  .Lpcrel_hi20:
1146; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1147; RV32I-MEDIUM-NEXT:    #APP
1148; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi20)(a0)
1149; RV32I-MEDIUM-NEXT:    #NO_APP
1150; RV32I-MEDIUM-NEXT:    #APP
1151; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi20)(a0)
1152; RV32I-MEDIUM-NEXT:    #NO_APP
1153; RV32I-MEDIUM-NEXT:    ret
1154;
1155; RV64I-MEDIUM-LABEL: constraint_o_with_multi_asm:
1156; RV64I-MEDIUM:       # %bb.0:
1157; RV64I-MEDIUM-NEXT:  .Lpcrel_hi20:
1158; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1159; RV64I-MEDIUM-NEXT:    #APP
1160; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi20)(a0)
1161; RV64I-MEDIUM-NEXT:    #NO_APP
1162; RV64I-MEDIUM-NEXT:    #APP
1163; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi20)(a0)
1164; RV64I-MEDIUM-NEXT:    #NO_APP
1165; RV64I-MEDIUM-NEXT:    ret
1166  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
1167  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
1168  ret void
1169}
1170
1171define i32 @constraint_o_with_callbr_multi_operands(i32 %a) {
1172; RV32I-LABEL: constraint_o_with_callbr_multi_operands:
1173; RV32I:       # %bb.0: # %entry
1174; RV32I-NEXT:    lui a1, %hi(eg)
1175; RV32I-NEXT:    #APP
1176; RV32I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB27_2
1177; RV32I-NEXT:    #NO_APP
1178; RV32I-NEXT:  # %bb.1: # %normal
1179; RV32I-NEXT:    li a0, 0
1180; RV32I-NEXT:    ret
1181; RV32I-NEXT:  .LBB27_2: # Block address taken
1182; RV32I-NEXT:    # %fail
1183; RV32I-NEXT:    # Label of block must be emitted
1184; RV32I-NEXT:    li a0, 1
1185; RV32I-NEXT:    ret
1186;
1187; RV64I-LABEL: constraint_o_with_callbr_multi_operands:
1188; RV64I:       # %bb.0: # %entry
1189; RV64I-NEXT:    lui a1, %hi(eg)
1190; RV64I-NEXT:    #APP
1191; RV64I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB27_2
1192; RV64I-NEXT:    #NO_APP
1193; RV64I-NEXT:  # %bb.1: # %normal
1194; RV64I-NEXT:    li a0, 0
1195; RV64I-NEXT:    ret
1196; RV64I-NEXT:  .LBB27_2: # Block address taken
1197; RV64I-NEXT:    # %fail
1198; RV64I-NEXT:    # Label of block must be emitted
1199; RV64I-NEXT:    li a0, 1
1200; RV64I-NEXT:    ret
1201;
1202; RV32I-MEDIUM-LABEL: constraint_o_with_callbr_multi_operands:
1203; RV32I-MEDIUM:       # %bb.0: # %entry
1204; RV32I-MEDIUM-NEXT:  .Lpcrel_hi21:
1205; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1206; RV32I-MEDIUM-NEXT:    #APP
1207; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi21)(a1); sw zero, %pcrel_lo(.Lpcrel_hi21)(a1); beqz a0, .LBB27_2
1208; RV32I-MEDIUM-NEXT:    #NO_APP
1209; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal
1210; RV32I-MEDIUM-NEXT:    li a0, 0
1211; RV32I-MEDIUM-NEXT:    ret
1212; RV32I-MEDIUM-NEXT:  .LBB27_2: # Block address taken
1213; RV32I-MEDIUM-NEXT:    # %fail
1214; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
1215; RV32I-MEDIUM-NEXT:    li a0, 1
1216; RV32I-MEDIUM-NEXT:    ret
1217;
1218; RV64I-MEDIUM-LABEL: constraint_o_with_callbr_multi_operands:
1219; RV64I-MEDIUM:       # %bb.0: # %entry
1220; RV64I-MEDIUM-NEXT:  .Lpcrel_hi21:
1221; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1222; RV64I-MEDIUM-NEXT:    #APP
1223; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi21)(a1); sw zero, %pcrel_lo(.Lpcrel_hi21)(a1); beqz a0, .LBB27_2
1224; RV64I-MEDIUM-NEXT:    #NO_APP
1225; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal
1226; RV64I-MEDIUM-NEXT:    li a0, 0
1227; RV64I-MEDIUM-NEXT:    ret
1228; RV64I-MEDIUM-NEXT:  .LBB27_2: # Block address taken
1229; RV64I-MEDIUM-NEXT:    # %fail
1230; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
1231; RV64I-MEDIUM-NEXT:    li a0, 1
1232; RV64I-MEDIUM-NEXT:    ret
1233entry:
1234  callbr void asm "sw zero, $0; sw zero, $1; beqz $2, $3", "=*m,=*m,r,!i"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg, i32 %a) to label %normal [label %fail]
1235
1236normal:
1237  ret i32 0
1238
1239fail:
1240  ret i32 1
1241}
1242
1243define i32 @constraint_o_with_multi_callbr_asm(i32 %a) {
1244; RV32I-LABEL: constraint_o_with_multi_callbr_asm:
1245; RV32I:       # %bb.0: # %entry
1246; RV32I-NEXT:    lui a1, %hi(eg)
1247; RV32I-NEXT:    #APP
1248; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB28_3
1249; RV32I-NEXT:    #NO_APP
1250; RV32I-NEXT:  # %bb.1: # %normal0
1251; RV32I-NEXT:    #APP
1252; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB28_3
1253; RV32I-NEXT:    #NO_APP
1254; RV32I-NEXT:  # %bb.2: # %normal1
1255; RV32I-NEXT:    li a0, 0
1256; RV32I-NEXT:    ret
1257; RV32I-NEXT:  .LBB28_3: # Block address taken
1258; RV32I-NEXT:    # %fail
1259; RV32I-NEXT:    # Label of block must be emitted
1260; RV32I-NEXT:    li a0, 1
1261; RV32I-NEXT:    ret
1262;
1263; RV64I-LABEL: constraint_o_with_multi_callbr_asm:
1264; RV64I:       # %bb.0: # %entry
1265; RV64I-NEXT:    lui a1, %hi(eg)
1266; RV64I-NEXT:    #APP
1267; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB28_3
1268; RV64I-NEXT:    #NO_APP
1269; RV64I-NEXT:  # %bb.1: # %normal0
1270; RV64I-NEXT:    #APP
1271; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB28_3
1272; RV64I-NEXT:    #NO_APP
1273; RV64I-NEXT:  # %bb.2: # %normal1
1274; RV64I-NEXT:    li a0, 0
1275; RV64I-NEXT:    ret
1276; RV64I-NEXT:  .LBB28_3: # Block address taken
1277; RV64I-NEXT:    # %fail
1278; RV64I-NEXT:    # Label of block must be emitted
1279; RV64I-NEXT:    li a0, 1
1280; RV64I-NEXT:    ret
1281;
1282; RV32I-MEDIUM-LABEL: constraint_o_with_multi_callbr_asm:
1283; RV32I-MEDIUM:       # %bb.0: # %entry
1284; RV32I-MEDIUM-NEXT:  .Lpcrel_hi22:
1285; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1286; RV32I-MEDIUM-NEXT:    #APP
1287; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi22)(a1); beqz a0, .LBB28_3
1288; RV32I-MEDIUM-NEXT:    #NO_APP
1289; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal0
1290; RV32I-MEDIUM-NEXT:    #APP
1291; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi22)(a1); beqz a0, .LBB28_3
1292; RV32I-MEDIUM-NEXT:    #NO_APP
1293; RV32I-MEDIUM-NEXT:  # %bb.2: # %normal1
1294; RV32I-MEDIUM-NEXT:    li a0, 0
1295; RV32I-MEDIUM-NEXT:    ret
1296; RV32I-MEDIUM-NEXT:  .LBB28_3: # Block address taken
1297; RV32I-MEDIUM-NEXT:    # %fail
1298; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
1299; RV32I-MEDIUM-NEXT:    li a0, 1
1300; RV32I-MEDIUM-NEXT:    ret
1301;
1302; RV64I-MEDIUM-LABEL: constraint_o_with_multi_callbr_asm:
1303; RV64I-MEDIUM:       # %bb.0: # %entry
1304; RV64I-MEDIUM-NEXT:  .Lpcrel_hi22:
1305; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1306; RV64I-MEDIUM-NEXT:    #APP
1307; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi22)(a1); beqz a0, .LBB28_3
1308; RV64I-MEDIUM-NEXT:    #NO_APP
1309; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal0
1310; RV64I-MEDIUM-NEXT:    #APP
1311; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi22)(a1); beqz a0, .LBB28_3
1312; RV64I-MEDIUM-NEXT:    #NO_APP
1313; RV64I-MEDIUM-NEXT:  # %bb.2: # %normal1
1314; RV64I-MEDIUM-NEXT:    li a0, 0
1315; RV64I-MEDIUM-NEXT:    ret
1316; RV64I-MEDIUM-NEXT:  .LBB28_3: # Block address taken
1317; RV64I-MEDIUM-NEXT:    # %fail
1318; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
1319; RV64I-MEDIUM-NEXT:    li a0, 1
1320; RV64I-MEDIUM-NEXT:    ret
1321entry:
1322  callbr void asm "sw zero, $0; beqz $1, $2", "=*o,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
1323
1324normal0:
1325  callbr void asm "sw zero, $0; beqz $1, $2", "=*o,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal1 [label %fail]
1326
1327normal1:
1328  ret i32 0
1329
1330fail:
1331  ret i32 1
1332}
1333
1334define void @constraint_o_with_local_1() nounwind {
1335; RV32I-LABEL: constraint_o_with_local_1:
1336; RV32I:       # %bb.0: # %entry
1337; RV32I-NEXT:  .Ltmp3: # Block address taken
1338; RV32I-NEXT:  # %bb.1: # %label
1339; RV32I-NEXT:    lui a0, %hi(.Ltmp3)
1340; RV32I-NEXT:    #APP
1341; RV32I-NEXT:    lw zero, %lo(.Ltmp3)(a0)
1342; RV32I-NEXT:    #NO_APP
1343; RV32I-NEXT:    ret
1344;
1345; RV64I-LABEL: constraint_o_with_local_1:
1346; RV64I:       # %bb.0: # %entry
1347; RV64I-NEXT:  .Ltmp3: # Block address taken
1348; RV64I-NEXT:  # %bb.1: # %label
1349; RV64I-NEXT:    lui a0, %hi(.Ltmp3)
1350; RV64I-NEXT:    #APP
1351; RV64I-NEXT:    lw zero, %lo(.Ltmp3)(a0)
1352; RV64I-NEXT:    #NO_APP
1353; RV64I-NEXT:    ret
1354;
1355; RV32I-MEDIUM-LABEL: constraint_o_with_local_1:
1356; RV32I-MEDIUM:       # %bb.0: # %entry
1357; RV32I-MEDIUM-NEXT:  .Ltmp3: # Block address taken
1358; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
1359; RV32I-MEDIUM-NEXT:  .Lpcrel_hi23:
1360; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp3)
1361; RV32I-MEDIUM-NEXT:    #APP
1362; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi23)(a0)
1363; RV32I-MEDIUM-NEXT:    #NO_APP
1364; RV32I-MEDIUM-NEXT:    ret
1365;
1366; RV64I-MEDIUM-LABEL: constraint_o_with_local_1:
1367; RV64I-MEDIUM:       # %bb.0: # %entry
1368; RV64I-MEDIUM-NEXT:  .Ltmp3: # Block address taken
1369; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
1370; RV64I-MEDIUM-NEXT:  .Lpcrel_hi23:
1371; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp3)
1372; RV64I-MEDIUM-NEXT:    #APP
1373; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi23)(a0)
1374; RV64I-MEDIUM-NEXT:    #NO_APP
1375; RV64I-MEDIUM-NEXT:    ret
1376entry:
1377  br label %label
1378
1379label:
1380  tail call void asm sideeffect "lw zero, $0", "*o"(ptr elementtype(ptr) blockaddress(@constraint_o_with_local_1, %label))
1381  ret void
1382}
1383
1384define void @constraint_o_with_local_2() nounwind {
1385; RV32I-LABEL: constraint_o_with_local_2:
1386; RV32I:       # %bb.0: # %entry
1387; RV32I-NEXT:  .Ltmp4: # Block address taken
1388; RV32I-NEXT:  # %bb.1: # %label
1389; RV32I-NEXT:    lui a0, %hi(.Ltmp4+4)
1390; RV32I-NEXT:    #APP
1391; RV32I-NEXT:    lw zero, %lo(.Ltmp4+4)(a0)
1392; RV32I-NEXT:    #NO_APP
1393; RV32I-NEXT:    ret
1394;
1395; RV64I-LABEL: constraint_o_with_local_2:
1396; RV64I:       # %bb.0: # %entry
1397; RV64I-NEXT:  .Ltmp4: # Block address taken
1398; RV64I-NEXT:  # %bb.1: # %label
1399; RV64I-NEXT:    lui a0, %hi(.Ltmp4+4)
1400; RV64I-NEXT:    #APP
1401; RV64I-NEXT:    lw zero, %lo(.Ltmp4+4)(a0)
1402; RV64I-NEXT:    #NO_APP
1403; RV64I-NEXT:    ret
1404;
1405; RV32I-MEDIUM-LABEL: constraint_o_with_local_2:
1406; RV32I-MEDIUM:       # %bb.0: # %entry
1407; RV32I-MEDIUM-NEXT:  .Ltmp4: # Block address taken
1408; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
1409; RV32I-MEDIUM-NEXT:  .Lpcrel_hi24:
1410; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp4+4)
1411; RV32I-MEDIUM-NEXT:    #APP
1412; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi24)(a0)
1413; RV32I-MEDIUM-NEXT:    #NO_APP
1414; RV32I-MEDIUM-NEXT:    ret
1415;
1416; RV64I-MEDIUM-LABEL: constraint_o_with_local_2:
1417; RV64I-MEDIUM:       # %bb.0: # %entry
1418; RV64I-MEDIUM-NEXT:  .Ltmp4: # Block address taken
1419; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
1420; RV64I-MEDIUM-NEXT:  .Lpcrel_hi24:
1421; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp4+4)
1422; RV64I-MEDIUM-NEXT:    #APP
1423; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi24)(a0)
1424; RV64I-MEDIUM-NEXT:    #NO_APP
1425; RV64I-MEDIUM-NEXT:    ret
1426entry:
1427  br label %label
1428
1429label:
1430  call void asm "lw zero, $0", "*o"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_o_with_local_2, %label), i32 4))
1431  ret void
1432}
1433
1434define void @constraint_o_with_local_3() nounwind {
1435; RV32I-LABEL: constraint_o_with_local_3:
1436; RV32I:       # %bb.0: # %entry
1437; RV32I-NEXT:  .Ltmp5: # Block address taken
1438; RV32I-NEXT:  # %bb.1: # %label
1439; RV32I-NEXT:    lui a0, %hi(.Ltmp5+2000)
1440; RV32I-NEXT:    #APP
1441; RV32I-NEXT:    lw zero, %lo(.Ltmp5+2000)(a0)
1442; RV32I-NEXT:    #NO_APP
1443; RV32I-NEXT:    ret
1444;
1445; RV64I-LABEL: constraint_o_with_local_3:
1446; RV64I:       # %bb.0: # %entry
1447; RV64I-NEXT:  .Ltmp5: # Block address taken
1448; RV64I-NEXT:  # %bb.1: # %label
1449; RV64I-NEXT:    lui a0, %hi(.Ltmp5+2000)
1450; RV64I-NEXT:    #APP
1451; RV64I-NEXT:    lw zero, %lo(.Ltmp5+2000)(a0)
1452; RV64I-NEXT:    #NO_APP
1453; RV64I-NEXT:    ret
1454;
1455; RV32I-MEDIUM-LABEL: constraint_o_with_local_3:
1456; RV32I-MEDIUM:       # %bb.0: # %entry
1457; RV32I-MEDIUM-NEXT:  .Ltmp5: # Block address taken
1458; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
1459; RV32I-MEDIUM-NEXT:  .Lpcrel_hi25:
1460; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp5+2000)
1461; RV32I-MEDIUM-NEXT:    #APP
1462; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi25)(a0)
1463; RV32I-MEDIUM-NEXT:    #NO_APP
1464; RV32I-MEDIUM-NEXT:    ret
1465;
1466; RV64I-MEDIUM-LABEL: constraint_o_with_local_3:
1467; RV64I-MEDIUM:       # %bb.0: # %entry
1468; RV64I-MEDIUM-NEXT:  .Ltmp5: # Block address taken
1469; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
1470; RV64I-MEDIUM-NEXT:  .Lpcrel_hi25:
1471; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp5+2000)
1472; RV64I-MEDIUM-NEXT:    #APP
1473; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi25)(a0)
1474; RV64I-MEDIUM-NEXT:    #NO_APP
1475; RV64I-MEDIUM-NEXT:    ret
1476entry:
1477  br label %label
1478
1479label:
1480  call void asm "lw zero, $0", "*o"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_o_with_local_3, %label), i32 2000))
1481  ret void
1482}
1483
1484define void @constraint_A(ptr %a) nounwind {
1485; RV32I-LABEL: constraint_A:
1486; RV32I:       # %bb.0:
1487; RV32I-NEXT:    #APP
1488; RV32I-NEXT:    sb s0, 0(a0)
1489; RV32I-NEXT:    #NO_APP
1490; RV32I-NEXT:    #APP
1491; RV32I-NEXT:    lb s1, 0(a0)
1492; RV32I-NEXT:    #NO_APP
1493; RV32I-NEXT:    ret
1494;
1495; RV64I-LABEL: constraint_A:
1496; RV64I:       # %bb.0:
1497; RV64I-NEXT:    #APP
1498; RV64I-NEXT:    sb s0, 0(a0)
1499; RV64I-NEXT:    #NO_APP
1500; RV64I-NEXT:    #APP
1501; RV64I-NEXT:    lb s1, 0(a0)
1502; RV64I-NEXT:    #NO_APP
1503; RV64I-NEXT:    ret
1504;
1505; RV32I-MEDIUM-LABEL: constraint_A:
1506; RV32I-MEDIUM:       # %bb.0:
1507; RV32I-MEDIUM-NEXT:    #APP
1508; RV32I-MEDIUM-NEXT:    sb s0, 0(a0)
1509; RV32I-MEDIUM-NEXT:    #NO_APP
1510; RV32I-MEDIUM-NEXT:    #APP
1511; RV32I-MEDIUM-NEXT:    lb s1, 0(a0)
1512; RV32I-MEDIUM-NEXT:    #NO_APP
1513; RV32I-MEDIUM-NEXT:    ret
1514;
1515; RV64I-MEDIUM-LABEL: constraint_A:
1516; RV64I-MEDIUM:       # %bb.0:
1517; RV64I-MEDIUM-NEXT:    #APP
1518; RV64I-MEDIUM-NEXT:    sb s0, 0(a0)
1519; RV64I-MEDIUM-NEXT:    #NO_APP
1520; RV64I-MEDIUM-NEXT:    #APP
1521; RV64I-MEDIUM-NEXT:    lb s1, 0(a0)
1522; RV64I-MEDIUM-NEXT:    #NO_APP
1523; RV64I-MEDIUM-NEXT:    ret
1524  tail call void asm sideeffect "sb s0, $0", "*A"(ptr elementtype(i8) %a)
1525  tail call void asm sideeffect "lb s1, $0", "*A"(ptr elementtype(i8) %a)
1526  ret void
1527}
1528
1529define i32 @constraint_A_with_offset(ptr %a) nounwind {
1530; RV32I-LABEL: constraint_A_with_offset:
1531; RV32I:       # %bb.0:
1532; RV32I-NEXT:    addi a0, a0, 4
1533; RV32I-NEXT:    #APP
1534; RV32I-NEXT:    lw a0, 0(a0)
1535; RV32I-NEXT:    #NO_APP
1536; RV32I-NEXT:    ret
1537;
1538; RV64I-LABEL: constraint_A_with_offset:
1539; RV64I:       # %bb.0:
1540; RV64I-NEXT:    addi a0, a0, 4
1541; RV64I-NEXT:    #APP
1542; RV64I-NEXT:    lw a0, 0(a0)
1543; RV64I-NEXT:    #NO_APP
1544; RV64I-NEXT:    ret
1545;
1546; RV32I-MEDIUM-LABEL: constraint_A_with_offset:
1547; RV32I-MEDIUM:       # %bb.0:
1548; RV32I-MEDIUM-NEXT:    addi a0, a0, 4
1549; RV32I-MEDIUM-NEXT:    #APP
1550; RV32I-MEDIUM-NEXT:    lw a0, 0(a0)
1551; RV32I-MEDIUM-NEXT:    #NO_APP
1552; RV32I-MEDIUM-NEXT:    ret
1553;
1554; RV64I-MEDIUM-LABEL: constraint_A_with_offset:
1555; RV64I-MEDIUM:       # %bb.0:
1556; RV64I-MEDIUM-NEXT:    addi a0, a0, 4
1557; RV64I-MEDIUM-NEXT:    #APP
1558; RV64I-MEDIUM-NEXT:    lw a0, 0(a0)
1559; RV64I-MEDIUM-NEXT:    #NO_APP
1560; RV64I-MEDIUM-NEXT:    ret
1561  %1 = getelementptr i32, ptr %a, i32 1
1562  %2 = tail call i32 asm "lw $0, $1", "=r,*A"(ptr elementtype(i32) %1)
1563  ret i32 %2
1564}
1565
1566define void @constraint_A_with_global_1() nounwind {
1567; RV32I-LABEL: constraint_A_with_global_1:
1568; RV32I:       # %bb.0:
1569; RV32I-NEXT:    lui a0, %hi(eg)
1570; RV32I-NEXT:    addi a0, a0, %lo(eg)
1571; RV32I-NEXT:    #APP
1572; RV32I-NEXT:    sw zero, 0(a0)
1573; RV32I-NEXT:    #NO_APP
1574; RV32I-NEXT:    ret
1575;
1576; RV64I-LABEL: constraint_A_with_global_1:
1577; RV64I:       # %bb.0:
1578; RV64I-NEXT:    lui a0, %hi(eg)
1579; RV64I-NEXT:    addi a0, a0, %lo(eg)
1580; RV64I-NEXT:    #APP
1581; RV64I-NEXT:    sw zero, 0(a0)
1582; RV64I-NEXT:    #NO_APP
1583; RV64I-NEXT:    ret
1584;
1585; RV32I-MEDIUM-LABEL: constraint_A_with_global_1:
1586; RV32I-MEDIUM:       # %bb.0:
1587; RV32I-MEDIUM-NEXT:  .Lpcrel_hi26:
1588; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1589; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi26)
1590; RV32I-MEDIUM-NEXT:    #APP
1591; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1592; RV32I-MEDIUM-NEXT:    #NO_APP
1593; RV32I-MEDIUM-NEXT:    ret
1594;
1595; RV64I-MEDIUM-LABEL: constraint_A_with_global_1:
1596; RV64I-MEDIUM:       # %bb.0:
1597; RV64I-MEDIUM-NEXT:  .Lpcrel_hi26:
1598; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1599; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi26)
1600; RV64I-MEDIUM-NEXT:    #APP
1601; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1602; RV64I-MEDIUM-NEXT:    #NO_APP
1603; RV64I-MEDIUM-NEXT:    ret
1604  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @eg)
1605  ret void
1606}
1607
1608define void @constraint_A_with_global_2() nounwind {
1609; RV32I-LABEL: constraint_A_with_global_2:
1610; RV32I:       # %bb.0:
1611; RV32I-NEXT:    lui a0, %hi(eg+4)
1612; RV32I-NEXT:    addi a0, a0, %lo(eg+4)
1613; RV32I-NEXT:    #APP
1614; RV32I-NEXT:    sw zero, 0(a0)
1615; RV32I-NEXT:    #NO_APP
1616; RV32I-NEXT:    ret
1617;
1618; RV64I-LABEL: constraint_A_with_global_2:
1619; RV64I:       # %bb.0:
1620; RV64I-NEXT:    lui a0, %hi(eg+4)
1621; RV64I-NEXT:    addi a0, a0, %lo(eg+4)
1622; RV64I-NEXT:    #APP
1623; RV64I-NEXT:    sw zero, 0(a0)
1624; RV64I-NEXT:    #NO_APP
1625; RV64I-NEXT:    ret
1626;
1627; RV32I-MEDIUM-LABEL: constraint_A_with_global_2:
1628; RV32I-MEDIUM:       # %bb.0:
1629; RV32I-MEDIUM-NEXT:  .Lpcrel_hi27:
1630; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+4)
1631; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi27)
1632; RV32I-MEDIUM-NEXT:    #APP
1633; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1634; RV32I-MEDIUM-NEXT:    #NO_APP
1635; RV32I-MEDIUM-NEXT:    ret
1636;
1637; RV64I-MEDIUM-LABEL: constraint_A_with_global_2:
1638; RV64I-MEDIUM:       # %bb.0:
1639; RV64I-MEDIUM-NEXT:  .Lpcrel_hi27:
1640; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+4)
1641; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi27)
1642; RV64I-MEDIUM-NEXT:    #APP
1643; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1644; RV64I-MEDIUM-NEXT:    #NO_APP
1645; RV64I-MEDIUM-NEXT:    ret
1646  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 1))
1647  ret void
1648}
1649
1650define void @constraint_A_with_global_3() nounwind {
1651; RV32I-LABEL: constraint_A_with_global_3:
1652; RV32I:       # %bb.0:
1653; RV32I-NEXT:    lui a0, %hi(eg+8000)
1654; RV32I-NEXT:    addi a0, a0, %lo(eg+8000)
1655; RV32I-NEXT:    #APP
1656; RV32I-NEXT:    sw zero, 0(a0)
1657; RV32I-NEXT:    #NO_APP
1658; RV32I-NEXT:    ret
1659;
1660; RV64I-LABEL: constraint_A_with_global_3:
1661; RV64I:       # %bb.0:
1662; RV64I-NEXT:    lui a0, %hi(eg+8000)
1663; RV64I-NEXT:    addi a0, a0, %lo(eg+8000)
1664; RV64I-NEXT:    #APP
1665; RV64I-NEXT:    sw zero, 0(a0)
1666; RV64I-NEXT:    #NO_APP
1667; RV64I-NEXT:    ret
1668;
1669; RV32I-MEDIUM-LABEL: constraint_A_with_global_3:
1670; RV32I-MEDIUM:       # %bb.0:
1671; RV32I-MEDIUM-NEXT:  .Lpcrel_hi28:
1672; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
1673; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi28)
1674; RV32I-MEDIUM-NEXT:    #APP
1675; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1676; RV32I-MEDIUM-NEXT:    #NO_APP
1677; RV32I-MEDIUM-NEXT:    ret
1678;
1679; RV64I-MEDIUM-LABEL: constraint_A_with_global_3:
1680; RV64I-MEDIUM:       # %bb.0:
1681; RV64I-MEDIUM-NEXT:  .Lpcrel_hi28:
1682; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
1683; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi28)
1684; RV64I-MEDIUM-NEXT:    #APP
1685; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1686; RV64I-MEDIUM-NEXT:    #NO_APP
1687; RV64I-MEDIUM-NEXT:    ret
1688  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @eg, i32 0, i32 2000))
1689  ret void
1690}
1691
1692define void @constraint_A_with_extern_weak_global_1() nounwind {
1693; RV32I-LABEL: constraint_A_with_extern_weak_global_1:
1694; RV32I:       # %bb.0:
1695; RV32I-NEXT:    lui a0, %hi(ewg)
1696; RV32I-NEXT:    addi a0, a0, %lo(ewg)
1697; RV32I-NEXT:    #APP
1698; RV32I-NEXT:    sw zero, 0(a0)
1699; RV32I-NEXT:    #NO_APP
1700; RV32I-NEXT:    ret
1701;
1702; RV64I-LABEL: constraint_A_with_extern_weak_global_1:
1703; RV64I:       # %bb.0:
1704; RV64I-NEXT:    lui a0, %hi(ewg)
1705; RV64I-NEXT:    addi a0, a0, %lo(ewg)
1706; RV64I-NEXT:    #APP
1707; RV64I-NEXT:    sw zero, 0(a0)
1708; RV64I-NEXT:    #NO_APP
1709; RV64I-NEXT:    ret
1710;
1711; RV32I-MEDIUM-LABEL: constraint_A_with_extern_weak_global_1:
1712; RV32I-MEDIUM:       # %bb.0:
1713; RV32I-MEDIUM-NEXT:  .Lpcrel_hi29:
1714; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1715; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi29)(a0)
1716; RV32I-MEDIUM-NEXT:    #APP
1717; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1718; RV32I-MEDIUM-NEXT:    #NO_APP
1719; RV32I-MEDIUM-NEXT:    ret
1720;
1721; RV64I-MEDIUM-LABEL: constraint_A_with_extern_weak_global_1:
1722; RV64I-MEDIUM:       # %bb.0:
1723; RV64I-MEDIUM-NEXT:  .Lpcrel_hi29:
1724; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1725; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi29)(a0)
1726; RV64I-MEDIUM-NEXT:    #APP
1727; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1728; RV64I-MEDIUM-NEXT:    #NO_APP
1729; RV64I-MEDIUM-NEXT:    ret
1730  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @ewg)
1731  ret void
1732}
1733
1734define void @constraint_A_with_extern_weak_global_2() nounwind {
1735; RV32I-LABEL: constraint_A_with_extern_weak_global_2:
1736; RV32I:       # %bb.0:
1737; RV32I-NEXT:    lui a0, %hi(ewg+4)
1738; RV32I-NEXT:    addi a0, a0, %lo(ewg+4)
1739; RV32I-NEXT:    #APP
1740; RV32I-NEXT:    sw zero, 0(a0)
1741; RV32I-NEXT:    #NO_APP
1742; RV32I-NEXT:    ret
1743;
1744; RV64I-LABEL: constraint_A_with_extern_weak_global_2:
1745; RV64I:       # %bb.0:
1746; RV64I-NEXT:    lui a0, %hi(ewg+4)
1747; RV64I-NEXT:    addi a0, a0, %lo(ewg+4)
1748; RV64I-NEXT:    #APP
1749; RV64I-NEXT:    sw zero, 0(a0)
1750; RV64I-NEXT:    #NO_APP
1751; RV64I-NEXT:    ret
1752;
1753; RV32I-MEDIUM-LABEL: constraint_A_with_extern_weak_global_2:
1754; RV32I-MEDIUM:       # %bb.0:
1755; RV32I-MEDIUM-NEXT:  .Lpcrel_hi30:
1756; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1757; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi30)(a0)
1758; RV32I-MEDIUM-NEXT:    addi a0, a0, 4
1759; RV32I-MEDIUM-NEXT:    #APP
1760; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1761; RV32I-MEDIUM-NEXT:    #NO_APP
1762; RV32I-MEDIUM-NEXT:    ret
1763;
1764; RV64I-MEDIUM-LABEL: constraint_A_with_extern_weak_global_2:
1765; RV64I-MEDIUM:       # %bb.0:
1766; RV64I-MEDIUM-NEXT:  .Lpcrel_hi30:
1767; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1768; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi30)(a0)
1769; RV64I-MEDIUM-NEXT:    addi a0, a0, 4
1770; RV64I-MEDIUM-NEXT:    #APP
1771; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1772; RV64I-MEDIUM-NEXT:    #NO_APP
1773; RV64I-MEDIUM-NEXT:    ret
1774  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 1))
1775  ret void
1776}
1777
1778define void @constraint_A_with_extern_weak_global_3() nounwind {
1779; RV32I-LABEL: constraint_A_with_extern_weak_global_3:
1780; RV32I:       # %bb.0:
1781; RV32I-NEXT:    lui a0, %hi(ewg+8000)
1782; RV32I-NEXT:    addi a0, a0, %lo(ewg+8000)
1783; RV32I-NEXT:    #APP
1784; RV32I-NEXT:    sw zero, 0(a0)
1785; RV32I-NEXT:    #NO_APP
1786; RV32I-NEXT:    ret
1787;
1788; RV64I-LABEL: constraint_A_with_extern_weak_global_3:
1789; RV64I:       # %bb.0:
1790; RV64I-NEXT:    lui a0, %hi(ewg+8000)
1791; RV64I-NEXT:    addi a0, a0, %lo(ewg+8000)
1792; RV64I-NEXT:    #APP
1793; RV64I-NEXT:    sw zero, 0(a0)
1794; RV64I-NEXT:    #NO_APP
1795; RV64I-NEXT:    ret
1796;
1797; RV32I-MEDIUM-LABEL: constraint_A_with_extern_weak_global_3:
1798; RV32I-MEDIUM:       # %bb.0:
1799; RV32I-MEDIUM-NEXT:  .Lpcrel_hi31:
1800; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1801; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi31)(a0)
1802; RV32I-MEDIUM-NEXT:    lui a1, 2
1803; RV32I-MEDIUM-NEXT:    addi a1, a1, -192
1804; RV32I-MEDIUM-NEXT:    add a0, a0, a1
1805; RV32I-MEDIUM-NEXT:    #APP
1806; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1807; RV32I-MEDIUM-NEXT:    #NO_APP
1808; RV32I-MEDIUM-NEXT:    ret
1809;
1810; RV64I-MEDIUM-LABEL: constraint_A_with_extern_weak_global_3:
1811; RV64I-MEDIUM:       # %bb.0:
1812; RV64I-MEDIUM-NEXT:  .Lpcrel_hi31:
1813; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
1814; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi31)(a0)
1815; RV64I-MEDIUM-NEXT:    lui a1, 2
1816; RV64I-MEDIUM-NEXT:    addiw a1, a1, -192
1817; RV64I-MEDIUM-NEXT:    add a0, a0, a1
1818; RV64I-MEDIUM-NEXT:    #APP
1819; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1820; RV64I-MEDIUM-NEXT:    #NO_APP
1821; RV64I-MEDIUM-NEXT:    ret
1822  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) getelementptr ([400000 x i32], ptr @ewg, i32 0, i32 2000))
1823  ret void
1824}
1825
1826define void @constraint_A_with_multi_operands() nounwind {
1827; RV32I-LABEL: constraint_A_with_multi_operands:
1828; RV32I:       # %bb.0:
1829; RV32I-NEXT:    lui a0, %hi(eg)
1830; RV32I-NEXT:    addi a0, a0, %lo(eg)
1831; RV32I-NEXT:    #APP
1832; RV32I-NEXT:    sw zero, 0(a0) \n sw zero, 0(a0)
1833; RV32I-NEXT:    #NO_APP
1834; RV32I-NEXT:    ret
1835;
1836; RV64I-LABEL: constraint_A_with_multi_operands:
1837; RV64I:       # %bb.0:
1838; RV64I-NEXT:    lui a0, %hi(eg)
1839; RV64I-NEXT:    addi a0, a0, %lo(eg)
1840; RV64I-NEXT:    #APP
1841; RV64I-NEXT:    sw zero, 0(a0) \n sw zero, 0(a0)
1842; RV64I-NEXT:    #NO_APP
1843; RV64I-NEXT:    ret
1844;
1845; RV32I-MEDIUM-LABEL: constraint_A_with_multi_operands:
1846; RV32I-MEDIUM:       # %bb.0:
1847; RV32I-MEDIUM-NEXT:  .Lpcrel_hi32:
1848; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1849; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi32)
1850; RV32I-MEDIUM-NEXT:    #APP
1851; RV32I-MEDIUM-NEXT:    sw zero, 0(a0) \n sw zero, 0(a0)
1852; RV32I-MEDIUM-NEXT:    #NO_APP
1853; RV32I-MEDIUM-NEXT:    ret
1854;
1855; RV64I-MEDIUM-LABEL: constraint_A_with_multi_operands:
1856; RV64I-MEDIUM:       # %bb.0:
1857; RV64I-MEDIUM-NEXT:  .Lpcrel_hi32:
1858; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1859; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi32)
1860; RV64I-MEDIUM-NEXT:    #APP
1861; RV64I-MEDIUM-NEXT:    sw zero, 0(a0) \n sw zero, 0(a0)
1862; RV64I-MEDIUM-NEXT:    #NO_APP
1863; RV64I-MEDIUM-NEXT:    ret
1864  call void asm "sw zero, $0 \n sw zero, $1", "=*A,=*A"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
1865  ret void
1866}
1867
1868define void @constraint_A_with_multi_asm() nounwind {
1869; RV32I-LABEL: constraint_A_with_multi_asm:
1870; RV32I:       # %bb.0:
1871; RV32I-NEXT:    lui a0, %hi(eg)
1872; RV32I-NEXT:    addi a0, a0, %lo(eg)
1873; RV32I-NEXT:    #APP
1874; RV32I-NEXT:    sw zero, 0(a0)
1875; RV32I-NEXT:    #NO_APP
1876; RV32I-NEXT:    #APP
1877; RV32I-NEXT:    sw zero, 0(a0)
1878; RV32I-NEXT:    #NO_APP
1879; RV32I-NEXT:    ret
1880;
1881; RV64I-LABEL: constraint_A_with_multi_asm:
1882; RV64I:       # %bb.0:
1883; RV64I-NEXT:    lui a0, %hi(eg)
1884; RV64I-NEXT:    addi a0, a0, %lo(eg)
1885; RV64I-NEXT:    #APP
1886; RV64I-NEXT:    sw zero, 0(a0)
1887; RV64I-NEXT:    #NO_APP
1888; RV64I-NEXT:    #APP
1889; RV64I-NEXT:    sw zero, 0(a0)
1890; RV64I-NEXT:    #NO_APP
1891; RV64I-NEXT:    ret
1892;
1893; RV32I-MEDIUM-LABEL: constraint_A_with_multi_asm:
1894; RV32I-MEDIUM:       # %bb.0:
1895; RV32I-MEDIUM-NEXT:  .Lpcrel_hi33:
1896; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1897; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi33)
1898; RV32I-MEDIUM-NEXT:    #APP
1899; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1900; RV32I-MEDIUM-NEXT:    #NO_APP
1901; RV32I-MEDIUM-NEXT:    #APP
1902; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1903; RV32I-MEDIUM-NEXT:    #NO_APP
1904; RV32I-MEDIUM-NEXT:    ret
1905;
1906; RV64I-MEDIUM-LABEL: constraint_A_with_multi_asm:
1907; RV64I-MEDIUM:       # %bb.0:
1908; RV64I-MEDIUM-NEXT:  .Lpcrel_hi33:
1909; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1910; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi33)
1911; RV64I-MEDIUM-NEXT:    #APP
1912; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1913; RV64I-MEDIUM-NEXT:    #NO_APP
1914; RV64I-MEDIUM-NEXT:    #APP
1915; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1916; RV64I-MEDIUM-NEXT:    #NO_APP
1917; RV64I-MEDIUM-NEXT:    ret
1918  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @eg)
1919  call void asm "sw zero, $0", "=*A"(ptr elementtype(i32) @eg)
1920  ret void
1921}
1922
1923define i32 @constraint_A_with_callbr_multi_operands(i32 %a) {
1924; RV32I-LABEL: constraint_A_with_callbr_multi_operands:
1925; RV32I:       # %bb.0: # %entry
1926; RV32I-NEXT:    lui a1, %hi(eg)
1927; RV32I-NEXT:    addi a1, a1, %lo(eg)
1928; RV32I-NEXT:    #APP
1929; RV32I-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB42_2
1930; RV32I-NEXT:    #NO_APP
1931; RV32I-NEXT:  # %bb.1: # %normal
1932; RV32I-NEXT:    li a0, 0
1933; RV32I-NEXT:    ret
1934; RV32I-NEXT:  .LBB42_2: # Block address taken
1935; RV32I-NEXT:    # %fail
1936; RV32I-NEXT:    # Label of block must be emitted
1937; RV32I-NEXT:    li a0, 1
1938; RV32I-NEXT:    ret
1939;
1940; RV64I-LABEL: constraint_A_with_callbr_multi_operands:
1941; RV64I:       # %bb.0: # %entry
1942; RV64I-NEXT:    lui a1, %hi(eg)
1943; RV64I-NEXT:    addi a1, a1, %lo(eg)
1944; RV64I-NEXT:    #APP
1945; RV64I-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB42_2
1946; RV64I-NEXT:    #NO_APP
1947; RV64I-NEXT:  # %bb.1: # %normal
1948; RV64I-NEXT:    li a0, 0
1949; RV64I-NEXT:    ret
1950; RV64I-NEXT:  .LBB42_2: # Block address taken
1951; RV64I-NEXT:    # %fail
1952; RV64I-NEXT:    # Label of block must be emitted
1953; RV64I-NEXT:    li a0, 1
1954; RV64I-NEXT:    ret
1955;
1956; RV32I-MEDIUM-LABEL: constraint_A_with_callbr_multi_operands:
1957; RV32I-MEDIUM:       # %bb.0: # %entry
1958; RV32I-MEDIUM-NEXT:  .Lpcrel_hi34:
1959; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1960; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi34)
1961; RV32I-MEDIUM-NEXT:    #APP
1962; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB42_2
1963; RV32I-MEDIUM-NEXT:    #NO_APP
1964; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal
1965; RV32I-MEDIUM-NEXT:    li a0, 0
1966; RV32I-MEDIUM-NEXT:    ret
1967; RV32I-MEDIUM-NEXT:  .LBB42_2: # Block address taken
1968; RV32I-MEDIUM-NEXT:    # %fail
1969; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
1970; RV32I-MEDIUM-NEXT:    li a0, 1
1971; RV32I-MEDIUM-NEXT:    ret
1972;
1973; RV64I-MEDIUM-LABEL: constraint_A_with_callbr_multi_operands:
1974; RV64I-MEDIUM:       # %bb.0: # %entry
1975; RV64I-MEDIUM-NEXT:  .Lpcrel_hi34:
1976; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1977; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi34)
1978; RV64I-MEDIUM-NEXT:    #APP
1979; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB42_2
1980; RV64I-MEDIUM-NEXT:    #NO_APP
1981; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal
1982; RV64I-MEDIUM-NEXT:    li a0, 0
1983; RV64I-MEDIUM-NEXT:    ret
1984; RV64I-MEDIUM-NEXT:  .LBB42_2: # Block address taken
1985; RV64I-MEDIUM-NEXT:    # %fail
1986; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
1987; RV64I-MEDIUM-NEXT:    li a0, 1
1988; RV64I-MEDIUM-NEXT:    ret
1989entry:
1990  callbr void asm "sw zero, $0; sw zero, $1; beqz $2, $3", "*A,*A,r,!i"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg, i32 %a) to label %normal [label %fail]
1991
1992normal:
1993  ret i32 0
1994
1995fail:
1996  ret i32 1
1997}
1998
1999define i32 @constraint_A_with_multi_callbr_asm(i32 %a) {
2000; RV32I-LABEL: constraint_A_with_multi_callbr_asm:
2001; RV32I:       # %bb.0: # %entry
2002; RV32I-NEXT:    lui a1, %hi(eg)
2003; RV32I-NEXT:    addi a1, a1, %lo(eg)
2004; RV32I-NEXT:    #APP
2005; RV32I-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2006; RV32I-NEXT:    #NO_APP
2007; RV32I-NEXT:  # %bb.1: # %normal0
2008; RV32I-NEXT:    #APP
2009; RV32I-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2010; RV32I-NEXT:    #NO_APP
2011; RV32I-NEXT:  # %bb.2: # %normal1
2012; RV32I-NEXT:    li a0, 0
2013; RV32I-NEXT:    ret
2014; RV32I-NEXT:  .LBB43_3: # Block address taken
2015; RV32I-NEXT:    # %fail
2016; RV32I-NEXT:    # Label of block must be emitted
2017; RV32I-NEXT:    li a0, 1
2018; RV32I-NEXT:    ret
2019;
2020; RV64I-LABEL: constraint_A_with_multi_callbr_asm:
2021; RV64I:       # %bb.0: # %entry
2022; RV64I-NEXT:    lui a1, %hi(eg)
2023; RV64I-NEXT:    addi a1, a1, %lo(eg)
2024; RV64I-NEXT:    #APP
2025; RV64I-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2026; RV64I-NEXT:    #NO_APP
2027; RV64I-NEXT:  # %bb.1: # %normal0
2028; RV64I-NEXT:    #APP
2029; RV64I-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2030; RV64I-NEXT:    #NO_APP
2031; RV64I-NEXT:  # %bb.2: # %normal1
2032; RV64I-NEXT:    li a0, 0
2033; RV64I-NEXT:    ret
2034; RV64I-NEXT:  .LBB43_3: # Block address taken
2035; RV64I-NEXT:    # %fail
2036; RV64I-NEXT:    # Label of block must be emitted
2037; RV64I-NEXT:    li a0, 1
2038; RV64I-NEXT:    ret
2039;
2040; RV32I-MEDIUM-LABEL: constraint_A_with_multi_callbr_asm:
2041; RV32I-MEDIUM:       # %bb.0: # %entry
2042; RV32I-MEDIUM-NEXT:  .Lpcrel_hi35:
2043; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
2044; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi35)
2045; RV32I-MEDIUM-NEXT:    #APP
2046; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2047; RV32I-MEDIUM-NEXT:    #NO_APP
2048; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal0
2049; RV32I-MEDIUM-NEXT:    #APP
2050; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2051; RV32I-MEDIUM-NEXT:    #NO_APP
2052; RV32I-MEDIUM-NEXT:  # %bb.2: # %normal1
2053; RV32I-MEDIUM-NEXT:    li a0, 0
2054; RV32I-MEDIUM-NEXT:    ret
2055; RV32I-MEDIUM-NEXT:  .LBB43_3: # Block address taken
2056; RV32I-MEDIUM-NEXT:    # %fail
2057; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
2058; RV32I-MEDIUM-NEXT:    li a0, 1
2059; RV32I-MEDIUM-NEXT:    ret
2060;
2061; RV64I-MEDIUM-LABEL: constraint_A_with_multi_callbr_asm:
2062; RV64I-MEDIUM:       # %bb.0: # %entry
2063; RV64I-MEDIUM-NEXT:  .Lpcrel_hi35:
2064; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
2065; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi35)
2066; RV64I-MEDIUM-NEXT:    #APP
2067; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2068; RV64I-MEDIUM-NEXT:    #NO_APP
2069; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal0
2070; RV64I-MEDIUM-NEXT:    #APP
2071; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB43_3
2072; RV64I-MEDIUM-NEXT:    #NO_APP
2073; RV64I-MEDIUM-NEXT:  # %bb.2: # %normal1
2074; RV64I-MEDIUM-NEXT:    li a0, 0
2075; RV64I-MEDIUM-NEXT:    ret
2076; RV64I-MEDIUM-NEXT:  .LBB43_3: # Block address taken
2077; RV64I-MEDIUM-NEXT:    # %fail
2078; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
2079; RV64I-MEDIUM-NEXT:    li a0, 1
2080; RV64I-MEDIUM-NEXT:    ret
2081entry:
2082  callbr void asm "sw zero, $0; beqz $1, $2", "=*A,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
2083
2084normal0:
2085  callbr void asm "sw zero, $0; beqz $1, $2", "=*A,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal1 [label %fail]
2086
2087normal1:
2088  ret i32 0
2089
2090fail:
2091  ret i32 1
2092}
2093
2094define void @constraint_A_with_local_1() nounwind {
2095; RV32I-LABEL: constraint_A_with_local_1:
2096; RV32I:       # %bb.0: # %entry
2097; RV32I-NEXT:  .Ltmp6: # Block address taken
2098; RV32I-NEXT:  # %bb.1: # %label
2099; RV32I-NEXT:    lui a0, %hi(.Ltmp6)
2100; RV32I-NEXT:    addi a0, a0, %lo(.Ltmp6)
2101; RV32I-NEXT:    #APP
2102; RV32I-NEXT:    lw zero, 0(a0)
2103; RV32I-NEXT:    #NO_APP
2104; RV32I-NEXT:    ret
2105;
2106; RV64I-LABEL: constraint_A_with_local_1:
2107; RV64I:       # %bb.0: # %entry
2108; RV64I-NEXT:  .Ltmp6: # Block address taken
2109; RV64I-NEXT:  # %bb.1: # %label
2110; RV64I-NEXT:    lui a0, %hi(.Ltmp6)
2111; RV64I-NEXT:    addi a0, a0, %lo(.Ltmp6)
2112; RV64I-NEXT:    #APP
2113; RV64I-NEXT:    lw zero, 0(a0)
2114; RV64I-NEXT:    #NO_APP
2115; RV64I-NEXT:    ret
2116;
2117; RV32I-MEDIUM-LABEL: constraint_A_with_local_1:
2118; RV32I-MEDIUM:       # %bb.0: # %entry
2119; RV32I-MEDIUM-NEXT:  .Ltmp6: # Block address taken
2120; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
2121; RV32I-MEDIUM-NEXT:  .Lpcrel_hi36:
2122; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp6)
2123; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi36)
2124; RV32I-MEDIUM-NEXT:    #APP
2125; RV32I-MEDIUM-NEXT:    lw zero, 0(a0)
2126; RV32I-MEDIUM-NEXT:    #NO_APP
2127; RV32I-MEDIUM-NEXT:    ret
2128;
2129; RV64I-MEDIUM-LABEL: constraint_A_with_local_1:
2130; RV64I-MEDIUM:       # %bb.0: # %entry
2131; RV64I-MEDIUM-NEXT:  .Ltmp6: # Block address taken
2132; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
2133; RV64I-MEDIUM-NEXT:  .Lpcrel_hi36:
2134; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp6)
2135; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi36)
2136; RV64I-MEDIUM-NEXT:    #APP
2137; RV64I-MEDIUM-NEXT:    lw zero, 0(a0)
2138; RV64I-MEDIUM-NEXT:    #NO_APP
2139; RV64I-MEDIUM-NEXT:    ret
2140entry:
2141  br label %label
2142
2143label:
2144  tail call void asm sideeffect "lw zero, $0", "*A"(ptr elementtype(ptr) blockaddress(@constraint_A_with_local_1, %label))
2145  ret void
2146}
2147
2148define void @constraint_A_with_local_2() nounwind {
2149; RV32I-LABEL: constraint_A_with_local_2:
2150; RV32I:       # %bb.0: # %entry
2151; RV32I-NEXT:  .Ltmp7: # Block address taken
2152; RV32I-NEXT:  # %bb.1: # %label
2153; RV32I-NEXT:    lui a0, %hi(.Ltmp7+4)
2154; RV32I-NEXT:    addi a0, a0, %lo(.Ltmp7+4)
2155; RV32I-NEXT:    #APP
2156; RV32I-NEXT:    lw zero, 0(a0)
2157; RV32I-NEXT:    #NO_APP
2158; RV32I-NEXT:    ret
2159;
2160; RV64I-LABEL: constraint_A_with_local_2:
2161; RV64I:       # %bb.0: # %entry
2162; RV64I-NEXT:  .Ltmp7: # Block address taken
2163; RV64I-NEXT:  # %bb.1: # %label
2164; RV64I-NEXT:    lui a0, %hi(.Ltmp7+4)
2165; RV64I-NEXT:    addi a0, a0, %lo(.Ltmp7+4)
2166; RV64I-NEXT:    #APP
2167; RV64I-NEXT:    lw zero, 0(a0)
2168; RV64I-NEXT:    #NO_APP
2169; RV64I-NEXT:    ret
2170;
2171; RV32I-MEDIUM-LABEL: constraint_A_with_local_2:
2172; RV32I-MEDIUM:       # %bb.0: # %entry
2173; RV32I-MEDIUM-NEXT:  .Ltmp7: # Block address taken
2174; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
2175; RV32I-MEDIUM-NEXT:  .Lpcrel_hi37:
2176; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp7+4)
2177; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi37)
2178; RV32I-MEDIUM-NEXT:    #APP
2179; RV32I-MEDIUM-NEXT:    lw zero, 0(a0)
2180; RV32I-MEDIUM-NEXT:    #NO_APP
2181; RV32I-MEDIUM-NEXT:    ret
2182;
2183; RV64I-MEDIUM-LABEL: constraint_A_with_local_2:
2184; RV64I-MEDIUM:       # %bb.0: # %entry
2185; RV64I-MEDIUM-NEXT:  .Ltmp7: # Block address taken
2186; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
2187; RV64I-MEDIUM-NEXT:  .Lpcrel_hi37:
2188; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp7+4)
2189; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi37)
2190; RV64I-MEDIUM-NEXT:    #APP
2191; RV64I-MEDIUM-NEXT:    lw zero, 0(a0)
2192; RV64I-MEDIUM-NEXT:    #NO_APP
2193; RV64I-MEDIUM-NEXT:    ret
2194entry:
2195  br label %label
2196
2197label:
2198  call void asm "lw zero, $0", "*A"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_A_with_local_2, %label), i32 4))
2199  ret void
2200}
2201
2202define void @constraint_A_with_local_3() nounwind {
2203; RV32I-LABEL: constraint_A_with_local_3:
2204; RV32I:       # %bb.0: # %entry
2205; RV32I-NEXT:  .Ltmp8: # Block address taken
2206; RV32I-NEXT:  # %bb.1: # %label
2207; RV32I-NEXT:    lui a0, %hi(.Ltmp8+2000)
2208; RV32I-NEXT:    addi a0, a0, %lo(.Ltmp8+2000)
2209; RV32I-NEXT:    #APP
2210; RV32I-NEXT:    lw zero, 0(a0)
2211; RV32I-NEXT:    #NO_APP
2212; RV32I-NEXT:    ret
2213;
2214; RV64I-LABEL: constraint_A_with_local_3:
2215; RV64I:       # %bb.0: # %entry
2216; RV64I-NEXT:  .Ltmp8: # Block address taken
2217; RV64I-NEXT:  # %bb.1: # %label
2218; RV64I-NEXT:    lui a0, %hi(.Ltmp8+2000)
2219; RV64I-NEXT:    addi a0, a0, %lo(.Ltmp8+2000)
2220; RV64I-NEXT:    #APP
2221; RV64I-NEXT:    lw zero, 0(a0)
2222; RV64I-NEXT:    #NO_APP
2223; RV64I-NEXT:    ret
2224;
2225; RV32I-MEDIUM-LABEL: constraint_A_with_local_3:
2226; RV32I-MEDIUM:       # %bb.0: # %entry
2227; RV32I-MEDIUM-NEXT:  .Ltmp8: # Block address taken
2228; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
2229; RV32I-MEDIUM-NEXT:  .Lpcrel_hi38:
2230; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp8+2000)
2231; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi38)
2232; RV32I-MEDIUM-NEXT:    #APP
2233; RV32I-MEDIUM-NEXT:    lw zero, 0(a0)
2234; RV32I-MEDIUM-NEXT:    #NO_APP
2235; RV32I-MEDIUM-NEXT:    ret
2236;
2237; RV64I-MEDIUM-LABEL: constraint_A_with_local_3:
2238; RV64I-MEDIUM:       # %bb.0: # %entry
2239; RV64I-MEDIUM-NEXT:  .Ltmp8: # Block address taken
2240; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
2241; RV64I-MEDIUM-NEXT:  .Lpcrel_hi38:
2242; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp8+2000)
2243; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi38)
2244; RV64I-MEDIUM-NEXT:    #APP
2245; RV64I-MEDIUM-NEXT:    lw zero, 0(a0)
2246; RV64I-MEDIUM-NEXT:    #NO_APP
2247; RV64I-MEDIUM-NEXT:    ret
2248entry:
2249  br label %label
2250
2251label:
2252  call void asm "lw zero, $0", "*A"(ptr elementtype(i32) getelementptr (i8, ptr blockaddress(@constraint_A_with_local_3, %label), i32 2000))
2253  ret void
2254}
2255