1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv7m -mattr=+dsp %s -o - | FileCheck %s --check-prefix=DSP
3 ; RUN: llc -mtriple=armv7a %s -o - | FileCheck %s --check-prefix=ARM7
4 ; RUN: llc -mtriple=thumbv7m -mattr=-dsp %s -o - | FileCheck %s --check-prefix=NODSP
6 define hidden i32 @SMMULR_SMMLAR(i32 %a, i32 %b0, i32 %b1, i32 %Xn, i32 %Xn1) local_unnamed_addr {
7 ; DSP-LABEL: SMMULR_SMMLAR:
8 ; DSP: @ %bb.0: @ %entry
9 ; DSP-NEXT: ldr r0, [sp]
10 ; DSP-NEXT: smmulr r0, r0, r2
11 ; DSP-NEXT: smmlar r0, r3, r1, r0
14 ; ARM7-LABEL: SMMULR_SMMLAR:
15 ; ARM7: @ %bb.0: @ %entry
16 ; ARM7-NEXT: ldr r0, [sp]
17 ; ARM7-NEXT: smmulr r0, r0, r2
18 ; ARM7-NEXT: smmlar r0, r3, r1, r0
21 ; NODSP-LABEL: SMMULR_SMMLAR:
22 ; NODSP: @ %bb.0: @ %entry
23 ; NODSP-NEXT: push {r4, lr}
24 ; NODSP-NEXT: ldr.w lr, [sp, #8]
25 ; NODSP-NEXT: movs r0, #0
26 ; NODSP-NEXT: mov.w r4, #-2147483648
27 ; NODSP-NEXT: mov.w r12, #-2147483648
28 ; NODSP-NEXT: smlal r4, r0, lr, r2
29 ; NODSP-NEXT: smlal r12, r0, r3, r1
30 ; NODSP-NEXT: pop {r4, pc}
32 %conv = sext i32 %b1 to i64
33 %conv1 = sext i32 %Xn1 to i64
34 %mul = mul nsw i64 %conv1, %conv
35 %add = add nsw i64 %mul, 2147483648
36 %0 = and i64 %add, -4294967296
37 %conv4 = sext i32 %b0 to i64
38 %conv5 = sext i32 %Xn to i64
39 %mul6 = mul nsw i64 %conv5, %conv4
40 %add7 = add i64 %mul6, 2147483648
41 %add8 = add i64 %add7, %0
42 %1 = lshr i64 %add8, 32
43 %conv10 = trunc i64 %1 to i32
47 define hidden i32 @SMMULR(i32 %a, i32 %b) local_unnamed_addr {
49 ; DSP: @ %bb.0: @ %entry
50 ; DSP-NEXT: smmulr r0, r1, r0
54 ; ARM7: @ %bb.0: @ %entry
55 ; ARM7-NEXT: smmulr r0, r1, r0
58 ; NODSP-LABEL: SMMULR:
59 ; NODSP: @ %bb.0: @ %entry
60 ; NODSP-NEXT: movs r2, #0
61 ; NODSP-NEXT: mov.w r3, #-2147483648
62 ; NODSP-NEXT: smlal r3, r2, r1, r0
63 ; NODSP-NEXT: mov r0, r2
66 %conv = sext i32 %a to i64
67 %conv1 = sext i32 %b to i64
68 %mul = mul nsw i64 %conv1, %conv
69 %add = add nsw i64 %mul, 2147483648
70 %0 = lshr i64 %add, 32
71 %conv2 = trunc i64 %0 to i32
75 define hidden i32 @SMMUL(i32 %a, i32 %b) local_unnamed_addr {
77 ; DSP: @ %bb.0: @ %entry
78 ; DSP-NEXT: smmul r0, r1, r0
82 ; ARM7: @ %bb.0: @ %entry
83 ; ARM7-NEXT: smmul r0, r1, r0
87 ; NODSP: @ %bb.0: @ %entry
88 ; NODSP-NEXT: smull r1, r0, r1, r0
91 %conv = sext i32 %a to i64
92 %conv1 = sext i32 %b to i64
93 %mul = mul nsw i64 %conv1, %conv
94 %0 = lshr i64 %mul, 32
95 %conv2 = trunc i64 %0 to i32
99 define hidden i32 @SMMLSR(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
101 ; DSP: @ %bb.0: @ %entry
102 ; DSP-NEXT: smmlsr r0, r2, r1, r0
105 ; ARM7-LABEL: SMMLSR:
106 ; ARM7: @ %bb.0: @ %entry
107 ; ARM7-NEXT: smmlsr r0, r2, r1, r0
110 ; NODSP-LABEL: SMMLSR:
111 ; NODSP: @ %bb.0: @ %entry
112 ; NODSP-NEXT: smull r1, r2, r2, r1
113 ; NODSP-NEXT: rsbs.w r1, r1, #-2147483648
114 ; NODSP-NEXT: sbcs r0, r2
117 %conv6 = zext i32 %a to i64
118 %shl = shl nuw i64 %conv6, 32
119 %conv1 = sext i32 %b to i64
120 %conv2 = sext i32 %c to i64
121 %mul = mul nsw i64 %conv2, %conv1
122 %sub = or i64 %shl, 2147483648
123 %add = sub i64 %sub, %mul
124 %0 = lshr i64 %add, 32
125 %conv3 = trunc i64 %0 to i32
129 define hidden i32 @NOT_SMMLSR(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
130 ; DSP-LABEL: NOT_SMMLSR:
131 ; DSP: @ %bb.0: @ %entry
132 ; DSP-NEXT: smmulr r1, r2, r1
133 ; DSP-NEXT: subs r0, r0, r1
136 ; ARM7-LABEL: NOT_SMMLSR:
137 ; ARM7: @ %bb.0: @ %entry
138 ; ARM7-NEXT: smmulr r1, r2, r1
139 ; ARM7-NEXT: sub r0, r0, r1
142 ; NODSP-LABEL: NOT_SMMLSR:
143 ; NODSP: @ %bb.0: @ %entry
144 ; NODSP-NEXT: mov.w r12, #0
145 ; NODSP-NEXT: mov.w r3, #-2147483648
146 ; NODSP-NEXT: smlal r3, r12, r2, r1
147 ; NODSP-NEXT: sub.w r0, r0, r12
150 %conv = sext i32 %b to i64
151 %conv1 = sext i32 %c to i64
152 %mul = mul nsw i64 %conv1, %conv
153 %add = add nsw i64 %mul, 2147483648
154 %0 = lshr i64 %add, 32
155 %conv2 = trunc i64 %0 to i32
156 %sub = sub nsw i32 %a, %conv2
160 define hidden i32 @SMMLS(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
162 ; DSP: @ %bb.0: @ %entry
163 ; DSP-NEXT: smmls r0, r2, r1, r0
167 ; ARM7: @ %bb.0: @ %entry
168 ; ARM7-NEXT: smmls r0, r2, r1, r0
171 ; NODSP-LABEL: SMMLS:
172 ; NODSP: @ %bb.0: @ %entry
173 ; NODSP-NEXT: smull r1, r2, r2, r1
174 ; NODSP-NEXT: rsbs r1, r1, #0
175 ; NODSP-NEXT: sbcs r0, r2
178 %conv5 = zext i32 %a to i64
179 %shl = shl nuw i64 %conv5, 32
180 %conv1 = sext i32 %b to i64
181 %conv2 = sext i32 %c to i64
182 %mul = mul nsw i64 %conv2, %conv1
183 %sub = sub nsw i64 %shl, %mul
184 %0 = lshr i64 %sub, 32
185 %conv3 = trunc i64 %0 to i32
189 define hidden i32 @NOT_SMMLS(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
190 ; DSP-LABEL: NOT_SMMLS:
191 ; DSP: @ %bb.0: @ %entry
192 ; DSP-NEXT: smmul r1, r2, r1
193 ; DSP-NEXT: subs r0, r0, r1
196 ; ARM7-LABEL: NOT_SMMLS:
197 ; ARM7: @ %bb.0: @ %entry
198 ; ARM7-NEXT: smmul r1, r2, r1
199 ; ARM7-NEXT: sub r0, r0, r1
202 ; NODSP-LABEL: NOT_SMMLS:
203 ; NODSP: @ %bb.0: @ %entry
204 ; NODSP-NEXT: smull r1, r2, r2, r1
205 ; NODSP-NEXT: subs r0, r0, r2
208 %conv = sext i32 %b to i64
209 %conv1 = sext i32 %c to i64
210 %mul = mul nsw i64 %conv1, %conv
211 %0 = lshr i64 %mul, 32
212 %conv2 = trunc i64 %0 to i32
213 %sub = sub nsw i32 %a, %conv2
217 define hidden i32 @SMMLA(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
219 ; DSP: @ %bb.0: @ %entry
220 ; DSP-NEXT: smmla r0, r1, r2, r0
224 ; ARM7: @ %bb.0: @ %entry
225 ; ARM7-NEXT: smmla r0, r2, r1, r0
228 ; NODSP-LABEL: SMMLA:
229 ; NODSP: @ %bb.0: @ %entry
230 ; NODSP-NEXT: smull r1, r2, r2, r1
231 ; NODSP-NEXT: add r0, r2
234 %conv = sext i32 %b to i64
235 %conv1 = sext i32 %c to i64
236 %mul = mul nsw i64 %conv1, %conv
237 %0 = lshr i64 %mul, 32
238 %conv2 = trunc i64 %0 to i32
239 %add = add nsw i32 %conv2, %a
243 define hidden i32 @SMMLAR(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
245 ; DSP: @ %bb.0: @ %entry
246 ; DSP-NEXT: smmlar r0, r2, r1, r0
249 ; ARM7-LABEL: SMMLAR:
250 ; ARM7: @ %bb.0: @ %entry
251 ; ARM7-NEXT: smmlar r0, r2, r1, r0
254 ; NODSP-LABEL: SMMLAR:
255 ; NODSP: @ %bb.0: @ %entry
256 ; NODSP-NEXT: mov.w r3, #-2147483648
257 ; NODSP-NEXT: smlal r3, r0, r2, r1
260 %conv7 = zext i32 %a to i64
261 %shl = shl nuw i64 %conv7, 32
262 %conv1 = sext i32 %b to i64
263 %conv2 = sext i32 %c to i64
264 %mul = mul nsw i64 %conv2, %conv1
265 %add = or i64 %shl, 2147483648
266 %add3 = add i64 %add, %mul
267 %0 = lshr i64 %add3, 32
268 %conv4 = trunc i64 %0 to i32
272 define hidden i32 @NOT_SMMLA(i32 %a, i32 %b, i32 %c) local_unnamed_addr {
273 ; DSP-LABEL: NOT_SMMLA:
274 ; DSP: @ %bb.0: @ %entry
275 ; DSP-NEXT: smmul r1, r2, r1
276 ; DSP-NEXT: eor r1, r1, #-2147483648
277 ; DSP-NEXT: add r0, r1
280 ; ARM7-LABEL: NOT_SMMLA:
281 ; ARM7: @ %bb.0: @ %entry
282 ; ARM7-NEXT: smmul r1, r2, r1
283 ; ARM7-NEXT: eor r1, r1, #-2147483648
284 ; ARM7-NEXT: add r0, r1, r0
287 ; NODSP-LABEL: NOT_SMMLA:
288 ; NODSP: @ %bb.0: @ %entry
289 ; NODSP-NEXT: smull r1, r2, r2, r1
290 ; NODSP-NEXT: eor r1, r2, #-2147483648
291 ; NODSP-NEXT: add r0, r1
294 %conv = sext i32 %b to i64
295 %conv1 = sext i32 %c to i64
296 %mul = mul nsw i64 %conv1, %conv
297 %0 = lshr i64 %mul, 32
298 %conv2 = trunc i64 %0 to i32
299 %add = xor i32 %conv2, -2147483648
300 %add3 = add i32 %add, %a