xref: /llvm-project/llvm/test/CodeGen/Hexagon/mul64.ll (revision 2208c97c1bec2512d4e47b6223db6d95a7037956)
1; RUN: llc -mtriple=hexagon < %s | FileCheck %s
2; This test checks for the generation of 64b mul instruction
3; (dpmpyss_s0 and dpmpyuu_s0).
4
5; Checks for unsigned multiplication.
6
7; 16 x 16 = 64
8; CHECK-LABEL: f0:
9; CHECK: r1:0 = mpyu(
10define i64 @f0(i16 zeroext %a0, i16 zeroext %a1) local_unnamed_addr #0 {
11b0:
12  %v0 = zext i16 %a0 to i64
13  %v1 = zext i16 %a1 to i64
14  %v2 = mul nuw nsw i64 %v1, %v0
15  ret i64 %v2
16}
17
18; 32 x 32 = 64
19; CHECK-LABEL: f1:
20; CHECK: r1:0 = mpyu(
21define i64 @f1(i32 %a0, i32 %a1) local_unnamed_addr #0 {
22b0:
23  %v0 = zext i32 %a0 to i64
24  %v1 = zext i32 %a1 to i64
25  %v2 = mul nuw nsw i64 %v1, %v0
26  ret i64 %v2
27}
28
29; Given int w[2], short h[4], signed char c[8], the below tests check for the
30; generation of dpmpyuu_s0.
31; wptr h[0]
32; CHECK-LABEL: f2:
33; CHECK: = sxth
34; CHECK: r1:0 = mpyu(
35define i64 @f2(i64 %a0, i64 %a1) local_unnamed_addr #0 {
36b0:
37  %v0 = and i64 %a0, 4294967295
38  %v1 = trunc i64 %a1 to i32
39  %v2 = shl i32 %v1, 16
40  %v3 = ashr exact i32 %v2, 16
41  %v4 = zext i32 %v3 to i64
42  %v5 = mul nuw i64 %v0, %v4
43  ret i64 %v5
44}
45
46; wptr h[1]
47; CHECK-LABEL: f3:
48; CHECK: = asrh
49; CHECK: r1:0 = mpyu(
50define i64 @f3(i64 %a0, i64 %a1) local_unnamed_addr #0 {
51b0:
52  %v0 = and i64 %a0, 4294967295
53  %v1 = trunc i64 %a1 to i32
54  %v2 = ashr i32 %v1, 16
55  %v3 = zext i32 %v2 to i64
56  %v4 = mul nuw i64 %v0, %v3
57  ret i64 %v4
58}
59
60; wptr h[2]
61; CHECK-LABEL: f4:
62; CHECK: = extract(
63; CHECK: r1:0 = mpyu(
64define i64 @f4(i64 %a0, i64 %a1) local_unnamed_addr #0 {
65b0:
66  %v0 = and i64 %a0, 4294967295
67  %v1 = lshr i64 %a1, 32
68  %v2 = shl nuw nsw i64 %v1, 16
69  %v3 = trunc i64 %v2 to i32
70  %v4 = ashr exact i32 %v3, 16
71  %v5 = zext i32 %v4 to i64
72  %v6 = mul nuw i64 %v0, %v5
73  ret i64 %v6
74}
75
76; wptr h[3]
77; CHECK-LABEL: f5:
78; CHECK: = extractu(
79; CHECK: r1:0 = mpyu(
80define i64 @f5(i64 %a0, i64 %a1) local_unnamed_addr #0 {
81b0:
82  %v0 = and i64 %a0, 4294967295
83  %v1 = lshr i64 %a1, 48
84  %v2 = shl nuw nsw i64 %v1, 16
85  %v3 = trunc i64 %v2 to i32
86  %v4 = ashr exact i32 %v3, 16
87  %v5 = zext i32 %v4 to i64
88  %v6 = mul nuw i64 %v0, %v5
89  ret i64 %v6
90}
91
92; wptr h[0]
93; CHECK-LABEL: f6:
94; CHECK: = sxth(
95; CHECK: r1:0 = mpyu(
96define i64 @f6(i64 %a0, i64 %a1) local_unnamed_addr #0 {
97b0:
98  %v0 = lshr i64 %a0, 32
99  %v1 = trunc i64 %a1 to i32
100  %v2 = shl i32 %v1, 16
101  %v3 = ashr exact i32 %v2, 16
102  %v4 = zext i32 %v3 to i64
103  %v5 = mul nuw i64 %v0, %v4
104  ret i64 %v5
105}
106
107; wptr c[0]
108; CHECK-LABEL: f7:
109; CHECK: = and({{.*}}#255)
110; CHECK: r1:0 = mpyu(
111define i64 @f7(i64 %a0, i64 %a1) local_unnamed_addr #0 {
112b0:
113  %v0 = and i64 %a0, 4294967295
114  %v1 = and i64 %a1, 255
115  %v2 = mul nuw nsw i64 %v1, %v0
116  ret i64 %v2
117}
118
119; wptr c[2]
120; CHECK-LABEL: f8:
121; CHECK: = extractu(
122; CHECK: r1:0 = mpyu(
123define i64 @f8(i64 %a0, i64 %a1) local_unnamed_addr #0 {
124b0:
125  %v0 = and i64 %a0, 4294967295
126  %v1 = lshr i64 %a1, 16
127  %v2 = and i64 %v1, 255
128  %v3 = mul nuw nsw i64 %v2, %v0
129  ret i64 %v3
130}
131
132; wptr c[7]
133; CHECK-LABEL: f9:
134; CHECK: = lsr(
135; CHECK: r1:0 = mpyu(
136define i64 @f9(i64 %a0, i64 %a1) local_unnamed_addr #0 {
137b0:
138  %v0 = and i64 %a0, 4294967295
139  %v1 = lshr i64 %a1, 56
140  %v2 = mul nuw nsw i64 %v1, %v0
141  ret i64 %v2
142}
143
144
145; Checks for signed multiplication.
146
147; 16 x 16 = 64
148; CHECK-LABEL: f10:
149; CHECK: r1:0 = mpy(
150define i64 @f10(i16 signext %a0, i16 signext %a1) local_unnamed_addr #0 {
151b0:
152  %v0 = sext i16 %a0 to i64
153  %v1 = sext i16 %a1 to i64
154  %v2 = mul nsw i64 %v1, %v0
155  ret i64 %v2
156}
157
158; 32 x 32 = 64
159; CHECK-LABEL: f11:
160; CHECK: r1:0 = mpy(
161define i64 @f11(i32 %a0, i32 %a1) local_unnamed_addr #0 {
162b0:
163  %v0 = sext i32 %a0 to i64
164  %v1 = sext i32 %a1 to i64
165  %v2 = mul nsw i64 %v1, %v0
166  ret i64 %v2
167}
168
169; Given unsigned int w[2], unsigned short h[4], unsigned char c[8], the below
170; tests check for the generation of dpmpyss_s0.
171; wptr h[0]
172; CHECK-LABEL: f12:
173; CHECK: = sxth
174; CHECK: r1:0 = mpy(
175define i64 @f12(i64 %a0, i64 %a1) local_unnamed_addr #0 {
176b0:
177  %v0 = shl i64 %a0, 32
178  %v1 = ashr exact i64 %v0, 32
179  %v2 = shl i64 %a1, 48
180  %v3 = ashr exact i64 %v2, 48
181  %v4 = mul nsw i64 %v3, %v1
182  ret i64 %v4
183}
184
185; wptr h[1]
186; CHECK-LABEL: f13:
187; CHECK: = asrh
188; CHECK: r1:0 = mpy(
189define i64 @f13(i64 %a0, i64 %a1) local_unnamed_addr #0 {
190b0:
191  %v0 = shl i64 %a0, 32
192  %v1 = ashr exact i64 %v0, 32
193  %v2 = trunc i64 %a1 to i32
194  %v3 = ashr i32 %v2, 16
195  %v4 = sext i32 %v3 to i64
196  %v5 = mul nsw i64 %v1, %v4
197  ret i64 %v5
198}
199
200; wptr h[2]
201; CHECK-LABEL: f14:
202; CHECK: = extract(
203; CHECK: r1:0 = mpy(
204define i64 @f14(i64 %a0, i64 %a1) local_unnamed_addr #0 {
205b0:
206  %v0 = shl i64 %a0, 32
207  %v1 = ashr exact i64 %v0, 32
208  %v2 = lshr i64 %a1, 32
209  %v3 = shl nuw nsw i64 %v2, 16
210  %v4 = trunc i64 %v3 to i32
211  %v5 = ashr exact i32 %v4, 16
212  %v6 = sext i32 %v5 to i64
213  %v7 = mul nsw i64 %v1, %v6
214  ret i64 %v7
215}
216
217; wptr h[3]
218; CHECK-LABEL: f15:
219; CHECK: = sxth(
220; CHECK: r1:0 = mpy(
221define i64 @f15(i64 %a0, i64 %a1) local_unnamed_addr #0 {
222b0:
223  %v0 = ashr i64 %a0, 32
224  %v1 = shl i64 %a1, 48
225  %v2 = ashr exact i64 %v1, 48
226  %v3 = mul nsw i64 %v2, %v0
227  ret i64 %v3
228}
229
230; wptr h[0]
231; CHECK-LABEL: f16:
232; CHECK: = asrh(
233; CHECK: r1:0 = mpy(
234define i64 @f16(i64 %a0, i64 %a1) local_unnamed_addr #0 {
235b0:
236  %v0 = ashr i64 %a0, 32
237  %v1 = trunc i64 %a1 to i32
238  %v2 = ashr i32 %v1, 16
239  %v3 = sext i32 %v2 to i64
240  %v4 = mul nsw i64 %v0, %v3
241  ret i64 %v4
242}
243
244; wptr c[0]
245; CHECK-LABEL: f17:
246; CHECK: = sxtb(
247; CHECK: r1:0 = mpy(
248define i64 @f17(i64 %a0, i64 %a1) local_unnamed_addr #0 {
249b0:
250  %v0 = shl i64 %a0, 32
251  %v1 = ashr exact i64 %v0, 32
252  %v2 = shl i64 %a1, 56
253  %v3 = ashr exact i64 %v2, 56
254  %v4 = mul nsw i64 %v3, %v1
255  ret i64 %v4
256}
257
258; wptr c[2]
259; CHECK-LABEL: f18:
260; CHECK: = extract(
261; CHECK: r1:0 = mpy(
262define i64 @f18(i64 %a0, i64 %a1) local_unnamed_addr #0 {
263b0:
264  %v0 = shl i64 %a0, 32
265  %v1 = ashr exact i64 %v0, 32
266  %v2 = lshr i64 %a1, 16
267  %v3 = shl i64 %v2, 24
268  %v4 = trunc i64 %v3 to i32
269  %v5 = ashr exact i32 %v4, 24
270  %v6 = sext i32 %v5 to i64
271  %v7 = mul nsw i64 %v1, %v6
272  ret i64 %v7
273}
274
275; wptr c[7]
276; CHECK-LABEL: f19:
277; CHECK: = sxtb(
278; CHECK: r1:0 = mpy(
279define i64 @f19(i64 %a0, i64 %a1) local_unnamed_addr #0 {
280b0:
281  %v0 = shl i64 %a0, 32
282  %v1 = ashr exact i64 %v0, 32
283  %v2 = lshr i64 %a1, 56
284  %v3 = shl nuw nsw i64 %v2, 24
285  %v4 = trunc i64 %v3 to i32
286  %v5 = ashr exact i32 %v4, 24
287  %v6 = sext i32 %v5 to i64
288  %v7 = mul nsw i64 %v1, %v6
289  ret i64 %v7
290}
291
292attributes #0 = { norecurse nounwind readnone "target-cpu"="hexagonv60" "target-features"="-hvx" }
293