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 define void @sext_shl_trunc_same_size(i16 %x, i32 %y, ptr %res) {
8 ; RV32I-LABEL: sext_shl_trunc_same_size:
10 ; RV32I-NEXT: sll a0, a0, a1
11 ; RV32I-NEXT: sh a0, 0(a2)
14 ; RV64I-LABEL: sext_shl_trunc_same_size:
16 ; RV64I-NEXT: sllw a0, a0, a1
17 ; RV64I-NEXT: sh a0, 0(a2)
19 %conv = sext i16 %x to i32
20 %shl = shl i32 %conv, %y
21 %t = trunc i32 %shl to i16
22 store i16 %t, ptr %res
26 define void @zext_shl_trunc_same_size(i16 %x, i32 %y, ptr %res) {
27 ; RV32I-LABEL: zext_shl_trunc_same_size:
29 ; RV32I-NEXT: sll a0, a0, a1
30 ; RV32I-NEXT: sh a0, 0(a2)
33 ; RV64I-LABEL: zext_shl_trunc_same_size:
35 ; RV64I-NEXT: sllw a0, a0, a1
36 ; RV64I-NEXT: sh a0, 0(a2)
38 %conv = zext i16 %x to i32
39 %shl = shl i32 %conv, %y
40 %t = trunc i32 %shl to i16
41 store i16 %t, ptr %res
45 define void @sext_shl_trunc_smaller(i16 %x, i32 %y, ptr %res) {
46 ; RV32I-LABEL: sext_shl_trunc_smaller:
48 ; RV32I-NEXT: sll a0, a0, a1
49 ; RV32I-NEXT: sb a0, 0(a2)
52 ; RV64I-LABEL: sext_shl_trunc_smaller:
54 ; RV64I-NEXT: sllw a0, a0, a1
55 ; RV64I-NEXT: sb a0, 0(a2)
57 %conv = sext i16 %x to i32
58 %shl = shl i32 %conv, %y
59 %t = trunc i32 %shl to i8
64 define void @zext_shl_trunc_smaller(i16 %x, i32 %y, ptr %res) {
65 ; RV32I-LABEL: zext_shl_trunc_smaller:
67 ; RV32I-NEXT: sll a0, a0, a1
68 ; RV32I-NEXT: sb a0, 0(a2)
71 ; RV64I-LABEL: zext_shl_trunc_smaller:
73 ; RV64I-NEXT: sllw a0, a0, a1
74 ; RV64I-NEXT: sb a0, 0(a2)
76 %conv = zext i16 %x to i32
77 %shl = shl i32 %conv, %y
78 %t = trunc i32 %shl to i8
83 ; negative test - demanding 1 high-bit too many to change the extend
85 define signext i17 @sext_shl_trunc_larger(i16 %x, i32 %y) {
86 ; RV32I-LABEL: sext_shl_trunc_larger:
88 ; RV32I-NEXT: slli a0, a0, 16
89 ; RV32I-NEXT: srai a0, a0, 16
90 ; RV32I-NEXT: sll a0, a0, a1
91 ; RV32I-NEXT: slli a0, a0, 15
92 ; RV32I-NEXT: srai a0, a0, 15
95 ; RV64I-LABEL: sext_shl_trunc_larger:
97 ; RV64I-NEXT: slli a0, a0, 48
98 ; RV64I-NEXT: srai a0, a0, 48
99 ; RV64I-NEXT: sllw a0, a0, a1
100 ; RV64I-NEXT: slli a0, a0, 47
101 ; RV64I-NEXT: srai a0, a0, 47
103 %conv = sext i16 %x to i32
104 %shl = shl i32 %conv, %y
105 %t = trunc i32 %shl to i17
109 ; negative test - demanding 1 high-bit too many to change the extend
111 define zeroext i17 @zext_shl_trunc_larger(i16 %x, i32 %y) {
112 ; RV32I-LABEL: zext_shl_trunc_larger:
114 ; RV32I-NEXT: slli a0, a0, 16
115 ; RV32I-NEXT: srli a0, a0, 16
116 ; RV32I-NEXT: sll a0, a0, a1
117 ; RV32I-NEXT: slli a0, a0, 15
118 ; RV32I-NEXT: srli a0, a0, 15
121 ; RV64I-LABEL: zext_shl_trunc_larger:
123 ; RV64I-NEXT: slli a0, a0, 48
124 ; RV64I-NEXT: srli a0, a0, 48
125 ; RV64I-NEXT: sllw a0, a0, a1
126 ; RV64I-NEXT: slli a0, a0, 47
127 ; RV64I-NEXT: srli a0, a0, 47
129 %conv = zext i16 %x to i32
130 %shl = shl i32 %conv, %y
131 %t = trunc i32 %shl to i17
135 define i32 @sext_shl_mask(i16 %x, i32 %y) {
136 ; RV32I-LABEL: sext_shl_mask:
138 ; RV32I-NEXT: sll a0, a0, a1
139 ; RV32I-NEXT: slli a0, a0, 16
140 ; RV32I-NEXT: srli a0, a0, 16
143 ; RV64I-LABEL: sext_shl_mask:
145 ; RV64I-NEXT: sllw a0, a0, a1
146 ; RV64I-NEXT: slli a0, a0, 48
147 ; RV64I-NEXT: srli a0, a0, 48
149 %conv = sext i16 %x to i32
150 %shl = shl i32 %conv, %y
151 %t = and i32 %shl, 65535
155 define i32 @zext_shl_mask(i16 %x, i32 %y) {
156 ; RV32I-LABEL: zext_shl_mask:
158 ; RV32I-NEXT: sll a0, a0, a1
159 ; RV32I-NEXT: slli a0, a0, 16
160 ; RV32I-NEXT: srli a0, a0, 16
163 ; RV64I-LABEL: zext_shl_mask:
165 ; RV64I-NEXT: sllw a0, a0, a1
166 ; RV64I-NEXT: slli a0, a0, 48
167 ; RV64I-NEXT: srli a0, a0, 48
169 %conv = zext i16 %x to i32
170 %shl = shl i32 %conv, %y
171 %t = and i32 %shl, 65535
175 ; negative test - demanding a bit that could change with sext
177 define i32 @sext_shl_mask_higher(i16 %x, i32 %y) {
178 ; RV32I-LABEL: sext_shl_mask_higher:
180 ; RV32I-NEXT: slli a0, a0, 16
181 ; RV32I-NEXT: srai a0, a0, 16
182 ; RV32I-NEXT: sll a0, a0, a1
183 ; RV32I-NEXT: lui a1, 16
184 ; RV32I-NEXT: and a0, a0, a1
187 ; RV64I-LABEL: sext_shl_mask_higher:
189 ; RV64I-NEXT: slli a0, a0, 48
190 ; RV64I-NEXT: srai a0, a0, 48
191 ; RV64I-NEXT: sllw a0, a0, a1
192 ; RV64I-NEXT: lui a1, 16
193 ; RV64I-NEXT: and a0, a0, a1
195 %conv = sext i16 %x to i32
196 %shl = shl i32 %conv, %y
197 %t = and i32 %shl, 65536
201 ; negative test - demanding a bit that could change with zext
203 define i32 @zext_shl_mask_higher(i16 %x, i32 %y) {
204 ; RV32I-LABEL: zext_shl_mask_higher:
206 ; RV32I-NEXT: slli a0, a0, 16
207 ; RV32I-NEXT: srli a0, a0, 16
208 ; RV32I-NEXT: sll a0, a0, a1
209 ; RV32I-NEXT: lui a1, 16
210 ; RV32I-NEXT: and a0, a0, a1
213 ; RV64I-LABEL: zext_shl_mask_higher:
215 ; RV64I-NEXT: slli a0, a0, 48
216 ; RV64I-NEXT: srli a0, a0, 48
217 ; RV64I-NEXT: sllw a0, a0, a1
218 ; RV64I-NEXT: lui a1, 16
219 ; RV64I-NEXT: and a0, a0, a1
221 %conv = zext i16 %x to i32
222 %shl = shl i32 %conv, %y
223 %t = and i32 %shl, 65536
227 ; May need some, but not all of the bits set by the 'or'.
229 define i32 @set_shl_mask(i32 %x, i32 %y) {
230 ; RV32I-LABEL: set_shl_mask:
232 ; RV32I-NEXT: lui a2, 16
233 ; RV32I-NEXT: addi a3, a2, 1
234 ; RV32I-NEXT: or a0, a0, a3
235 ; RV32I-NEXT: sll a0, a0, a1
236 ; RV32I-NEXT: and a0, a0, a2
239 ; RV64I-LABEL: set_shl_mask:
241 ; RV64I-NEXT: lui a2, 16
242 ; RV64I-NEXT: addi a3, a2, 1
243 ; RV64I-NEXT: or a0, a0, a3
244 ; RV64I-NEXT: sllw a0, a0, a1
245 ; RV64I-NEXT: and a0, a0, a2
247 %z = or i32 %x, 196609
249 %r = and i32 %s, 65536