Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / inline-asm.ll
blobcb240d2dc68d0c1f0b32fbb295dfa9de4911d6f9
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-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -no-integrated-as < %s \
5 ; RUN:   | FileCheck -check-prefix=RV64I %s
7 @gi = external global i32
9 define i32 @constraint_r(i32 %a) nounwind {
10 ; RV32I-LABEL: constraint_r:
11 ; RV32I:       # %bb.0:
12 ; RV32I-NEXT:    lui a1, %hi(gi)
13 ; RV32I-NEXT:    lw a1, %lo(gi)(a1)
14 ; RV32I-NEXT:    #APP
15 ; RV32I-NEXT:    add a0, a0, a1
16 ; RV32I-NEXT:    #NO_APP
17 ; RV32I-NEXT:    ret
19 ; RV64I-LABEL: constraint_r:
20 ; RV64I:       # %bb.0:
21 ; RV64I-NEXT:    lui a1, %hi(gi)
22 ; RV64I-NEXT:    lw a1, %lo(gi)(a1)
23 ; RV64I-NEXT:    #APP
24 ; RV64I-NEXT:    add a0, a0, a1
25 ; RV64I-NEXT:    #NO_APP
26 ; RV64I-NEXT:    ret
27   %1 = load i32, ptr @gi
28   %2 = tail call i32 asm "add $0, $1, $2", "=r,r,r"(i32 %a, i32 %1)
29   ret i32 %2
32 ; Don't allow 'x0' for 'r'. Some instructions have a different behavior when
33 ; x0 is encoded.
34 define i32 @constraint_r_zero(i32 %a) nounwind {
35 ; RV32I-LABEL: constraint_r_zero:
36 ; RV32I:       # %bb.0:
37 ; RV32I-NEXT:    lui a0, %hi(gi)
38 ; RV32I-NEXT:    lw a0, %lo(gi)(a0)
39 ; RV32I-NEXT:    li a1, 0
40 ; RV32I-NEXT:    #APP
41 ; RV32I-NEXT:    add a0, a1, a0
42 ; RV32I-NEXT:    #NO_APP
43 ; RV32I-NEXT:    ret
45 ; RV64I-LABEL: constraint_r_zero:
46 ; RV64I:       # %bb.0:
47 ; RV64I-NEXT:    lui a0, %hi(gi)
48 ; RV64I-NEXT:    lw a0, %lo(gi)(a0)
49 ; RV64I-NEXT:    li a1, 0
50 ; RV64I-NEXT:    #APP
51 ; RV64I-NEXT:    add a0, a1, a0
52 ; RV64I-NEXT:    #NO_APP
53 ; RV64I-NEXT:    ret
54   %1 = load i32, ptr @gi
55   %2 = tail call i32 asm "add $0, $1, $2", "=r,r,r"(i32 0, i32 %1)
56   ret i32 %2
59 define i32 @constraint_i(i32 %a) nounwind {
60 ; RV32I-LABEL: constraint_i:
61 ; RV32I:       # %bb.0:
62 ; RV32I-NEXT:    #APP
63 ; RV32I-NEXT:    addi a0, a0, 113
64 ; RV32I-NEXT:    #NO_APP
65 ; RV32I-NEXT:    ret
67 ; RV64I-LABEL: constraint_i:
68 ; RV64I:       # %bb.0:
69 ; RV64I-NEXT:    #APP
70 ; RV64I-NEXT:    addi a0, a0, 113
71 ; RV64I-NEXT:    #NO_APP
72 ; RV64I-NEXT:    ret
73   %1 = load i32, ptr @gi
74   %2 = tail call i32 asm "addi $0, $1, $2", "=r,r,i"(i32 %a, i32 113)
75   ret i32 %2
78 define void @constraint_I() nounwind {
79 ; RV32I-LABEL: constraint_I:
80 ; RV32I:       # %bb.0:
81 ; RV32I-NEXT:    #APP
82 ; RV32I-NEXT:    addi a0, a0, 2047
83 ; RV32I-NEXT:    #NO_APP
84 ; RV32I-NEXT:    #APP
85 ; RV32I-NEXT:    addi a0, a0, -2048
86 ; RV32I-NEXT:    #NO_APP
87 ; RV32I-NEXT:    ret
89 ; RV64I-LABEL: constraint_I:
90 ; RV64I:       # %bb.0:
91 ; RV64I-NEXT:    #APP
92 ; RV64I-NEXT:    addi a0, a0, 2047
93 ; RV64I-NEXT:    #NO_APP
94 ; RV64I-NEXT:    #APP
95 ; RV64I-NEXT:    addi a0, a0, -2048
96 ; RV64I-NEXT:    #NO_APP
97 ; RV64I-NEXT:    ret
98   tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 2047)
99   tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 -2048)
100   ret void
103 define void @constraint_J() nounwind {
104 ; RV32I-LABEL: constraint_J:
105 ; RV32I:       # %bb.0:
106 ; RV32I-NEXT:    #APP
107 ; RV32I-NEXT:    addi a0, a0, 0
108 ; RV32I-NEXT:    #NO_APP
109 ; RV32I-NEXT:    ret
111 ; RV64I-LABEL: constraint_J:
112 ; RV64I:       # %bb.0:
113 ; RV64I-NEXT:    #APP
114 ; RV64I-NEXT:    addi a0, a0, 0
115 ; RV64I-NEXT:    #NO_APP
116 ; RV64I-NEXT:    ret
117   tail call void asm sideeffect "addi a0, a0, $0", "J"(i32 0)
118   ret void
121 define void @constraint_K() nounwind {
122 ; RV32I-LABEL: constraint_K:
123 ; RV32I:       # %bb.0:
124 ; RV32I-NEXT:    #APP
125 ; RV32I-NEXT:    csrwi mstatus, 31
126 ; RV32I-NEXT:    #NO_APP
127 ; RV32I-NEXT:    #APP
128 ; RV32I-NEXT:    csrwi mstatus, 0
129 ; RV32I-NEXT:    #NO_APP
130 ; RV32I-NEXT:    ret
132 ; RV64I-LABEL: constraint_K:
133 ; RV64I:       # %bb.0:
134 ; RV64I-NEXT:    #APP
135 ; RV64I-NEXT:    csrwi mstatus, 31
136 ; RV64I-NEXT:    #NO_APP
137 ; RV64I-NEXT:    #APP
138 ; RV64I-NEXT:    csrwi mstatus, 0
139 ; RV64I-NEXT:    #NO_APP
140 ; RV64I-NEXT:    ret
141   tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 31)
142   tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 0)
143   ret void
146 define i32 @modifier_z_zero(i32 %a) nounwind {
147 ; RV32I-LABEL: modifier_z_zero:
148 ; RV32I:       # %bb.0:
149 ; RV32I-NEXT:    #APP
150 ; RV32I-NEXT:    add a0, a0, zero
151 ; RV32I-NEXT:    #NO_APP
152 ; RV32I-NEXT:    ret
154 ; RV64I-LABEL: modifier_z_zero:
155 ; RV64I:       # %bb.0:
156 ; RV64I-NEXT:    #APP
157 ; RV64I-NEXT:    add a0, a0, zero
158 ; RV64I-NEXT:    #NO_APP
159 ; RV64I-NEXT:    ret
160   %1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,i"(i32 %a, i32 0)
161   ret i32 %1
164 define i32 @modifier_z_nonzero(i32 %a) nounwind {
165 ; RV32I-LABEL: modifier_z_nonzero:
166 ; RV32I:       # %bb.0:
167 ; RV32I-NEXT:    #APP
168 ; RV32I-NEXT:    add a0, a0, 1
169 ; RV32I-NEXT:    #NO_APP
170 ; RV32I-NEXT:    ret
172 ; RV64I-LABEL: modifier_z_nonzero:
173 ; RV64I:       # %bb.0:
174 ; RV64I-NEXT:    #APP
175 ; RV64I-NEXT:    add a0, a0, 1
176 ; RV64I-NEXT:    #NO_APP
177 ; RV64I-NEXT:    ret
178   %1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,i"(i32 %a, i32 1)
179   ret i32 %1
182 define i32 @modifier_i_imm(i32 %a) nounwind {
183 ; RV32I-LABEL: modifier_i_imm:
184 ; RV32I:       # %bb.0:
185 ; RV32I-NEXT:    #APP
186 ; RV32I-NEXT:    addi a0, a0, 1
187 ; RV32I-NEXT:    #NO_APP
188 ; RV32I-NEXT:    ret
190 ; RV64I-LABEL: modifier_i_imm:
191 ; RV64I:       # %bb.0:
192 ; RV64I-NEXT:    #APP
193 ; RV64I-NEXT:    addi a0, a0, 1
194 ; RV64I-NEXT:    #NO_APP
195 ; RV64I-NEXT:    ret
196   %1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 1)
197   ret i32 %1
200 define i32 @modifier_i_reg(i32 %a, i32 %b) nounwind {
201 ; RV32I-LABEL: modifier_i_reg:
202 ; RV32I:       # %bb.0:
203 ; RV32I-NEXT:    #APP
204 ; RV32I-NEXT:    add a0, a0, a1
205 ; RV32I-NEXT:    #NO_APP
206 ; RV32I-NEXT:    ret
208 ; RV64I-LABEL: modifier_i_reg:
209 ; RV64I:       # %bb.0:
210 ; RV64I-NEXT:    #APP
211 ; RV64I-NEXT:    add a0, a0, a1
212 ; RV64I-NEXT:    #NO_APP
213 ; RV64I-NEXT:    ret
214   %1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 %b)
215   ret i32 %1
218 define void @operand_global() nounwind {
219 ; RV32I-LABEL: operand_global:
220 ; RV32I:       # %bb.0:
221 ; RV32I-NEXT:    #APP
222 ; RV32I-NEXT:    .8byte gi
223 ; RV32I-NEXT:    #NO_APP
224 ; RV32I-NEXT:    ret
226 ; RV64I-LABEL: operand_global:
227 ; RV64I:       # %bb.0:
228 ; RV64I-NEXT:    #APP
229 ; RV64I-NEXT:    .8byte gi
230 ; RV64I-NEXT:    #NO_APP
231 ; RV64I-NEXT:    ret
232   tail call void asm sideeffect ".8byte $0", "i"(ptr @gi)
233   ret void
236 define void @operand_block_address() nounwind {
237 ; RV32I-LABEL: operand_block_address:
238 ; RV32I:       # %bb.0:
239 ; RV32I-NEXT:    #APP
240 ; RV32I-NEXT:    j .Ltmp0
241 ; RV32I-NEXT:    #NO_APP
242 ; RV32I-NEXT:  .Ltmp0: # Block address taken
243 ; RV32I-NEXT:  # %bb.1: # %bb
244 ; RV32I-NEXT:    ret
246 ; RV64I-LABEL: operand_block_address:
247 ; RV64I:       # %bb.0:
248 ; RV64I-NEXT:    #APP
249 ; RV64I-NEXT:    j .Ltmp0
250 ; RV64I-NEXT:    #NO_APP
251 ; RV64I-NEXT:  .Ltmp0: # Block address taken
252 ; RV64I-NEXT:  # %bb.1: # %bb
253 ; RV64I-NEXT:    ret
254   call void asm sideeffect "j $0", "i"(ptr blockaddress(@operand_block_address, %bb))
255   br label %bb
257   ret void
260 ; TODO: expand tests for more complex constraints, out of range immediates etc