1 ; RUN: llc -march=hexagon < %s | FileCheck %s
2 ; This test checks for the generation of 64b mul instruction
3 ; (dpmpyss_s0 and dpmpyuu_s0).
5 ; Checks for unsigned multiplication.
10 define i64 @f0(i16 zeroext %a0, i16 zeroext %a1) local_unnamed_addr #0 {
12 %v0 = zext i16 %a0 to i64
13 %v1 = zext i16 %a1 to i64
14 %v2 = mul nuw nsw i64 %v1, %v0
21 define i64 @f1(i32 %a0, i32 %a1) local_unnamed_addr #0 {
23 %v0 = zext i32 %a0 to i64
24 %v1 = zext i32 %a1 to i64
25 %v2 = mul nuw nsw i64 %v1, %v0
29 ; Given int w[2], short h[4], signed char c[8], the below tests check for the
30 ; generation of dpmpyuu_s0.
35 define i64 @f2(i64 %a0, i64 %a1) local_unnamed_addr #0 {
37 %v0 = and i64 %a0, 4294967295
38 %v1 = trunc i64 %a1 to i32
40 %v3 = ashr exact i32 %v2, 16
41 %v4 = zext i32 %v3 to i64
42 %v5 = mul nuw i64 %v0, %v4
50 define i64 @f3(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
64 define i64 @f4(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
80 define i64 @f5(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
96 define i64 @f6(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
109 ; CHECK: = and({{.*}}#255)
110 ; CHECK: r1:0 = mpyu(
111 define i64 @f7(i64 %a0, i64 %a1) local_unnamed_addr #0 {
113 %v0 = and i64 %a0, 4294967295
114 %v1 = and i64 %a1, 255
115 %v2 = mul nuw nsw i64 %v1, %v0
122 ; CHECK: r1:0 = mpyu(
123 define i64 @f8(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
135 ; CHECK: r1:0 = mpyu(
136 define i64 @f9(i64 %a0, i64 %a1) local_unnamed_addr #0 {
138 %v0 = and i64 %a0, 4294967295
139 %v1 = lshr i64 %a1, 56
140 %v2 = mul nuw nsw i64 %v1, %v0
145 ; Checks for signed multiplication.
150 define i64 @f10(i16 signext %a0, i16 signext %a1) local_unnamed_addr #0 {
152 %v0 = sext i16 %a0 to i64
153 %v1 = sext i16 %a1 to i64
154 %v2 = mul nsw i64 %v1, %v0
161 define i64 @f11(i32 %a0, i32 %a1) local_unnamed_addr #0 {
163 %v0 = sext i32 %a0 to i64
164 %v1 = sext i32 %a1 to i64
165 %v2 = mul nsw i64 %v1, %v0
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.
175 define i64 @f12(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
189 define i64 @f13(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
204 define i64 @f14(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
221 define i64 @f15(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
234 define i64 @f16(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
248 define i64 @f17(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
262 define i64 @f18(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
279 define i64 @f19(i64 %a0, i64 %a1) local_unnamed_addr #0 {
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
292 attributes #0 = { norecurse nounwind readnone "target-cpu"="hexagonv60" "target-features"="-hvx" }