Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / alu16.ll
blobcb28ccdda0a54b082bc04260870bc85e6c63c868
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck %s -check-prefix=RV32I
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck %s -check-prefix=RV64I
7 ; These tests are identical to those in alu32.ll but operate on i16. They check
8 ; that legalisation of these non-native types doesn't introduce unnecessary
9 ; inefficiencies.
11 define i16 @addi(i16 %a) nounwind {
12 ; RV32I-LABEL: addi:
13 ; RV32I:       # %bb.0:
14 ; RV32I-NEXT:    addi a0, a0, 1
15 ; RV32I-NEXT:    ret
17 ; RV64I-LABEL: addi:
18 ; RV64I:       # %bb.0:
19 ; RV64I-NEXT:    addi a0, a0, 1
20 ; RV64I-NEXT:    ret
21   %1 = add i16 %a, 1
22   ret i16 %1
25 define i16 @slti(i16 %a) nounwind {
26 ; RV32I-LABEL: slti:
27 ; RV32I:       # %bb.0:
28 ; RV32I-NEXT:    slli a0, a0, 16
29 ; RV32I-NEXT:    srai a0, a0, 16
30 ; RV32I-NEXT:    slti a0, a0, 2
31 ; RV32I-NEXT:    ret
33 ; RV64I-LABEL: slti:
34 ; RV64I:       # %bb.0:
35 ; RV64I-NEXT:    slli a0, a0, 48
36 ; RV64I-NEXT:    srai a0, a0, 48
37 ; RV64I-NEXT:    slti a0, a0, 2
38 ; RV64I-NEXT:    ret
39   %1 = icmp slt i16 %a, 2
40   %2 = zext i1 %1 to i16
41   ret i16 %2
44 define i16 @sltiu(i16 %a) nounwind {
45 ; RV32I-LABEL: sltiu:
46 ; RV32I:       # %bb.0:
47 ; RV32I-NEXT:    slli a0, a0, 16
48 ; RV32I-NEXT:    srli a0, a0, 16
49 ; RV32I-NEXT:    sltiu a0, a0, 3
50 ; RV32I-NEXT:    ret
52 ; RV64I-LABEL: sltiu:
53 ; RV64I:       # %bb.0:
54 ; RV64I-NEXT:    slli a0, a0, 48
55 ; RV64I-NEXT:    srli a0, a0, 48
56 ; RV64I-NEXT:    sltiu a0, a0, 3
57 ; RV64I-NEXT:    ret
58   %1 = icmp ult i16 %a, 3
59   %2 = zext i1 %1 to i16
60   ret i16 %2
63 ; Make sure we avoid an AND, if the input of an unsigned compare is known
64 ; to be sign extended. This can occur due to InstCombine canonicalizing
65 ; x s>= 0 && x s< 10 to x u< 10.
66 define i16 @sltiu_signext(i16 signext %a) nounwind {
67 ; RV32I-LABEL: sltiu_signext:
68 ; RV32I:       # %bb.0:
69 ; RV32I-NEXT:    sltiu a0, a0, 10
70 ; RV32I-NEXT:    ret
72 ; RV64I-LABEL: sltiu_signext:
73 ; RV64I:       # %bb.0:
74 ; RV64I-NEXT:    sltiu a0, a0, 10
75 ; RV64I-NEXT:    ret
76   %1 = icmp ult i16 %a, 10
77   %2 = zext i1 %1 to i16
78   ret i16 %2
81 define i16 @xori(i16 %a) nounwind {
82 ; RV32I-LABEL: xori:
83 ; RV32I:       # %bb.0:
84 ; RV32I-NEXT:    xori a0, a0, 4
85 ; RV32I-NEXT:    ret
87 ; RV64I-LABEL: xori:
88 ; RV64I:       # %bb.0:
89 ; RV64I-NEXT:    xori a0, a0, 4
90 ; RV64I-NEXT:    ret
91   %1 = xor i16 %a, 4
92   ret i16 %1
95 define i16 @ori(i16 %a) nounwind {
96 ; RV32I-LABEL: ori:
97 ; RV32I:       # %bb.0:
98 ; RV32I-NEXT:    ori a0, a0, 5
99 ; RV32I-NEXT:    ret
101 ; RV64I-LABEL: ori:
102 ; RV64I:       # %bb.0:
103 ; RV64I-NEXT:    ori a0, a0, 5
104 ; RV64I-NEXT:    ret
105   %1 = or i16 %a, 5
106   ret i16 %1
109 define i16 @andi(i16 %a) nounwind {
110 ; RV32I-LABEL: andi:
111 ; RV32I:       # %bb.0:
112 ; RV32I-NEXT:    andi a0, a0, 6
113 ; RV32I-NEXT:    ret
115 ; RV64I-LABEL: andi:
116 ; RV64I:       # %bb.0:
117 ; RV64I-NEXT:    andi a0, a0, 6
118 ; RV64I-NEXT:    ret
119   %1 = and i16 %a, 6
120   ret i16 %1
123 define i16 @slli(i16 %a) nounwind {
124 ; RV32I-LABEL: slli:
125 ; RV32I:       # %bb.0:
126 ; RV32I-NEXT:    slli a0, a0, 7
127 ; RV32I-NEXT:    ret
129 ; RV64I-LABEL: slli:
130 ; RV64I:       # %bb.0:
131 ; RV64I-NEXT:    slli a0, a0, 7
132 ; RV64I-NEXT:    ret
133   %1 = shl i16 %a, 7
134   ret i16 %1
137 define i16 @srli(i16 %a) nounwind {
138 ; RV32I-LABEL: srli:
139 ; RV32I:       # %bb.0:
140 ; RV32I-NEXT:    slli a0, a0, 16
141 ; RV32I-NEXT:    srli a0, a0, 22
142 ; RV32I-NEXT:    ret
144 ; RV64I-LABEL: srli:
145 ; RV64I:       # %bb.0:
146 ; RV64I-NEXT:    slli a0, a0, 48
147 ; RV64I-NEXT:    srli a0, a0, 54
148 ; RV64I-NEXT:    ret
149   %1 = lshr i16 %a, 6
150   ret i16 %1
153 define i16 @srai(i16 %a) nounwind {
154 ; RV32I-LABEL: srai:
155 ; RV32I:       # %bb.0:
156 ; RV32I-NEXT:    slli a0, a0, 16
157 ; RV32I-NEXT:    srai a0, a0, 25
158 ; RV32I-NEXT:    ret
160 ; RV64I-LABEL: srai:
161 ; RV64I:       # %bb.0:
162 ; RV64I-NEXT:    slli a0, a0, 48
163 ; RV64I-NEXT:    srai a0, a0, 57
164 ; RV64I-NEXT:    ret
165   %1 = ashr i16 %a, 9
166   ret i16 %1
170 define i16 @add(i16 %a, i16 %b) nounwind {
171 ; RV32I-LABEL: add:
172 ; RV32I:       # %bb.0:
173 ; RV32I-NEXT:    add a0, a0, a1
174 ; RV32I-NEXT:    ret
176 ; RV64I-LABEL: add:
177 ; RV64I:       # %bb.0:
178 ; RV64I-NEXT:    add a0, a0, a1
179 ; RV64I-NEXT:    ret
180   %1 = add i16 %a, %b
181   ret i16 %1
184 define i16 @sub(i16 %a, i16 %b) nounwind {
185 ; RV32I-LABEL: sub:
186 ; RV32I:       # %bb.0:
187 ; RV32I-NEXT:    sub a0, a0, a1
188 ; RV32I-NEXT:    ret
190 ; RV64I-LABEL: sub:
191 ; RV64I:       # %bb.0:
192 ; RV64I-NEXT:    sub a0, a0, a1
193 ; RV64I-NEXT:    ret
194   %1 = sub i16 %a, %b
195   ret i16 %1
198 define i16 @sll(i16 %a, i16 %b) nounwind {
199 ; RV32I-LABEL: sll:
200 ; RV32I:       # %bb.0:
201 ; RV32I-NEXT:    sll a0, a0, a1
202 ; RV32I-NEXT:    ret
204 ; RV64I-LABEL: sll:
205 ; RV64I:       # %bb.0:
206 ; RV64I-NEXT:    sll a0, a0, a1
207 ; RV64I-NEXT:    ret
208   %1 = shl i16 %a, %b
209   ret i16 %1
212 ; Test the pattern we get from C integer promotion.
213 define void @sll_ext(i16 %a, i32 signext %b, ptr %p) nounwind {
214 ; RV32I-LABEL: sll_ext:
215 ; RV32I:       # %bb.0:
216 ; RV32I-NEXT:    sll a0, a0, a1
217 ; RV32I-NEXT:    sh a0, 0(a2)
218 ; RV32I-NEXT:    ret
220 ; RV64I-LABEL: sll_ext:
221 ; RV64I:       # %bb.0:
222 ; RV64I-NEXT:    sllw a0, a0, a1
223 ; RV64I-NEXT:    sh a0, 0(a2)
224 ; RV64I-NEXT:    ret
225   %1 = zext i16 %a to i32
226   %2 = shl i32 %1, %b
227   %3 = trunc i32 %2 to i16
228   store i16 %3, ptr %p
229   ret void
232 ; Test the pattern we get from C integer promotion. This time with poison
233 ; generating flags.
234 define void @sll_ext_drop_poison(i16 %a, i32 signext %b, ptr %p) nounwind {
235 ; RV32I-LABEL: sll_ext_drop_poison:
236 ; RV32I:       # %bb.0:
237 ; RV32I-NEXT:    sll a0, a0, a1
238 ; RV32I-NEXT:    sh a0, 0(a2)
239 ; RV32I-NEXT:    ret
241 ; RV64I-LABEL: sll_ext_drop_poison:
242 ; RV64I:       # %bb.0:
243 ; RV64I-NEXT:    sllw a0, a0, a1
244 ; RV64I-NEXT:    sh a0, 0(a2)
245 ; RV64I-NEXT:    ret
246   %1 = zext i16 %a to i32
247   %2 = shl nuw nsw i32 %1, %b
248   %3 = trunc i32 %2 to i16
249   store i16 %3, ptr %p
250   ret void
253 define i16 @slt(i16 %a, i16 %b) nounwind {
254 ; RV32I-LABEL: slt:
255 ; RV32I:       # %bb.0:
256 ; RV32I-NEXT:    slli a1, a1, 16
257 ; RV32I-NEXT:    srai a1, a1, 16
258 ; RV32I-NEXT:    slli a0, a0, 16
259 ; RV32I-NEXT:    srai a0, a0, 16
260 ; RV32I-NEXT:    slt a0, a0, a1
261 ; RV32I-NEXT:    ret
263 ; RV64I-LABEL: slt:
264 ; RV64I:       # %bb.0:
265 ; RV64I-NEXT:    slli a1, a1, 48
266 ; RV64I-NEXT:    srai a1, a1, 48
267 ; RV64I-NEXT:    slli a0, a0, 48
268 ; RV64I-NEXT:    srai a0, a0, 48
269 ; RV64I-NEXT:    slt a0, a0, a1
270 ; RV64I-NEXT:    ret
271   %1 = icmp slt i16 %a, %b
272   %2 = zext i1 %1 to i16
273   ret i16 %2
276 define i16 @sltu(i16 %a, i16 %b) nounwind {
277 ; RV32I-LABEL: sltu:
278 ; RV32I:       # %bb.0:
279 ; RV32I-NEXT:    lui a2, 16
280 ; RV32I-NEXT:    addi a2, a2, -1
281 ; RV32I-NEXT:    and a1, a1, a2
282 ; RV32I-NEXT:    and a0, a0, a2
283 ; RV32I-NEXT:    sltu a0, a0, a1
284 ; RV32I-NEXT:    ret
286 ; RV64I-LABEL: sltu:
287 ; RV64I:       # %bb.0:
288 ; RV64I-NEXT:    lui a2, 16
289 ; RV64I-NEXT:    addiw a2, a2, -1
290 ; RV64I-NEXT:    and a1, a1, a2
291 ; RV64I-NEXT:    and a0, a0, a2
292 ; RV64I-NEXT:    sltu a0, a0, a1
293 ; RV64I-NEXT:    ret
294   %1 = icmp ult i16 %a, %b
295   %2 = zext i1 %1 to i16
296   ret i16 %2
299 define i16 @xor(i16 %a, i16 %b) nounwind {
300 ; RV32I-LABEL: xor:
301 ; RV32I:       # %bb.0:
302 ; RV32I-NEXT:    xor a0, a0, a1
303 ; RV32I-NEXT:    ret
305 ; RV64I-LABEL: xor:
306 ; RV64I:       # %bb.0:
307 ; RV64I-NEXT:    xor a0, a0, a1
308 ; RV64I-NEXT:    ret
309   %1 = xor i16 %a, %b
310   ret i16 %1
313 define i16 @srl(i16 %a, i16 %b) nounwind {
314 ; RV32I-LABEL: srl:
315 ; RV32I:       # %bb.0:
316 ; RV32I-NEXT:    slli a0, a0, 16
317 ; RV32I-NEXT:    srli a0, a0, 16
318 ; RV32I-NEXT:    srl a0, a0, a1
319 ; RV32I-NEXT:    ret
321 ; RV64I-LABEL: srl:
322 ; RV64I:       # %bb.0:
323 ; RV64I-NEXT:    slli a0, a0, 48
324 ; RV64I-NEXT:    srli a0, a0, 48
325 ; RV64I-NEXT:    srl a0, a0, a1
326 ; RV64I-NEXT:    ret
327   %1 = lshr i16 %a, %b
328   ret i16 %1
331 define i16 @sra(i16 %a, i16 %b) nounwind {
332 ; RV32I-LABEL: sra:
333 ; RV32I:       # %bb.0:
334 ; RV32I-NEXT:    slli a0, a0, 16
335 ; RV32I-NEXT:    srai a0, a0, 16
336 ; RV32I-NEXT:    sra a0, a0, a1
337 ; RV32I-NEXT:    ret
339 ; RV64I-LABEL: sra:
340 ; RV64I:       # %bb.0:
341 ; RV64I-NEXT:    slli a0, a0, 48
342 ; RV64I-NEXT:    srai a0, a0, 48
343 ; RV64I-NEXT:    sra a0, a0, a1
344 ; RV64I-NEXT:    ret
345   %1 = ashr i16 %a, %b
346   ret i16 %1
349 define i16 @or(i16 %a, i16 %b) nounwind {
350 ; RV32I-LABEL: or:
351 ; RV32I:       # %bb.0:
352 ; RV32I-NEXT:    or a0, a0, a1
353 ; RV32I-NEXT:    ret
355 ; RV64I-LABEL: or:
356 ; RV64I:       # %bb.0:
357 ; RV64I-NEXT:    or a0, a0, a1
358 ; RV64I-NEXT:    ret
359   %1 = or i16 %a, %b
360   ret i16 %1
363 define i16 @and(i16 %a, i16 %b) nounwind {
364 ; RV32I-LABEL: and:
365 ; RV32I:       # %bb.0:
366 ; RV32I-NEXT:    and a0, a0, a1
367 ; RV32I-NEXT:    ret
369 ; RV64I-LABEL: and:
370 ; RV64I:       # %bb.0:
371 ; RV64I-NEXT:    and a0, a0, a1
372 ; RV64I-NEXT:    ret
373   %1 = and i16 %a, %b
374   ret i16 %1