1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --extra_scrub
2 ; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefixes=RV32I
4 ; RUN: llc -mtriple=riscv32 -mattr=+m,+xtheadba -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=RV32XTHEADBA
7 define signext i16 @th_addsl_1(i64 %0, ptr %1) {
8 ; RV32I-LABEL: th_addsl_1:
10 ; RV32I-NEXT: slli a0, a0, 1
11 ; RV32I-NEXT: add a0, a2, a0
12 ; RV32I-NEXT: lh a0, 0(a0)
15 ; RV32XTHEADBA-LABEL: th_addsl_1:
16 ; RV32XTHEADBA: # %bb.0:
17 ; RV32XTHEADBA-NEXT: th.addsl a0, a2, a0, 1
18 ; RV32XTHEADBA-NEXT: lh a0, 0(a0)
19 ; RV32XTHEADBA-NEXT: ret
20 %3 = getelementptr inbounds i16, ptr %1, i64 %0
25 define signext i32 @th_addsl_2(i64 %0, ptr %1) {
26 ; RV32I-LABEL: th_addsl_2:
28 ; RV32I-NEXT: slli a0, a0, 2
29 ; RV32I-NEXT: add a0, a2, a0
30 ; RV32I-NEXT: lw a0, 0(a0)
33 ; RV32XTHEADBA-LABEL: th_addsl_2:
34 ; RV32XTHEADBA: # %bb.0:
35 ; RV32XTHEADBA-NEXT: th.addsl a0, a2, a0, 2
36 ; RV32XTHEADBA-NEXT: lw a0, 0(a0)
37 ; RV32XTHEADBA-NEXT: ret
38 %3 = getelementptr inbounds i32, ptr %1, i64 %0
43 define i64 @th_addsl_3(i64 %0, ptr %1) {
44 ; RV32I-LABEL: th_addsl_3:
46 ; RV32I-NEXT: slli a0, a0, 3
47 ; RV32I-NEXT: add a2, a2, a0
48 ; RV32I-NEXT: lw a0, 0(a2)
49 ; RV32I-NEXT: lw a1, 4(a2)
52 ; RV32XTHEADBA-LABEL: th_addsl_3:
53 ; RV32XTHEADBA: # %bb.0:
54 ; RV32XTHEADBA-NEXT: th.addsl a1, a2, a0, 3
55 ; RV32XTHEADBA-NEXT: lw a0, 0(a1)
56 ; RV32XTHEADBA-NEXT: lw a1, 4(a1)
57 ; RV32XTHEADBA-NEXT: ret
58 %3 = getelementptr inbounds i64, ptr %1, i64 %0
63 ; Type legalization inserts a sext_inreg after the first add. That add will be
64 ; selected as th.addsl which does not sign extend. SimplifyDemandedBits is unable
65 ; to remove the sext_inreg because it has multiple uses. The ashr will use the
66 ; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
67 ; If the shl is selected as sllw, we don't need the sext_inreg.
68 define i64 @th_addsl_2_extra_sext(i32 %x, i32 %y, i32 %z) {
69 ; RV32I-LABEL: th_addsl_2_extra_sext:
71 ; RV32I-NEXT: slli a0, a0, 2
72 ; RV32I-NEXT: add a0, a0, a1
73 ; RV32I-NEXT: sll a1, a2, a0
74 ; RV32I-NEXT: srai a2, a0, 2
75 ; RV32I-NEXT: mul a0, a1, a2
76 ; RV32I-NEXT: mulh a1, a1, a2
79 ; RV32XTHEADBA-LABEL: th_addsl_2_extra_sext:
80 ; RV32XTHEADBA: # %bb.0:
81 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
82 ; RV32XTHEADBA-NEXT: sll a1, a2, a0
83 ; RV32XTHEADBA-NEXT: srai a2, a0, 2
84 ; RV32XTHEADBA-NEXT: mul a0, a1, a2
85 ; RV32XTHEADBA-NEXT: mulh a1, a1, a2
86 ; RV32XTHEADBA-NEXT: ret
91 %e = sext i32 %c to i64
92 %f = sext i32 %d to i64
97 define i32 @addmul6(i32 %a, i32 %b) {
98 ; RV32I-LABEL: addmul6:
100 ; RV32I-NEXT: slli a2, a0, 1
101 ; RV32I-NEXT: slli a0, a0, 3
102 ; RV32I-NEXT: sub a0, a0, a2
103 ; RV32I-NEXT: add a0, a0, a1
106 ; RV32XTHEADBA-LABEL: addmul6:
107 ; RV32XTHEADBA: # %bb.0:
108 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
109 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 1
110 ; RV32XTHEADBA-NEXT: ret
116 define i32 @addmul10(i32 %a, i32 %b) {
117 ; RV32I-LABEL: addmul10:
119 ; RV32I-NEXT: li a2, 10
120 ; RV32I-NEXT: mul a0, a0, a2
121 ; RV32I-NEXT: add a0, a0, a1
124 ; RV32XTHEADBA-LABEL: addmul10:
125 ; RV32XTHEADBA: # %bb.0:
126 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
127 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 1
128 ; RV32XTHEADBA-NEXT: ret
134 define i32 @addmul12(i32 %a, i32 %b) {
135 ; RV32I-LABEL: addmul12:
137 ; RV32I-NEXT: slli a2, a0, 2
138 ; RV32I-NEXT: slli a0, a0, 4
139 ; RV32I-NEXT: sub a0, a0, a2
140 ; RV32I-NEXT: add a0, a0, a1
143 ; RV32XTHEADBA-LABEL: addmul12:
144 ; RV32XTHEADBA: # %bb.0:
145 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
146 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
147 ; RV32XTHEADBA-NEXT: ret
153 define i32 @addmul18(i32 %a, i32 %b) {
154 ; RV32I-LABEL: addmul18:
156 ; RV32I-NEXT: li a2, 18
157 ; RV32I-NEXT: mul a0, a0, a2
158 ; RV32I-NEXT: add a0, a0, a1
161 ; RV32XTHEADBA-LABEL: addmul18:
162 ; RV32XTHEADBA: # %bb.0:
163 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
164 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 1
165 ; RV32XTHEADBA-NEXT: ret
171 define i32 @addmul20(i32 %a, i32 %b) {
172 ; RV32I-LABEL: addmul20:
174 ; RV32I-NEXT: li a2, 20
175 ; RV32I-NEXT: mul a0, a0, a2
176 ; RV32I-NEXT: add a0, a0, a1
179 ; RV32XTHEADBA-LABEL: addmul20:
180 ; RV32XTHEADBA: # %bb.0:
181 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
182 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
183 ; RV32XTHEADBA-NEXT: ret
189 define i32 @addmul24(i32 %a, i32 %b) {
190 ; RV32I-LABEL: addmul24:
192 ; RV32I-NEXT: slli a2, a0, 3
193 ; RV32I-NEXT: slli a0, a0, 5
194 ; RV32I-NEXT: sub a0, a0, a2
195 ; RV32I-NEXT: add a0, a0, a1
198 ; RV32XTHEADBA-LABEL: addmul24:
199 ; RV32XTHEADBA: # %bb.0:
200 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
201 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 3
202 ; RV32XTHEADBA-NEXT: ret
208 define i32 @addmul36(i32 %a, i32 %b) {
209 ; RV32I-LABEL: addmul36:
211 ; RV32I-NEXT: li a2, 36
212 ; RV32I-NEXT: mul a0, a0, a2
213 ; RV32I-NEXT: add a0, a0, a1
216 ; RV32XTHEADBA-LABEL: addmul36:
217 ; RV32XTHEADBA: # %bb.0:
218 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
219 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
220 ; RV32XTHEADBA-NEXT: ret
226 define i32 @addmul40(i32 %a, i32 %b) {
227 ; RV32I-LABEL: addmul40:
229 ; RV32I-NEXT: li a2, 40
230 ; RV32I-NEXT: mul a0, a0, a2
231 ; RV32I-NEXT: add a0, a0, a1
234 ; RV32XTHEADBA-LABEL: addmul40:
235 ; RV32XTHEADBA: # %bb.0:
236 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
237 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 3
238 ; RV32XTHEADBA-NEXT: ret
244 define i32 @addmul72(i32 %a, i32 %b) {
245 ; RV32I-LABEL: addmul72:
247 ; RV32I-NEXT: li a2, 72
248 ; RV32I-NEXT: mul a0, a0, a2
249 ; RV32I-NEXT: add a0, a0, a1
252 ; RV32XTHEADBA-LABEL: addmul72:
253 ; RV32XTHEADBA: # %bb.0:
254 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
255 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 3
256 ; RV32XTHEADBA-NEXT: ret
262 define i32 @mul96(i32 %a) {
263 ; RV32I-LABEL: mul96:
265 ; RV32I-NEXT: slli a1, a0, 5
266 ; RV32I-NEXT: slli a0, a0, 7
267 ; RV32I-NEXT: sub a0, a0, a1
270 ; RV32XTHEADBA-LABEL: mul96:
271 ; RV32XTHEADBA: # %bb.0:
272 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
273 ; RV32XTHEADBA-NEXT: slli a0, a0, 5
274 ; RV32XTHEADBA-NEXT: ret
279 define i32 @mul160(i32 %a) {
280 ; RV32I-LABEL: mul160:
282 ; RV32I-NEXT: li a1, 160
283 ; RV32I-NEXT: mul a0, a0, a1
286 ; RV32XTHEADBA-LABEL: mul160:
287 ; RV32XTHEADBA: # %bb.0:
288 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
289 ; RV32XTHEADBA-NEXT: slli a0, a0, 5
290 ; RV32XTHEADBA-NEXT: ret
295 define i32 @mul200(i32 %a) {
296 ; RV32I-LABEL: mul200:
298 ; RV32I-NEXT: li a1, 200
299 ; RV32I-NEXT: mul a0, a0, a1
302 ; RV32XTHEADBA-LABEL: mul200:
303 ; RV32XTHEADBA: # %bb.0:
304 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
305 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
306 ; RV32XTHEADBA-NEXT: slli a0, a0, 3
307 ; RV32XTHEADBA-NEXT: ret
312 define i32 @mul288(i32 %a) {
313 ; RV32I-LABEL: mul288:
315 ; RV32I-NEXT: li a1, 288
316 ; RV32I-NEXT: mul a0, a0, a1
319 ; RV32XTHEADBA-LABEL: mul288:
320 ; RV32XTHEADBA: # %bb.0:
321 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
322 ; RV32XTHEADBA-NEXT: slli a0, a0, 5
323 ; RV32XTHEADBA-NEXT: ret