xref: /llvm-project/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll (revision 0d73259cf24bf840a980124a90fc80eefa7d70d8)
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:    addi a0, a0, %pcrel_lo(.Lpcrel_hi0)
129; RV32I-MEDIUM-NEXT:    #APP
130; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
131; RV32I-MEDIUM-NEXT:    #NO_APP
132; RV32I-MEDIUM-NEXT:    ret
133;
134; RV64I-MEDIUM-LABEL: constraint_m_with_global_1:
135; RV64I-MEDIUM:       # %bb.0:
136; RV64I-MEDIUM-NEXT:  .Lpcrel_hi0:
137; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
138; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi0)
139; RV64I-MEDIUM-NEXT:    #APP
140; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
141; RV64I-MEDIUM-NEXT:    #NO_APP
142; RV64I-MEDIUM-NEXT:    ret
143  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
144  ret void
145}
146
147define void @constraint_m_with_global_2() nounwind {
148; RV32I-LABEL: constraint_m_with_global_2:
149; RV32I:       # %bb.0:
150; RV32I-NEXT:    lui a0, %hi(eg)
151; RV32I-NEXT:    addi a0, a0, %lo(eg)
152; RV32I-NEXT:    #APP
153; RV32I-NEXT:    sw zero, 4(a0)
154; RV32I-NEXT:    #NO_APP
155; RV32I-NEXT:    ret
156;
157; RV64I-LABEL: constraint_m_with_global_2:
158; RV64I:       # %bb.0:
159; RV64I-NEXT:    lui a0, %hi(eg)
160; RV64I-NEXT:    addi a0, a0, %lo(eg)
161; RV64I-NEXT:    #APP
162; RV64I-NEXT:    sw zero, 4(a0)
163; RV64I-NEXT:    #NO_APP
164; RV64I-NEXT:    ret
165;
166; RV32I-MEDIUM-LABEL: constraint_m_with_global_2:
167; RV32I-MEDIUM:       # %bb.0:
168; RV32I-MEDIUM-NEXT:  .Lpcrel_hi1:
169; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
170; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi1)
171; RV32I-MEDIUM-NEXT:    #APP
172; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
173; RV32I-MEDIUM-NEXT:    #NO_APP
174; RV32I-MEDIUM-NEXT:    ret
175;
176; RV64I-MEDIUM-LABEL: constraint_m_with_global_2:
177; RV64I-MEDIUM:       # %bb.0:
178; RV64I-MEDIUM-NEXT:  .Lpcrel_hi1:
179; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
180; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi1)
181; RV64I-MEDIUM-NEXT:    #APP
182; RV64I-MEDIUM-NEXT:    sw zero, 4(a0)
183; RV64I-MEDIUM-NEXT:    #NO_APP
184; RV64I-MEDIUM-NEXT:    ret
185  call void asm "sw zero, $0", "=*m"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 1))
186  ret void
187}
188
189define void @constraint_m_with_global_3() nounwind {
190; RV32I-LABEL: constraint_m_with_global_3:
191; RV32I:       # %bb.0:
192; RV32I-NEXT:    lui a0, %hi(eg+8000)
193; RV32I-NEXT:    addi a0, a0, %lo(eg+8000)
194; RV32I-NEXT:    #APP
195; RV32I-NEXT:    sw zero, 0(a0)
196; RV32I-NEXT:    #NO_APP
197; RV32I-NEXT:    ret
198;
199; RV64I-LABEL: constraint_m_with_global_3:
200; RV64I:       # %bb.0:
201; RV64I-NEXT:    lui a0, %hi(eg+8000)
202; RV64I-NEXT:    addi a0, a0, %lo(eg+8000)
203; RV64I-NEXT:    #APP
204; RV64I-NEXT:    sw zero, 0(a0)
205; RV64I-NEXT:    #NO_APP
206; RV64I-NEXT:    ret
207;
208; RV32I-MEDIUM-LABEL: constraint_m_with_global_3:
209; RV32I-MEDIUM:       # %bb.0:
210; RV32I-MEDIUM-NEXT:  .Lpcrel_hi2:
211; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
212; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi2)
213; RV32I-MEDIUM-NEXT:    #APP
214; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
215; RV32I-MEDIUM-NEXT:    #NO_APP
216; RV32I-MEDIUM-NEXT:    ret
217;
218; RV64I-MEDIUM-LABEL: constraint_m_with_global_3:
219; RV64I-MEDIUM:       # %bb.0:
220; RV64I-MEDIUM-NEXT:  .Lpcrel_hi2:
221; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
222; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi2)
223; RV64I-MEDIUM-NEXT:    #APP
224; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
225; RV64I-MEDIUM-NEXT:    #NO_APP
226; RV64I-MEDIUM-NEXT:    ret
227  call void asm "sw zero, $0", "=*m"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 2000))
228  ret void
229}
230
231define void @constraint_m_with_extern_weak_global_1() nounwind {
232; RV32I-LABEL: constraint_m_with_extern_weak_global_1:
233; RV32I:       # %bb.0:
234; RV32I-NEXT:    lui a0, %hi(ewg)
235; RV32I-NEXT:    #APP
236; RV32I-NEXT:    sw zero, %lo(ewg)(a0)
237; RV32I-NEXT:    #NO_APP
238; RV32I-NEXT:    ret
239;
240; RV64I-LABEL: constraint_m_with_extern_weak_global_1:
241; RV64I:       # %bb.0:
242; RV64I-NEXT:    lui a0, %hi(ewg)
243; RV64I-NEXT:    #APP
244; RV64I-NEXT:    sw zero, %lo(ewg)(a0)
245; RV64I-NEXT:    #NO_APP
246; RV64I-NEXT:    ret
247;
248; RV32I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_1:
249; RV32I-MEDIUM:       # %bb.0:
250; RV32I-MEDIUM-NEXT:  .Lpcrel_hi3:
251; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
252; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi3)(a0)
253; RV32I-MEDIUM-NEXT:    #APP
254; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
255; RV32I-MEDIUM-NEXT:    #NO_APP
256; RV32I-MEDIUM-NEXT:    ret
257;
258; RV64I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_1:
259; RV64I-MEDIUM:       # %bb.0:
260; RV64I-MEDIUM-NEXT:  .Lpcrel_hi3:
261; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
262; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi3)(a0)
263; RV64I-MEDIUM-NEXT:    #APP
264; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
265; RV64I-MEDIUM-NEXT:    #NO_APP
266; RV64I-MEDIUM-NEXT:    ret
267  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @ewg)
268  ret void
269}
270
271define void @constraint_m_with_extern_weak_global_2() nounwind {
272; RV32I-LABEL: constraint_m_with_extern_weak_global_2:
273; RV32I:       # %bb.0:
274; RV32I-NEXT:    lui a0, %hi(ewg)
275; RV32I-NEXT:    addi a0, a0, %lo(ewg)
276; RV32I-NEXT:    #APP
277; RV32I-NEXT:    sw zero, 4(a0)
278; RV32I-NEXT:    #NO_APP
279; RV32I-NEXT:    ret
280;
281; RV64I-LABEL: constraint_m_with_extern_weak_global_2:
282; RV64I:       # %bb.0:
283; RV64I-NEXT:    lui a0, %hi(ewg)
284; RV64I-NEXT:    addi a0, a0, %lo(ewg)
285; RV64I-NEXT:    #APP
286; RV64I-NEXT:    sw zero, 4(a0)
287; RV64I-NEXT:    #NO_APP
288; RV64I-NEXT:    ret
289;
290; RV32I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_2:
291; RV32I-MEDIUM:       # %bb.0:
292; RV32I-MEDIUM-NEXT:  .Lpcrel_hi4:
293; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
294; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi4)(a0)
295; RV32I-MEDIUM-NEXT:    #APP
296; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
297; RV32I-MEDIUM-NEXT:    #NO_APP
298; RV32I-MEDIUM-NEXT:    ret
299;
300; RV64I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_2:
301; RV64I-MEDIUM:       # %bb.0:
302; RV64I-MEDIUM-NEXT:  .Lpcrel_hi4:
303; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
304; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi4)(a0)
305; RV64I-MEDIUM-NEXT:    #APP
306; RV64I-MEDIUM-NEXT:    sw zero, 4(a0)
307; RV64I-MEDIUM-NEXT:    #NO_APP
308; RV64I-MEDIUM-NEXT:    ret
309  call void asm "sw zero, $0", "=*m"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @ewg, i32 0, i32 1))
310  ret void
311}
312
313define void @constraint_m_with_extern_weak_global_3() nounwind {
314; RV32I-LABEL: constraint_m_with_extern_weak_global_3:
315; RV32I:       # %bb.0:
316; RV32I-NEXT:    lui a0, %hi(ewg+8000)
317; RV32I-NEXT:    addi a0, a0, %lo(ewg+8000)
318; RV32I-NEXT:    #APP
319; RV32I-NEXT:    sw zero, 0(a0)
320; RV32I-NEXT:    #NO_APP
321; RV32I-NEXT:    ret
322;
323; RV64I-LABEL: constraint_m_with_extern_weak_global_3:
324; RV64I:       # %bb.0:
325; RV64I-NEXT:    lui a0, %hi(ewg+8000)
326; RV64I-NEXT:    addi a0, a0, %lo(ewg+8000)
327; RV64I-NEXT:    #APP
328; RV64I-NEXT:    sw zero, 0(a0)
329; RV64I-NEXT:    #NO_APP
330; RV64I-NEXT:    ret
331;
332; RV32I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_3:
333; RV32I-MEDIUM:       # %bb.0:
334; RV32I-MEDIUM-NEXT:  .Lpcrel_hi5:
335; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
336; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi5)(a0)
337; RV32I-MEDIUM-NEXT:    lui a1, 2
338; RV32I-MEDIUM-NEXT:    addi a1, a1, -192
339; RV32I-MEDIUM-NEXT:    add a0, a0, a1
340; RV32I-MEDIUM-NEXT:    #APP
341; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
342; RV32I-MEDIUM-NEXT:    #NO_APP
343; RV32I-MEDIUM-NEXT:    ret
344;
345; RV64I-MEDIUM-LABEL: constraint_m_with_extern_weak_global_3:
346; RV64I-MEDIUM:       # %bb.0:
347; RV64I-MEDIUM-NEXT:  .Lpcrel_hi5:
348; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
349; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi5)(a0)
350; RV64I-MEDIUM-NEXT:    lui a1, 2
351; RV64I-MEDIUM-NEXT:    addiw a1, a1, -192
352; RV64I-MEDIUM-NEXT:    add a0, a0, a1
353; RV64I-MEDIUM-NEXT:    #APP
354; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
355; RV64I-MEDIUM-NEXT:    #NO_APP
356; RV64I-MEDIUM-NEXT:    ret
357  call void asm "sw zero, $0", "=*m"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @ewg, i32 0, i32 2000))
358  ret void
359}
360
361define void @constraint_m_with_multi_operands() nounwind {
362; RV32I-LABEL: constraint_m_with_multi_operands:
363; RV32I:       # %bb.0:
364; RV32I-NEXT:    lui a0, %hi(eg)
365; RV32I-NEXT:    #APP
366; RV32I-NEXT:    sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
367; RV32I-NEXT:    #NO_APP
368; RV32I-NEXT:    ret
369;
370; RV64I-LABEL: constraint_m_with_multi_operands:
371; RV64I:       # %bb.0:
372; RV64I-NEXT:    lui a0, %hi(eg)
373; RV64I-NEXT:    #APP
374; RV64I-NEXT:    sw zero, %lo(eg)(a0); sw zero, %lo(eg)(a0)
375; RV64I-NEXT:    #NO_APP
376; RV64I-NEXT:    ret
377;
378; RV32I-MEDIUM-LABEL: constraint_m_with_multi_operands:
379; RV32I-MEDIUM:       # %bb.0:
380; RV32I-MEDIUM-NEXT:  .Lpcrel_hi6:
381; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
382; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi6)
383; RV32I-MEDIUM-NEXT:    #APP
384; RV32I-MEDIUM-NEXT:    sw zero, 0(a0); sw zero, 0(a0)
385; RV32I-MEDIUM-NEXT:    #NO_APP
386; RV32I-MEDIUM-NEXT:    ret
387;
388; RV64I-MEDIUM-LABEL: constraint_m_with_multi_operands:
389; RV64I-MEDIUM:       # %bb.0:
390; RV64I-MEDIUM-NEXT:  .Lpcrel_hi6:
391; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
392; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi6)
393; RV64I-MEDIUM-NEXT:    #APP
394; RV64I-MEDIUM-NEXT:    sw zero, 0(a0); sw zero, 0(a0)
395; RV64I-MEDIUM-NEXT:    #NO_APP
396; RV64I-MEDIUM-NEXT:    ret
397  call void asm "sw zero, $0; sw zero, $1", "=*m,=*m"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
398  ret void
399}
400
401define void @constraint_m_with_multi_asm() nounwind {
402; RV32I-LABEL: constraint_m_with_multi_asm:
403; RV32I:       # %bb.0:
404; RV32I-NEXT:    lui a0, %hi(eg)
405; RV32I-NEXT:    #APP
406; RV32I-NEXT:    sw zero, %lo(eg)(a0)
407; RV32I-NEXT:    #NO_APP
408; RV32I-NEXT:    #APP
409; RV32I-NEXT:    sw zero, %lo(eg)(a0)
410; RV32I-NEXT:    #NO_APP
411; RV32I-NEXT:    ret
412;
413; RV64I-LABEL: constraint_m_with_multi_asm:
414; RV64I:       # %bb.0:
415; RV64I-NEXT:    lui a0, %hi(eg)
416; RV64I-NEXT:    #APP
417; RV64I-NEXT:    sw zero, %lo(eg)(a0)
418; RV64I-NEXT:    #NO_APP
419; RV64I-NEXT:    #APP
420; RV64I-NEXT:    sw zero, %lo(eg)(a0)
421; RV64I-NEXT:    #NO_APP
422; RV64I-NEXT:    ret
423;
424; RV32I-MEDIUM-LABEL: constraint_m_with_multi_asm:
425; RV32I-MEDIUM:       # %bb.0:
426; RV32I-MEDIUM-NEXT:  .Lpcrel_hi7:
427; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
428; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi7)
429; RV32I-MEDIUM-NEXT:    #APP
430; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
431; RV32I-MEDIUM-NEXT:    #NO_APP
432; RV32I-MEDIUM-NEXT:    #APP
433; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
434; RV32I-MEDIUM-NEXT:    #NO_APP
435; RV32I-MEDIUM-NEXT:    ret
436;
437; RV64I-MEDIUM-LABEL: constraint_m_with_multi_asm:
438; RV64I-MEDIUM:       # %bb.0:
439; RV64I-MEDIUM-NEXT:  .Lpcrel_hi7:
440; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
441; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi7)
442; RV64I-MEDIUM-NEXT:    #APP
443; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
444; RV64I-MEDIUM-NEXT:    #NO_APP
445; RV64I-MEDIUM-NEXT:    #APP
446; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
447; RV64I-MEDIUM-NEXT:    #NO_APP
448; RV64I-MEDIUM-NEXT:    ret
449  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
450  call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg)
451  ret void
452}
453
454define i32 @constraint_m_with_callbr_multi_operands(i32 %a) {
455; RV32I-LABEL: constraint_m_with_callbr_multi_operands:
456; RV32I:       # %bb.0: # %entry
457; RV32I-NEXT:    lui a1, %hi(eg)
458; RV32I-NEXT:    #APP
459; RV32I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB11_2
460; RV32I-NEXT:    #NO_APP
461; RV32I-NEXT:  # %bb.1: # %normal
462; RV32I-NEXT:    li a0, 0
463; RV32I-NEXT:    ret
464; RV32I-NEXT:  .LBB11_2: # Block address taken
465; RV32I-NEXT:    # %fail
466; RV32I-NEXT:    # Label of block must be emitted
467; RV32I-NEXT:    li a0, 1
468; RV32I-NEXT:    ret
469;
470; RV64I-LABEL: constraint_m_with_callbr_multi_operands:
471; RV64I:       # %bb.0: # %entry
472; RV64I-NEXT:    lui a1, %hi(eg)
473; RV64I-NEXT:    #APP
474; RV64I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB11_2
475; RV64I-NEXT:    #NO_APP
476; RV64I-NEXT:  # %bb.1: # %normal
477; RV64I-NEXT:    li a0, 0
478; RV64I-NEXT:    ret
479; RV64I-NEXT:  .LBB11_2: # Block address taken
480; RV64I-NEXT:    # %fail
481; RV64I-NEXT:    # Label of block must be emitted
482; RV64I-NEXT:    li a0, 1
483; RV64I-NEXT:    ret
484;
485; RV32I-MEDIUM-LABEL: constraint_m_with_callbr_multi_operands:
486; RV32I-MEDIUM:       # %bb.0: # %entry
487; RV32I-MEDIUM-NEXT:  .Lpcrel_hi8:
488; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
489; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi8)
490; RV32I-MEDIUM-NEXT:    #APP
491; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB11_2
492; RV32I-MEDIUM-NEXT:    #NO_APP
493; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal
494; RV32I-MEDIUM-NEXT:    li a0, 0
495; RV32I-MEDIUM-NEXT:    ret
496; RV32I-MEDIUM-NEXT:  .LBB11_2: # Block address taken
497; RV32I-MEDIUM-NEXT:    # %fail
498; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
499; RV32I-MEDIUM-NEXT:    li a0, 1
500; RV32I-MEDIUM-NEXT:    ret
501;
502; RV64I-MEDIUM-LABEL: constraint_m_with_callbr_multi_operands:
503; RV64I-MEDIUM:       # %bb.0: # %entry
504; RV64I-MEDIUM-NEXT:  .Lpcrel_hi8:
505; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
506; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi8)
507; RV64I-MEDIUM-NEXT:    #APP
508; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB11_2
509; RV64I-MEDIUM-NEXT:    #NO_APP
510; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal
511; RV64I-MEDIUM-NEXT:    li a0, 0
512; RV64I-MEDIUM-NEXT:    ret
513; RV64I-MEDIUM-NEXT:  .LBB11_2: # Block address taken
514; RV64I-MEDIUM-NEXT:    # %fail
515; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
516; RV64I-MEDIUM-NEXT:    li a0, 1
517; RV64I-MEDIUM-NEXT:    ret
518entry:
519  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]
520
521normal:
522  ret i32 0
523
524fail:
525  ret i32 1
526}
527
528define i32 @constraint_m_with_multi_callbr_asm(i32 %a) {
529; RV32I-LABEL: constraint_m_with_multi_callbr_asm:
530; RV32I:       # %bb.0: # %entry
531; RV32I-NEXT:    lui a1, %hi(eg)
532; RV32I-NEXT:    #APP
533; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB12_3
534; RV32I-NEXT:    #NO_APP
535; RV32I-NEXT:  # %bb.1: # %normal0
536; RV32I-NEXT:    #APP
537; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB12_3
538; RV32I-NEXT:    #NO_APP
539; RV32I-NEXT:  # %bb.2: # %normal1
540; RV32I-NEXT:    li a0, 0
541; RV32I-NEXT:    ret
542; RV32I-NEXT:  .LBB12_3: # Block address taken
543; RV32I-NEXT:    # %fail
544; RV32I-NEXT:    # Label of block must be emitted
545; RV32I-NEXT:    li a0, 1
546; RV32I-NEXT:    ret
547;
548; RV64I-LABEL: constraint_m_with_multi_callbr_asm:
549; RV64I:       # %bb.0: # %entry
550; RV64I-NEXT:    lui a1, %hi(eg)
551; RV64I-NEXT:    #APP
552; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB12_3
553; RV64I-NEXT:    #NO_APP
554; RV64I-NEXT:  # %bb.1: # %normal0
555; RV64I-NEXT:    #APP
556; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB12_3
557; RV64I-NEXT:    #NO_APP
558; RV64I-NEXT:  # %bb.2: # %normal1
559; RV64I-NEXT:    li a0, 0
560; RV64I-NEXT:    ret
561; RV64I-NEXT:  .LBB12_3: # Block address taken
562; RV64I-NEXT:    # %fail
563; RV64I-NEXT:    # Label of block must be emitted
564; RV64I-NEXT:    li a0, 1
565; RV64I-NEXT:    ret
566;
567; RV32I-MEDIUM-LABEL: constraint_m_with_multi_callbr_asm:
568; RV32I-MEDIUM:       # %bb.0: # %entry
569; RV32I-MEDIUM-NEXT:  .Lpcrel_hi9:
570; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
571; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi9)
572; RV32I-MEDIUM-NEXT:    #APP
573; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB12_3
574; RV32I-MEDIUM-NEXT:    #NO_APP
575; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal0
576; RV32I-MEDIUM-NEXT:    #APP
577; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB12_3
578; RV32I-MEDIUM-NEXT:    #NO_APP
579; RV32I-MEDIUM-NEXT:  # %bb.2: # %normal1
580; RV32I-MEDIUM-NEXT:    li a0, 0
581; RV32I-MEDIUM-NEXT:    ret
582; RV32I-MEDIUM-NEXT:  .LBB12_3: # Block address taken
583; RV32I-MEDIUM-NEXT:    # %fail
584; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
585; RV32I-MEDIUM-NEXT:    li a0, 1
586; RV32I-MEDIUM-NEXT:    ret
587;
588; RV64I-MEDIUM-LABEL: constraint_m_with_multi_callbr_asm:
589; RV64I-MEDIUM:       # %bb.0: # %entry
590; RV64I-MEDIUM-NEXT:  .Lpcrel_hi9:
591; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
592; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi9)
593; RV64I-MEDIUM-NEXT:    #APP
594; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB12_3
595; RV64I-MEDIUM-NEXT:    #NO_APP
596; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal0
597; RV64I-MEDIUM-NEXT:    #APP
598; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB12_3
599; RV64I-MEDIUM-NEXT:    #NO_APP
600; RV64I-MEDIUM-NEXT:  # %bb.2: # %normal1
601; RV64I-MEDIUM-NEXT:    li a0, 0
602; RV64I-MEDIUM-NEXT:    ret
603; RV64I-MEDIUM-NEXT:  .LBB12_3: # Block address taken
604; RV64I-MEDIUM-NEXT:    # %fail
605; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
606; RV64I-MEDIUM-NEXT:    li a0, 1
607; RV64I-MEDIUM-NEXT:    ret
608entry:
609  callbr void asm "sw zero, $0; beqz $1, $2", "=*m,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
610
611normal0:
612  callbr void asm "sw zero, $0; beqz $1, $2", "=*m,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal1 [label %fail]
613
614normal1:
615  ret i32 0
616
617fail:
618  ret i32 1
619}
620
621define void @constraint_o_1(ptr %a) nounwind {
622; RV32I-LABEL: constraint_o_1:
623; RV32I:       # %bb.0:
624; RV32I-NEXT:    #APP
625; RV32I-NEXT:    #NO_APP
626; RV32I-NEXT:    ret
627;
628; RV64I-LABEL: constraint_o_1:
629; RV64I:       # %bb.0:
630; RV64I-NEXT:    #APP
631; RV64I-NEXT:    #NO_APP
632; RV64I-NEXT:    ret
633;
634; RV32I-MEDIUM-LABEL: constraint_o_1:
635; RV32I-MEDIUM:       # %bb.0:
636; RV32I-MEDIUM-NEXT:    #APP
637; RV32I-MEDIUM-NEXT:    #NO_APP
638; RV32I-MEDIUM-NEXT:    ret
639;
640; RV64I-MEDIUM-LABEL: constraint_o_1:
641; RV64I-MEDIUM:       # %bb.0:
642; RV64I-MEDIUM-NEXT:    #APP
643; RV64I-MEDIUM-NEXT:    #NO_APP
644; RV64I-MEDIUM-NEXT:    ret
645  call void asm sideeffect "", "=*o"(ptr elementtype(i32) %a)
646  ret void
647}
648
649define i32 @constraint_o_2(ptr %a) nounwind {
650; RV32I-LABEL: constraint_o_2:
651; RV32I:       # %bb.0:
652; RV32I-NEXT:    #APP
653; RV32I-NEXT:    lw a0, 0(a0)
654; RV32I-NEXT:    #NO_APP
655; RV32I-NEXT:    ret
656;
657; RV64I-LABEL: constraint_o_2:
658; RV64I:       # %bb.0:
659; RV64I-NEXT:    #APP
660; RV64I-NEXT:    lw a0, 0(a0)
661; RV64I-NEXT:    #NO_APP
662; RV64I-NEXT:    ret
663;
664; RV32I-MEDIUM-LABEL: constraint_o_2:
665; RV32I-MEDIUM:       # %bb.0:
666; RV32I-MEDIUM-NEXT:    #APP
667; RV32I-MEDIUM-NEXT:    lw a0, 0(a0)
668; RV32I-MEDIUM-NEXT:    #NO_APP
669; RV32I-MEDIUM-NEXT:    ret
670;
671; RV64I-MEDIUM-LABEL: constraint_o_2:
672; RV64I-MEDIUM:       # %bb.0:
673; RV64I-MEDIUM-NEXT:    #APP
674; RV64I-MEDIUM-NEXT:    lw a0, 0(a0)
675; RV64I-MEDIUM-NEXT:    #NO_APP
676; RV64I-MEDIUM-NEXT:    ret
677  %1 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %a)
678  ret i32 %1
679}
680
681define i32 @constraint_o_with_offset(ptr %a) nounwind {
682; RV32I-LABEL: constraint_o_with_offset:
683; RV32I:       # %bb.0:
684; RV32I-NEXT:    #APP
685; RV32I-NEXT:    lw a0, 4(a0)
686; RV32I-NEXT:    #NO_APP
687; RV32I-NEXT:    ret
688;
689; RV64I-LABEL: constraint_o_with_offset:
690; RV64I:       # %bb.0:
691; RV64I-NEXT:    #APP
692; RV64I-NEXT:    lw a0, 4(a0)
693; RV64I-NEXT:    #NO_APP
694; RV64I-NEXT:    ret
695;
696; RV32I-MEDIUM-LABEL: constraint_o_with_offset:
697; RV32I-MEDIUM:       # %bb.0:
698; RV32I-MEDIUM-NEXT:    #APP
699; RV32I-MEDIUM-NEXT:    lw a0, 4(a0)
700; RV32I-MEDIUM-NEXT:    #NO_APP
701; RV32I-MEDIUM-NEXT:    ret
702;
703; RV64I-MEDIUM-LABEL: constraint_o_with_offset:
704; RV64I-MEDIUM:       # %bb.0:
705; RV64I-MEDIUM-NEXT:    #APP
706; RV64I-MEDIUM-NEXT:    lw a0, 4(a0)
707; RV64I-MEDIUM-NEXT:    #NO_APP
708; RV64I-MEDIUM-NEXT:    ret
709  %1 = getelementptr i32, ptr %a, i32 1
710  %2 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %1)
711  ret i32 %2
712}
713
714define void @constraint_o_with_global_1() nounwind {
715; RV32I-LABEL: constraint_o_with_global_1:
716; RV32I:       # %bb.0:
717; RV32I-NEXT:    lui a0, %hi(eg)
718; RV32I-NEXT:    #APP
719; RV32I-NEXT:    sw zero, %lo(eg)(a0)
720; RV32I-NEXT:    #NO_APP
721; RV32I-NEXT:    ret
722;
723; RV64I-LABEL: constraint_o_with_global_1:
724; RV64I:       # %bb.0:
725; RV64I-NEXT:    lui a0, %hi(eg)
726; RV64I-NEXT:    #APP
727; RV64I-NEXT:    sw zero, %lo(eg)(a0)
728; RV64I-NEXT:    #NO_APP
729; RV64I-NEXT:    ret
730;
731; RV32I-MEDIUM-LABEL: constraint_o_with_global_1:
732; RV32I-MEDIUM:       # %bb.0:
733; RV32I-MEDIUM-NEXT:  .Lpcrel_hi10:
734; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
735; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi10)
736; RV32I-MEDIUM-NEXT:    #APP
737; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
738; RV32I-MEDIUM-NEXT:    #NO_APP
739; RV32I-MEDIUM-NEXT:    ret
740;
741; RV64I-MEDIUM-LABEL: constraint_o_with_global_1:
742; RV64I-MEDIUM:       # %bb.0:
743; RV64I-MEDIUM-NEXT:  .Lpcrel_hi10:
744; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
745; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi10)
746; RV64I-MEDIUM-NEXT:    #APP
747; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
748; RV64I-MEDIUM-NEXT:    #NO_APP
749; RV64I-MEDIUM-NEXT:    ret
750  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
751  ret void
752}
753
754define void @constraint_o_with_global_2() nounwind {
755; RV32I-LABEL: constraint_o_with_global_2:
756; RV32I:       # %bb.0:
757; RV32I-NEXT:    lui a0, %hi(eg)
758; RV32I-NEXT:    addi a0, a0, %lo(eg)
759; RV32I-NEXT:    #APP
760; RV32I-NEXT:    sw zero, 4(a0)
761; RV32I-NEXT:    #NO_APP
762; RV32I-NEXT:    ret
763;
764; RV64I-LABEL: constraint_o_with_global_2:
765; RV64I:       # %bb.0:
766; RV64I-NEXT:    lui a0, %hi(eg)
767; RV64I-NEXT:    addi a0, a0, %lo(eg)
768; RV64I-NEXT:    #APP
769; RV64I-NEXT:    sw zero, 4(a0)
770; RV64I-NEXT:    #NO_APP
771; RV64I-NEXT:    ret
772;
773; RV32I-MEDIUM-LABEL: constraint_o_with_global_2:
774; RV32I-MEDIUM:       # %bb.0:
775; RV32I-MEDIUM-NEXT:  .Lpcrel_hi11:
776; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
777; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi11)
778; RV32I-MEDIUM-NEXT:    #APP
779; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
780; RV32I-MEDIUM-NEXT:    #NO_APP
781; RV32I-MEDIUM-NEXT:    ret
782;
783; RV64I-MEDIUM-LABEL: constraint_o_with_global_2:
784; RV64I-MEDIUM:       # %bb.0:
785; RV64I-MEDIUM-NEXT:  .Lpcrel_hi11:
786; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
787; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi11)
788; RV64I-MEDIUM-NEXT:    #APP
789; RV64I-MEDIUM-NEXT:    sw zero, 4(a0)
790; RV64I-MEDIUM-NEXT:    #NO_APP
791; RV64I-MEDIUM-NEXT:    ret
792  call void asm "sw zero, $0", "=*o"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 1))
793  ret void
794}
795
796define void @constraint_o_with_global_3() nounwind {
797; RV32I-LABEL: constraint_o_with_global_3:
798; RV32I:       # %bb.0:
799; RV32I-NEXT:    lui a0, %hi(eg+8000)
800; RV32I-NEXT:    addi a0, a0, %lo(eg+8000)
801; RV32I-NEXT:    #APP
802; RV32I-NEXT:    sw zero, 0(a0)
803; RV32I-NEXT:    #NO_APP
804; RV32I-NEXT:    ret
805;
806; RV64I-LABEL: constraint_o_with_global_3:
807; RV64I:       # %bb.0:
808; RV64I-NEXT:    lui a0, %hi(eg+8000)
809; RV64I-NEXT:    addi a0, a0, %lo(eg+8000)
810; RV64I-NEXT:    #APP
811; RV64I-NEXT:    sw zero, 0(a0)
812; RV64I-NEXT:    #NO_APP
813; RV64I-NEXT:    ret
814;
815; RV32I-MEDIUM-LABEL: constraint_o_with_global_3:
816; RV32I-MEDIUM:       # %bb.0:
817; RV32I-MEDIUM-NEXT:  .Lpcrel_hi12:
818; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
819; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi12)
820; RV32I-MEDIUM-NEXT:    #APP
821; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
822; RV32I-MEDIUM-NEXT:    #NO_APP
823; RV32I-MEDIUM-NEXT:    ret
824;
825; RV64I-MEDIUM-LABEL: constraint_o_with_global_3:
826; RV64I-MEDIUM:       # %bb.0:
827; RV64I-MEDIUM-NEXT:  .Lpcrel_hi12:
828; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg+8000)
829; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi12)
830; RV64I-MEDIUM-NEXT:    #APP
831; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
832; RV64I-MEDIUM-NEXT:    #NO_APP
833; RV64I-MEDIUM-NEXT:    ret
834  call void asm "sw zero, $0", "=*o"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 2000))
835  ret void
836}
837
838define void @constraint_o_with_extern_weak_global_1() nounwind {
839; RV32I-LABEL: constraint_o_with_extern_weak_global_1:
840; RV32I:       # %bb.0:
841; RV32I-NEXT:    lui a0, %hi(ewg)
842; RV32I-NEXT:    #APP
843; RV32I-NEXT:    sw zero, %lo(ewg)(a0)
844; RV32I-NEXT:    #NO_APP
845; RV32I-NEXT:    ret
846;
847; RV64I-LABEL: constraint_o_with_extern_weak_global_1:
848; RV64I:       # %bb.0:
849; RV64I-NEXT:    lui a0, %hi(ewg)
850; RV64I-NEXT:    #APP
851; RV64I-NEXT:    sw zero, %lo(ewg)(a0)
852; RV64I-NEXT:    #NO_APP
853; RV64I-NEXT:    ret
854;
855; RV32I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_1:
856; RV32I-MEDIUM:       # %bb.0:
857; RV32I-MEDIUM-NEXT:  .Lpcrel_hi13:
858; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
859; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi13)(a0)
860; RV32I-MEDIUM-NEXT:    #APP
861; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
862; RV32I-MEDIUM-NEXT:    #NO_APP
863; RV32I-MEDIUM-NEXT:    ret
864;
865; RV64I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_1:
866; RV64I-MEDIUM:       # %bb.0:
867; RV64I-MEDIUM-NEXT:  .Lpcrel_hi13:
868; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
869; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi13)(a0)
870; RV64I-MEDIUM-NEXT:    #APP
871; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
872; RV64I-MEDIUM-NEXT:    #NO_APP
873; RV64I-MEDIUM-NEXT:    ret
874  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @ewg)
875  ret void
876}
877
878define void @constraint_o_with_extern_weak_global_2() nounwind {
879; RV32I-LABEL: constraint_o_with_extern_weak_global_2:
880; RV32I:       # %bb.0:
881; RV32I-NEXT:    lui a0, %hi(ewg)
882; RV32I-NEXT:    addi a0, a0, %lo(ewg)
883; RV32I-NEXT:    #APP
884; RV32I-NEXT:    sw zero, 4(a0)
885; RV32I-NEXT:    #NO_APP
886; RV32I-NEXT:    ret
887;
888; RV64I-LABEL: constraint_o_with_extern_weak_global_2:
889; RV64I:       # %bb.0:
890; RV64I-NEXT:    lui a0, %hi(ewg)
891; RV64I-NEXT:    addi a0, a0, %lo(ewg)
892; RV64I-NEXT:    #APP
893; RV64I-NEXT:    sw zero, 4(a0)
894; RV64I-NEXT:    #NO_APP
895; RV64I-NEXT:    ret
896;
897; RV32I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_2:
898; RV32I-MEDIUM:       # %bb.0:
899; RV32I-MEDIUM-NEXT:  .Lpcrel_hi14:
900; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
901; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi14)(a0)
902; RV32I-MEDIUM-NEXT:    #APP
903; RV32I-MEDIUM-NEXT:    sw zero, 4(a0)
904; RV32I-MEDIUM-NEXT:    #NO_APP
905; RV32I-MEDIUM-NEXT:    ret
906;
907; RV64I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_2:
908; RV64I-MEDIUM:       # %bb.0:
909; RV64I-MEDIUM-NEXT:  .Lpcrel_hi14:
910; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
911; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi14)(a0)
912; RV64I-MEDIUM-NEXT:    #APP
913; RV64I-MEDIUM-NEXT:    sw zero, 4(a0)
914; RV64I-MEDIUM-NEXT:    #NO_APP
915; RV64I-MEDIUM-NEXT:    ret
916  call void asm "sw zero, $0", "=*o"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @ewg, i32 0, i32 1))
917  ret void
918}
919
920define void @constraint_o_with_extern_weak_global_3() nounwind {
921; RV32I-LABEL: constraint_o_with_extern_weak_global_3:
922; RV32I:       # %bb.0:
923; RV32I-NEXT:    lui a0, %hi(ewg+8000)
924; RV32I-NEXT:    addi a0, a0, %lo(ewg+8000)
925; RV32I-NEXT:    #APP
926; RV32I-NEXT:    sw zero, 0(a0)
927; RV32I-NEXT:    #NO_APP
928; RV32I-NEXT:    ret
929;
930; RV64I-LABEL: constraint_o_with_extern_weak_global_3:
931; RV64I:       # %bb.0:
932; RV64I-NEXT:    lui a0, %hi(ewg+8000)
933; RV64I-NEXT:    addi a0, a0, %lo(ewg+8000)
934; RV64I-NEXT:    #APP
935; RV64I-NEXT:    sw zero, 0(a0)
936; RV64I-NEXT:    #NO_APP
937; RV64I-NEXT:    ret
938;
939; RV32I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_3:
940; RV32I-MEDIUM:       # %bb.0:
941; RV32I-MEDIUM-NEXT:  .Lpcrel_hi15:
942; RV32I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
943; RV32I-MEDIUM-NEXT:    lw a0, %pcrel_lo(.Lpcrel_hi15)(a0)
944; RV32I-MEDIUM-NEXT:    lui a1, 2
945; RV32I-MEDIUM-NEXT:    addi a1, a1, -192
946; RV32I-MEDIUM-NEXT:    add a0, a0, a1
947; RV32I-MEDIUM-NEXT:    #APP
948; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
949; RV32I-MEDIUM-NEXT:    #NO_APP
950; RV32I-MEDIUM-NEXT:    ret
951;
952; RV64I-MEDIUM-LABEL: constraint_o_with_extern_weak_global_3:
953; RV64I-MEDIUM:       # %bb.0:
954; RV64I-MEDIUM-NEXT:  .Lpcrel_hi15:
955; RV64I-MEDIUM-NEXT:    auipc a0, %got_pcrel_hi(ewg)
956; RV64I-MEDIUM-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi15)(a0)
957; RV64I-MEDIUM-NEXT:    lui a1, 2
958; RV64I-MEDIUM-NEXT:    addiw a1, a1, -192
959; RV64I-MEDIUM-NEXT:    add a0, a0, a1
960; RV64I-MEDIUM-NEXT:    #APP
961; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
962; RV64I-MEDIUM-NEXT:    #NO_APP
963; RV64I-MEDIUM-NEXT:    ret
964  call void asm "sw zero, $0", "=*o"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @ewg, i32 0, i32 2000))
965  ret void
966}
967
968define void @constraint_o_with_multi_operands() nounwind {
969; RV32I-LABEL: constraint_o_with_multi_operands:
970; RV32I:       # %bb.0:
971; RV32I-NEXT:    lui a0, %hi(eg)
972; RV32I-NEXT:    #APP
973; RV32I-NEXT:    sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
974; RV32I-NEXT:    #NO_APP
975; RV32I-NEXT:    ret
976;
977; RV64I-LABEL: constraint_o_with_multi_operands:
978; RV64I:       # %bb.0:
979; RV64I-NEXT:    lui a0, %hi(eg)
980; RV64I-NEXT:    #APP
981; RV64I-NEXT:    sw zero, %lo(eg)(a0) \n sw zero, %lo(eg)(a0)
982; RV64I-NEXT:    #NO_APP
983; RV64I-NEXT:    ret
984;
985; RV32I-MEDIUM-LABEL: constraint_o_with_multi_operands:
986; RV32I-MEDIUM:       # %bb.0:
987; RV32I-MEDIUM-NEXT:  .Lpcrel_hi16:
988; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
989; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi16)
990; RV32I-MEDIUM-NEXT:    #APP
991; RV32I-MEDIUM-NEXT:    sw zero, 0(a0) \n sw zero, 0(a0)
992; RV32I-MEDIUM-NEXT:    #NO_APP
993; RV32I-MEDIUM-NEXT:    ret
994;
995; RV64I-MEDIUM-LABEL: constraint_o_with_multi_operands:
996; RV64I-MEDIUM:       # %bb.0:
997; RV64I-MEDIUM-NEXT:  .Lpcrel_hi16:
998; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
999; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi16)
1000; RV64I-MEDIUM-NEXT:    #APP
1001; RV64I-MEDIUM-NEXT:    sw zero, 0(a0) \n sw zero, 0(a0)
1002; RV64I-MEDIUM-NEXT:    #NO_APP
1003; RV64I-MEDIUM-NEXT:    ret
1004  call void asm "sw zero, $0 \n sw zero, $1", "=*o,=*o"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg)
1005  ret void
1006}
1007
1008define void @constraint_o_with_multi_asm() nounwind {
1009; RV32I-LABEL: constraint_o_with_multi_asm:
1010; RV32I:       # %bb.0:
1011; RV32I-NEXT:    lui a0, %hi(eg)
1012; RV32I-NEXT:    #APP
1013; RV32I-NEXT:    sw zero, %lo(eg)(a0)
1014; RV32I-NEXT:    #NO_APP
1015; RV32I-NEXT:    #APP
1016; RV32I-NEXT:    sw zero, %lo(eg)(a0)
1017; RV32I-NEXT:    #NO_APP
1018; RV32I-NEXT:    ret
1019;
1020; RV64I-LABEL: constraint_o_with_multi_asm:
1021; RV64I:       # %bb.0:
1022; RV64I-NEXT:    lui a0, %hi(eg)
1023; RV64I-NEXT:    #APP
1024; RV64I-NEXT:    sw zero, %lo(eg)(a0)
1025; RV64I-NEXT:    #NO_APP
1026; RV64I-NEXT:    #APP
1027; RV64I-NEXT:    sw zero, %lo(eg)(a0)
1028; RV64I-NEXT:    #NO_APP
1029; RV64I-NEXT:    ret
1030;
1031; RV32I-MEDIUM-LABEL: constraint_o_with_multi_asm:
1032; RV32I-MEDIUM:       # %bb.0:
1033; RV32I-MEDIUM-NEXT:  .Lpcrel_hi17:
1034; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1035; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi17)
1036; RV32I-MEDIUM-NEXT:    #APP
1037; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1038; RV32I-MEDIUM-NEXT:    #NO_APP
1039; RV32I-MEDIUM-NEXT:    #APP
1040; RV32I-MEDIUM-NEXT:    sw zero, 0(a0)
1041; RV32I-MEDIUM-NEXT:    #NO_APP
1042; RV32I-MEDIUM-NEXT:    ret
1043;
1044; RV64I-MEDIUM-LABEL: constraint_o_with_multi_asm:
1045; RV64I-MEDIUM:       # %bb.0:
1046; RV64I-MEDIUM-NEXT:  .Lpcrel_hi17:
1047; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
1048; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi17)
1049; RV64I-MEDIUM-NEXT:    #APP
1050; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1051; RV64I-MEDIUM-NEXT:    #NO_APP
1052; RV64I-MEDIUM-NEXT:    #APP
1053; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
1054; RV64I-MEDIUM-NEXT:    #NO_APP
1055; RV64I-MEDIUM-NEXT:    ret
1056  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
1057  call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg)
1058  ret void
1059}
1060
1061define i32 @constraint_o_with_callbr_multi_operands(i32 %a) {
1062; RV32I-LABEL: constraint_o_with_callbr_multi_operands:
1063; RV32I:       # %bb.0: # %entry
1064; RV32I-NEXT:    lui a1, %hi(eg)
1065; RV32I-NEXT:    #APP
1066; RV32I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB24_2
1067; RV32I-NEXT:    #NO_APP
1068; RV32I-NEXT:  # %bb.1: # %normal
1069; RV32I-NEXT:    li a0, 0
1070; RV32I-NEXT:    ret
1071; RV32I-NEXT:  .LBB24_2: # Block address taken
1072; RV32I-NEXT:    # %fail
1073; RV32I-NEXT:    # Label of block must be emitted
1074; RV32I-NEXT:    li a0, 1
1075; RV32I-NEXT:    ret
1076;
1077; RV64I-LABEL: constraint_o_with_callbr_multi_operands:
1078; RV64I:       # %bb.0: # %entry
1079; RV64I-NEXT:    lui a1, %hi(eg)
1080; RV64I-NEXT:    #APP
1081; RV64I-NEXT:    sw zero, %lo(eg)(a1); sw zero, %lo(eg)(a1); beqz a0, .LBB24_2
1082; RV64I-NEXT:    #NO_APP
1083; RV64I-NEXT:  # %bb.1: # %normal
1084; RV64I-NEXT:    li a0, 0
1085; RV64I-NEXT:    ret
1086; RV64I-NEXT:  .LBB24_2: # Block address taken
1087; RV64I-NEXT:    # %fail
1088; RV64I-NEXT:    # Label of block must be emitted
1089; RV64I-NEXT:    li a0, 1
1090; RV64I-NEXT:    ret
1091;
1092; RV32I-MEDIUM-LABEL: constraint_o_with_callbr_multi_operands:
1093; RV32I-MEDIUM:       # %bb.0: # %entry
1094; RV32I-MEDIUM-NEXT:  .Lpcrel_hi18:
1095; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1096; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi18)
1097; RV32I-MEDIUM-NEXT:    #APP
1098; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB24_2
1099; RV32I-MEDIUM-NEXT:    #NO_APP
1100; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal
1101; RV32I-MEDIUM-NEXT:    li a0, 0
1102; RV32I-MEDIUM-NEXT:    ret
1103; RV32I-MEDIUM-NEXT:  .LBB24_2: # Block address taken
1104; RV32I-MEDIUM-NEXT:    # %fail
1105; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
1106; RV32I-MEDIUM-NEXT:    li a0, 1
1107; RV32I-MEDIUM-NEXT:    ret
1108;
1109; RV64I-MEDIUM-LABEL: constraint_o_with_callbr_multi_operands:
1110; RV64I-MEDIUM:       # %bb.0: # %entry
1111; RV64I-MEDIUM-NEXT:  .Lpcrel_hi18:
1112; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1113; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi18)
1114; RV64I-MEDIUM-NEXT:    #APP
1115; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB24_2
1116; RV64I-MEDIUM-NEXT:    #NO_APP
1117; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal
1118; RV64I-MEDIUM-NEXT:    li a0, 0
1119; RV64I-MEDIUM-NEXT:    ret
1120; RV64I-MEDIUM-NEXT:  .LBB24_2: # Block address taken
1121; RV64I-MEDIUM-NEXT:    # %fail
1122; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
1123; RV64I-MEDIUM-NEXT:    li a0, 1
1124; RV64I-MEDIUM-NEXT:    ret
1125entry:
1126  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]
1127
1128normal:
1129  ret i32 0
1130
1131fail:
1132  ret i32 1
1133}
1134
1135define i32 @constraint_o_with_multi_callbr_asm(i32 %a) {
1136; RV32I-LABEL: constraint_o_with_multi_callbr_asm:
1137; RV32I:       # %bb.0: # %entry
1138; RV32I-NEXT:    lui a1, %hi(eg)
1139; RV32I-NEXT:    #APP
1140; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB25_3
1141; RV32I-NEXT:    #NO_APP
1142; RV32I-NEXT:  # %bb.1: # %normal0
1143; RV32I-NEXT:    #APP
1144; RV32I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB25_3
1145; RV32I-NEXT:    #NO_APP
1146; RV32I-NEXT:  # %bb.2: # %normal1
1147; RV32I-NEXT:    li a0, 0
1148; RV32I-NEXT:    ret
1149; RV32I-NEXT:  .LBB25_3: # Block address taken
1150; RV32I-NEXT:    # %fail
1151; RV32I-NEXT:    # Label of block must be emitted
1152; RV32I-NEXT:    li a0, 1
1153; RV32I-NEXT:    ret
1154;
1155; RV64I-LABEL: constraint_o_with_multi_callbr_asm:
1156; RV64I:       # %bb.0: # %entry
1157; RV64I-NEXT:    lui a1, %hi(eg)
1158; RV64I-NEXT:    #APP
1159; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB25_3
1160; RV64I-NEXT:    #NO_APP
1161; RV64I-NEXT:  # %bb.1: # %normal0
1162; RV64I-NEXT:    #APP
1163; RV64I-NEXT:    sw zero, %lo(eg)(a1); beqz a0, .LBB25_3
1164; RV64I-NEXT:    #NO_APP
1165; RV64I-NEXT:  # %bb.2: # %normal1
1166; RV64I-NEXT:    li a0, 0
1167; RV64I-NEXT:    ret
1168; RV64I-NEXT:  .LBB25_3: # Block address taken
1169; RV64I-NEXT:    # %fail
1170; RV64I-NEXT:    # Label of block must be emitted
1171; RV64I-NEXT:    li a0, 1
1172; RV64I-NEXT:    ret
1173;
1174; RV32I-MEDIUM-LABEL: constraint_o_with_multi_callbr_asm:
1175; RV32I-MEDIUM:       # %bb.0: # %entry
1176; RV32I-MEDIUM-NEXT:  .Lpcrel_hi19:
1177; RV32I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1178; RV32I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi19)
1179; RV32I-MEDIUM-NEXT:    #APP
1180; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB25_3
1181; RV32I-MEDIUM-NEXT:    #NO_APP
1182; RV32I-MEDIUM-NEXT:  # %bb.1: # %normal0
1183; RV32I-MEDIUM-NEXT:    #APP
1184; RV32I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB25_3
1185; RV32I-MEDIUM-NEXT:    #NO_APP
1186; RV32I-MEDIUM-NEXT:  # %bb.2: # %normal1
1187; RV32I-MEDIUM-NEXT:    li a0, 0
1188; RV32I-MEDIUM-NEXT:    ret
1189; RV32I-MEDIUM-NEXT:  .LBB25_3: # Block address taken
1190; RV32I-MEDIUM-NEXT:    # %fail
1191; RV32I-MEDIUM-NEXT:    # Label of block must be emitted
1192; RV32I-MEDIUM-NEXT:    li a0, 1
1193; RV32I-MEDIUM-NEXT:    ret
1194;
1195; RV64I-MEDIUM-LABEL: constraint_o_with_multi_callbr_asm:
1196; RV64I-MEDIUM:       # %bb.0: # %entry
1197; RV64I-MEDIUM-NEXT:  .Lpcrel_hi19:
1198; RV64I-MEDIUM-NEXT:    auipc a1, %pcrel_hi(eg)
1199; RV64I-MEDIUM-NEXT:    addi a1, a1, %pcrel_lo(.Lpcrel_hi19)
1200; RV64I-MEDIUM-NEXT:    #APP
1201; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB25_3
1202; RV64I-MEDIUM-NEXT:    #NO_APP
1203; RV64I-MEDIUM-NEXT:  # %bb.1: # %normal0
1204; RV64I-MEDIUM-NEXT:    #APP
1205; RV64I-MEDIUM-NEXT:    sw zero, 0(a1); beqz a0, .LBB25_3
1206; RV64I-MEDIUM-NEXT:    #NO_APP
1207; RV64I-MEDIUM-NEXT:  # %bb.2: # %normal1
1208; RV64I-MEDIUM-NEXT:    li a0, 0
1209; RV64I-MEDIUM-NEXT:    ret
1210; RV64I-MEDIUM-NEXT:  .LBB25_3: # Block address taken
1211; RV64I-MEDIUM-NEXT:    # %fail
1212; RV64I-MEDIUM-NEXT:    # Label of block must be emitted
1213; RV64I-MEDIUM-NEXT:    li a0, 1
1214; RV64I-MEDIUM-NEXT:    ret
1215entry:
1216  callbr void asm "sw zero, $0; beqz $1, $2", "=*o,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal0 [label %fail]
1217
1218normal0:
1219  callbr void asm "sw zero, $0; beqz $1, $2", "=*o,r,!i"(ptr elementtype(i32) @eg, i32 %a) to label %normal1 [label %fail]
1220
1221normal1:
1222  ret i32 0
1223
1224fail:
1225  ret i32 1
1226}
1227
1228define void @constraint_A(ptr %a) nounwind {
1229; RV32I-LABEL: constraint_A:
1230; RV32I:       # %bb.0:
1231; RV32I-NEXT:    #APP
1232; RV32I-NEXT:    sb s0, 0(a0)
1233; RV32I-NEXT:    #NO_APP
1234; RV32I-NEXT:    #APP
1235; RV32I-NEXT:    lb s1, 0(a0)
1236; RV32I-NEXT:    #NO_APP
1237; RV32I-NEXT:    ret
1238;
1239; RV64I-LABEL: constraint_A:
1240; RV64I:       # %bb.0:
1241; RV64I-NEXT:    #APP
1242; RV64I-NEXT:    sb s0, 0(a0)
1243; RV64I-NEXT:    #NO_APP
1244; RV64I-NEXT:    #APP
1245; RV64I-NEXT:    lb s1, 0(a0)
1246; RV64I-NEXT:    #NO_APP
1247; RV64I-NEXT:    ret
1248;
1249; RV32I-MEDIUM-LABEL: constraint_A:
1250; RV32I-MEDIUM:       # %bb.0:
1251; RV32I-MEDIUM-NEXT:    #APP
1252; RV32I-MEDIUM-NEXT:    sb s0, 0(a0)
1253; RV32I-MEDIUM-NEXT:    #NO_APP
1254; RV32I-MEDIUM-NEXT:    #APP
1255; RV32I-MEDIUM-NEXT:    lb s1, 0(a0)
1256; RV32I-MEDIUM-NEXT:    #NO_APP
1257; RV32I-MEDIUM-NEXT:    ret
1258;
1259; RV64I-MEDIUM-LABEL: constraint_A:
1260; RV64I-MEDIUM:       # %bb.0:
1261; RV64I-MEDIUM-NEXT:    #APP
1262; RV64I-MEDIUM-NEXT:    sb s0, 0(a0)
1263; RV64I-MEDIUM-NEXT:    #NO_APP
1264; RV64I-MEDIUM-NEXT:    #APP
1265; RV64I-MEDIUM-NEXT:    lb s1, 0(a0)
1266; RV64I-MEDIUM-NEXT:    #NO_APP
1267; RV64I-MEDIUM-NEXT:    ret
1268  tail call void asm sideeffect "sb s0, $0", "*A"(ptr elementtype(i8) %a)
1269  tail call void asm sideeffect "lb s1, $0", "*A"(ptr elementtype(i8) %a)
1270  ret void
1271}
1272
1273define i32 @constraint_A_with_offset(ptr %a) nounwind {
1274; RV32I-LABEL: constraint_A_with_offset:
1275; RV32I:       # %bb.0:
1276; RV32I-NEXT:    addi a0, a0, 4
1277; RV32I-NEXT:    #APP
1278; RV32I-NEXT:    lw a0, 0(a0)
1279; RV32I-NEXT:    #NO_APP
1280; RV32I-NEXT:    ret
1281;
1282; RV64I-LABEL: constraint_A_with_offset:
1283; RV64I:       # %bb.0:
1284; RV64I-NEXT:    addi a0, a0, 4
1285; RV64I-NEXT:    #APP
1286; RV64I-NEXT:    lw a0, 0(a0)
1287; RV64I-NEXT:    #NO_APP
1288; RV64I-NEXT:    ret
1289;
1290; RV32I-MEDIUM-LABEL: constraint_A_with_offset:
1291; RV32I-MEDIUM:       # %bb.0:
1292; RV32I-MEDIUM-NEXT:    addi a0, a0, 4
1293; RV32I-MEDIUM-NEXT:    #APP
1294; RV32I-MEDIUM-NEXT:    lw a0, 0(a0)
1295; RV32I-MEDIUM-NEXT:    #NO_APP
1296; RV32I-MEDIUM-NEXT:    ret
1297;
1298; RV64I-MEDIUM-LABEL: constraint_A_with_offset:
1299; RV64I-MEDIUM:       # %bb.0:
1300; RV64I-MEDIUM-NEXT:    addi a0, a0, 4
1301; RV64I-MEDIUM-NEXT:    #APP
1302; RV64I-MEDIUM-NEXT:    lw a0, 0(a0)
1303; RV64I-MEDIUM-NEXT:    #NO_APP
1304; RV64I-MEDIUM-NEXT:    ret
1305  %1 = getelementptr i32, ptr %a, i32 1
1306  %2 = tail call i32 asm "lw $0, $1", "=r,*A"(ptr elementtype(i32) %1)
1307  ret i32 %2
1308}
1309