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: li a2, 6
101 ; RV32I-NEXT: mul a0, a0, a2
102 ; RV32I-NEXT: add a0, a0, a1
105 ; RV32XTHEADBA-LABEL: addmul6:
106 ; RV32XTHEADBA: # %bb.0:
107 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
108 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 1
109 ; RV32XTHEADBA-NEXT: ret
115 define i32 @addmul10(i32 %a, i32 %b) {
116 ; RV32I-LABEL: addmul10:
118 ; RV32I-NEXT: li a2, 10
119 ; RV32I-NEXT: mul a0, a0, a2
120 ; RV32I-NEXT: add a0, a0, a1
123 ; RV32XTHEADBA-LABEL: addmul10:
124 ; RV32XTHEADBA: # %bb.0:
125 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
126 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 1
127 ; RV32XTHEADBA-NEXT: ret
133 define i32 @addmul12(i32 %a, i32 %b) {
134 ; RV32I-LABEL: addmul12:
136 ; RV32I-NEXT: li a2, 12
137 ; RV32I-NEXT: mul a0, a0, a2
138 ; RV32I-NEXT: add a0, a0, a1
141 ; RV32XTHEADBA-LABEL: addmul12:
142 ; RV32XTHEADBA: # %bb.0:
143 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
144 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
145 ; RV32XTHEADBA-NEXT: ret
151 define i32 @addmul18(i32 %a, i32 %b) {
152 ; RV32I-LABEL: addmul18:
154 ; RV32I-NEXT: li a2, 18
155 ; RV32I-NEXT: mul a0, a0, a2
156 ; RV32I-NEXT: add a0, a0, a1
159 ; RV32XTHEADBA-LABEL: addmul18:
160 ; RV32XTHEADBA: # %bb.0:
161 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
162 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 1
163 ; RV32XTHEADBA-NEXT: ret
169 define i32 @addmul20(i32 %a, i32 %b) {
170 ; RV32I-LABEL: addmul20:
172 ; RV32I-NEXT: li a2, 20
173 ; RV32I-NEXT: mul a0, a0, a2
174 ; RV32I-NEXT: add a0, a0, a1
177 ; RV32XTHEADBA-LABEL: addmul20:
178 ; RV32XTHEADBA: # %bb.0:
179 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
180 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
181 ; RV32XTHEADBA-NEXT: ret
187 define i32 @addmul24(i32 %a, i32 %b) {
188 ; RV32I-LABEL: addmul24:
190 ; RV32I-NEXT: li a2, 24
191 ; RV32I-NEXT: mul a0, a0, a2
192 ; RV32I-NEXT: add a0, a0, a1
195 ; RV32XTHEADBA-LABEL: addmul24:
196 ; RV32XTHEADBA: # %bb.0:
197 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
198 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 3
199 ; RV32XTHEADBA-NEXT: ret
205 define i32 @addmul36(i32 %a, i32 %b) {
206 ; RV32I-LABEL: addmul36:
208 ; RV32I-NEXT: li a2, 36
209 ; RV32I-NEXT: mul a0, a0, a2
210 ; RV32I-NEXT: add a0, a0, a1
213 ; RV32XTHEADBA-LABEL: addmul36:
214 ; RV32XTHEADBA: # %bb.0:
215 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
216 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 2
217 ; RV32XTHEADBA-NEXT: ret
223 define i32 @addmul40(i32 %a, i32 %b) {
224 ; RV32I-LABEL: addmul40:
226 ; RV32I-NEXT: li a2, 40
227 ; RV32I-NEXT: mul a0, a0, a2
228 ; RV32I-NEXT: add a0, a0, a1
231 ; RV32XTHEADBA-LABEL: addmul40:
232 ; RV32XTHEADBA: # %bb.0:
233 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
234 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 3
235 ; RV32XTHEADBA-NEXT: ret
241 define i32 @addmul72(i32 %a, i32 %b) {
242 ; RV32I-LABEL: addmul72:
244 ; RV32I-NEXT: li a2, 72
245 ; RV32I-NEXT: mul a0, a0, a2
246 ; RV32I-NEXT: add a0, a0, a1
249 ; RV32XTHEADBA-LABEL: addmul72:
250 ; RV32XTHEADBA: # %bb.0:
251 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
252 ; RV32XTHEADBA-NEXT: th.addsl a0, a1, a0, 3
253 ; RV32XTHEADBA-NEXT: ret
259 define i32 @mul96(i32 %a) {
260 ; RV32I-LABEL: mul96:
262 ; RV32I-NEXT: li a1, 96
263 ; RV32I-NEXT: mul a0, a0, a1
266 ; RV32XTHEADBA-LABEL: mul96:
267 ; RV32XTHEADBA: # %bb.0:
268 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 1
269 ; RV32XTHEADBA-NEXT: slli a0, a0, 5
270 ; RV32XTHEADBA-NEXT: ret
275 define i32 @mul160(i32 %a) {
276 ; RV32I-LABEL: mul160:
278 ; RV32I-NEXT: li a1, 160
279 ; RV32I-NEXT: mul a0, a0, a1
282 ; RV32XTHEADBA-LABEL: mul160:
283 ; RV32XTHEADBA: # %bb.0:
284 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
285 ; RV32XTHEADBA-NEXT: slli a0, a0, 5
286 ; RV32XTHEADBA-NEXT: ret
291 define i32 @mul200(i32 %a) {
292 ; RV32I-LABEL: mul200:
294 ; RV32I-NEXT: li a1, 200
295 ; RV32I-NEXT: mul a0, a0, a1
298 ; RV32XTHEADBA-LABEL: mul200:
299 ; RV32XTHEADBA: # %bb.0:
300 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
301 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 2
302 ; RV32XTHEADBA-NEXT: slli a0, a0, 3
303 ; RV32XTHEADBA-NEXT: ret
308 define i32 @mul288(i32 %a) {
309 ; RV32I-LABEL: mul288:
311 ; RV32I-NEXT: li a1, 288
312 ; RV32I-NEXT: mul a0, a0, a1
315 ; RV32XTHEADBA-LABEL: mul288:
316 ; RV32XTHEADBA: # %bb.0:
317 ; RV32XTHEADBA-NEXT: th.addsl a0, a0, a0, 3
318 ; RV32XTHEADBA-NEXT: slli a0, a0, 5
319 ; RV32XTHEADBA-NEXT: ret