[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / RISCV / inline-asm.ll
blobc5aa8540427a0c39551f16b661ff74f68bc50a8c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %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:    lwu 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, i32* @gi
28   %2 = tail call i32 asm "add $0, $1, $2", "=r,r,r"(i32 %a, i32 %1)
29   ret i32 %2
32 define i32 @constraint_i(i32 %a) nounwind {
33 ; RV32I-LABEL: constraint_i:
34 ; RV32I:       # %bb.0:
35 ; RV32I-NEXT:    #APP
36 ; RV32I-NEXT:    addi a0, a0, 113
37 ; RV32I-NEXT:    #NO_APP
38 ; RV32I-NEXT:    ret
40 ; RV64I-LABEL: constraint_i:
41 ; RV64I:       # %bb.0:
42 ; RV64I-NEXT:    #APP
43 ; RV64I-NEXT:    addi a0, a0, 113
44 ; RV64I-NEXT:    #NO_APP
45 ; RV64I-NEXT:    ret
46   %1 = load i32, i32* @gi
47   %2 = tail call i32 asm "addi $0, $1, $2", "=r,r,i"(i32 %a, i32 113)
48   ret i32 %2
51 define void @constraint_m(i32* %a) nounwind {
52 ; RV32I-LABEL: constraint_m:
53 ; RV32I:       # %bb.0:
54 ; RV32I-NEXT:    #APP
55 ; RV32I-NEXT:    #NO_APP
56 ; RV32I-NEXT:    ret
58 ; RV64I-LABEL: constraint_m:
59 ; RV64I:       # %bb.0:
60 ; RV64I-NEXT:    #APP
61 ; RV64I-NEXT:    #NO_APP
62 ; RV64I-NEXT:    ret
63   call void asm sideeffect "", "=*m"(i32* %a)
64   ret void
67 define i32 @constraint_m2(i32* %a) nounwind {
68 ; RV32I-LABEL: constraint_m2:
69 ; RV32I:       # %bb.0:
70 ; RV32I-NEXT:    #APP
71 ; RV32I-NEXT:    lw a0, 0(a0)
72 ; RV32I-NEXT:    #NO_APP
73 ; RV32I-NEXT:    ret
75 ; RV64I-LABEL: constraint_m2:
76 ; RV64I:       # %bb.0:
77 ; RV64I-NEXT:    #APP
78 ; RV64I-NEXT:    lw a0, 0(a0)
79 ; RV64I-NEXT:    #NO_APP
80 ; RV64I-NEXT:    ret
81   %1 = tail call i32 asm "lw $0, $1", "=r,*m"(i32* %a) nounwind
82   ret i32 %1
85 define void @constraint_I() nounwind {
86 ; RV32I-LABEL: constraint_I:
87 ; RV32I:       # %bb.0:
88 ; RV32I-NEXT:    #APP
89 ; RV32I-NEXT:    addi a0, a0, 2047
90 ; RV32I-NEXT:    #NO_APP
91 ; RV32I-NEXT:    #APP
92 ; RV32I-NEXT:    addi a0, a0, -2048
93 ; RV32I-NEXT:    #NO_APP
94 ; RV32I-NEXT:    ret
96 ; RV64I-LABEL: constraint_I:
97 ; RV64I:       # %bb.0:
98 ; RV64I-NEXT:    #APP
99 ; RV64I-NEXT:    addi a0, a0, 2047
100 ; RV64I-NEXT:    #NO_APP
101 ; RV64I-NEXT:    #APP
102 ; RV64I-NEXT:    addi a0, a0, -2048
103 ; RV64I-NEXT:    #NO_APP
104 ; RV64I-NEXT:    ret
105   tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 2047)
106   tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 -2048)
107   ret void
110 define void @constraint_J() nounwind {
111 ; RV32I-LABEL: constraint_J:
112 ; RV32I:       # %bb.0:
113 ; RV32I-NEXT:    #APP
114 ; RV32I-NEXT:    addi a0, a0, 0
115 ; RV32I-NEXT:    #NO_APP
116 ; RV32I-NEXT:    ret
118 ; RV64I-LABEL: constraint_J:
119 ; RV64I:       # %bb.0:
120 ; RV64I-NEXT:    #APP
121 ; RV64I-NEXT:    addi a0, a0, 0
122 ; RV64I-NEXT:    #NO_APP
123 ; RV64I-NEXT:    ret
124   tail call void asm sideeffect "addi a0, a0, $0", "J"(i32 0)
125   ret void
128 define void @constraint_K() nounwind {
129 ; RV32I-LABEL: constraint_K:
130 ; RV32I:       # %bb.0:
131 ; RV32I-NEXT:    #APP
132 ; RV32I-NEXT:    csrwi mstatus, 31
133 ; RV32I-NEXT:    #NO_APP
134 ; RV32I-NEXT:    #APP
135 ; RV32I-NEXT:    csrwi mstatus, 0
136 ; RV32I-NEXT:    #NO_APP
137 ; RV32I-NEXT:    ret
139 ; RV64I-LABEL: constraint_K:
140 ; RV64I:       # %bb.0:
141 ; RV64I-NEXT:    #APP
142 ; RV64I-NEXT:    csrwi mstatus, 31
143 ; RV64I-NEXT:    #NO_APP
144 ; RV64I-NEXT:    #APP
145 ; RV64I-NEXT:    csrwi mstatus, 0
146 ; RV64I-NEXT:    #NO_APP
147 ; RV64I-NEXT:    ret
148   tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 31)
149   tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 0)
150   ret void
153 define void @constraint_A(i8* %a) nounwind {
154 ; RV32I-LABEL: constraint_A:
155 ; RV32I:       # %bb.0:
156 ; RV32I-NEXT:    #APP
157 ; RV32I-NEXT:    sb s0, 0(a0)
158 ; RV32I-NEXT:    #NO_APP
159 ; RV32I-NEXT:    #APP
160 ; RV32I-NEXT:    lb s1, 0(a0)
161 ; RV32I-NEXT:    #NO_APP
162 ; RV32I-NEXT:    ret
164 ; RV64I-LABEL: constraint_A:
165 ; RV64I:       # %bb.0:
166 ; RV64I-NEXT:    #APP
167 ; RV64I-NEXT:    sb s0, 0(a0)
168 ; RV64I-NEXT:    #NO_APP
169 ; RV64I-NEXT:    #APP
170 ; RV64I-NEXT:    lb s1, 0(a0)
171 ; RV64I-NEXT:    #NO_APP
172 ; RV64I-NEXT:    ret
173   tail call void asm sideeffect "sb s0, $0", "*A"(i8* %a)
174   tail call void asm sideeffect "lb s1, $0", "*A"(i8* %a)
175   ret void
178 define i32 @modifier_z_zero(i32 %a) nounwind {
179 ; RV32I-LABEL: modifier_z_zero:
180 ; RV32I:       # %bb.0:
181 ; RV32I-NEXT:    #APP
182 ; RV32I-NEXT:    add a0, a0, zero
183 ; RV32I-NEXT:    #NO_APP
184 ; RV32I-NEXT:    ret
186 ; RV64I-LABEL: modifier_z_zero:
187 ; RV64I:       # %bb.0:
188 ; RV64I-NEXT:    #APP
189 ; RV64I-NEXT:    add a0, a0, zero
190 ; RV64I-NEXT:    #NO_APP
191 ; RV64I-NEXT:    ret
192   %1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,r"(i32 %a, i32 0)
193   ret i32 %1
196 define i32 @modifier_z_nonzero(i32 %a) nounwind {
197 ; RV32I-LABEL: modifier_z_nonzero:
198 ; RV32I:       # %bb.0:
199 ; RV32I-NEXT:    addi a1, zero, 1
200 ; RV32I-NEXT:    #APP
201 ; RV32I-NEXT:    add a0, a0, a1
202 ; RV32I-NEXT:    #NO_APP
203 ; RV32I-NEXT:    ret
205 ; RV64I-LABEL: modifier_z_nonzero:
206 ; RV64I:       # %bb.0:
207 ; RV64I-NEXT:    addi a1, zero, 1
208 ; RV64I-NEXT:    #APP
209 ; RV64I-NEXT:    add a0, a0, a1
210 ; RV64I-NEXT:    #NO_APP
211 ; RV64I-NEXT:    ret
212   %1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,r"(i32 %a, i32 1)
213   ret i32 %1
216 define i32 @modifier_i_imm(i32 %a) nounwind {
217 ; RV32I-LABEL: modifier_i_imm:
218 ; RV32I:       # %bb.0:
219 ; RV32I-NEXT:    #APP
220 ; RV32I-NEXT:    addi a0, a0, 1
221 ; RV32I-NEXT:    #NO_APP
222 ; RV32I-NEXT:    ret
224 ; RV64I-LABEL: modifier_i_imm:
225 ; RV64I:       # %bb.0:
226 ; RV64I-NEXT:    #APP
227 ; RV64I-NEXT:    addi a0, a0, 1
228 ; RV64I-NEXT:    #NO_APP
229 ; RV64I-NEXT:    ret
230   %1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 1)
231   ret i32 %1
234 define i32 @modifier_i_reg(i32 %a, i32 %b) nounwind {
235 ; RV32I-LABEL: modifier_i_reg:
236 ; RV32I:       # %bb.0:
237 ; RV32I-NEXT:    #APP
238 ; RV32I-NEXT:    add a0, a0, a1
239 ; RV32I-NEXT:    #NO_APP
240 ; RV32I-NEXT:    ret
242 ; RV64I-LABEL: modifier_i_reg:
243 ; RV64I:       # %bb.0:
244 ; RV64I-NEXT:    #APP
245 ; RV64I-NEXT:    add a0, a0, a1
246 ; RV64I-NEXT:    #NO_APP
247 ; RV64I-NEXT:    ret
248   %1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 %b)
249   ret i32 %1
252 ; TODO: expend tests for more complex constraints, out of range immediates etc