Skip to content

Commit fc12fc6

Browse files
authored
[SystemZ] Fix code in widening vector multiplication (#150836)
Commit cdc7864 has an error which would wrongly fold widening multiplications into an even/odd widening operation. This PR fixes it and adds tests to check scenarios which should not be folded into an even/odd widening operation are actually not.
1 parent 03e54a1 commit fc12fc6

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9044,7 +9044,7 @@ static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG,
90449044
if (unsigned(ShuffleMask[Elt]) != 2 * Elt)
90459045
CanUseEven = false;
90469046
if (unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9047-
CanUseEven = true;
9047+
CanUseOdd = false;
90489048
}
90499049
Op = Op.getOperand(0);
90509050
if (CanUseEven)

llvm/test/CodeGen/SystemZ/vec-mul-07.ll

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
;
44
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
55

6+
; Test a v16i8 -> v8i16 unsigned widening multiplication
7+
; which is not folded into an even/odd widening operation.
8+
define <8 x i16> @f1_not(<16 x i8> %val1, <16 x i8> %val2) {
9+
; CHECK-LABEL: f1_not:
10+
; CHECK: # %bb.0:
11+
; CHECK-NEXT: vuplhb %v0, %v24
12+
; CHECK-NEXT: vuplhb %v1, %v26
13+
; CHECK-NEXT: vmlhw %v24, %v0, %v1
14+
; CHECK-NEXT: br %r14
15+
%shuf1 = shufflevector <16 x i8> %val1, <16 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
16+
%zext1 = zext <8 x i8> %shuf1 to <8 x i16>
17+
%shuf2 = shufflevector <16 x i8> %val2, <16 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
18+
%zext2 = zext <8 x i8> %shuf2 to <8 x i16>
19+
%ret = mul <8 x i16> %zext1, %zext2
20+
ret <8 x i16> %ret
21+
}
22+
623
; Test a v16i8 (even) -> v8i16 unsigned widening multiplication.
724
define <8 x i16> @f1(<16 x i8> %val1, <16 x i8> %val2) {
825
; CHECK-LABEL: f1:
@@ -31,6 +48,23 @@ define <8 x i16> @f2(<16 x i8> %val1, <16 x i8> %val2) {
3148
ret <8 x i16> %ret
3249
}
3350

51+
; Test a v16i8 -> v8i16 signed widening multiplication
52+
; which is not folded into an even/odd widening operation.
53+
define <8 x i16> @f3_not(<16 x i8> %val1, <16 x i8> %val2) {
54+
; CHECK-LABEL: f3_not:
55+
; CHECK: # %bb.0:
56+
; CHECK-NEXT: vuphb %v0, %v26
57+
; CHECK-NEXT: vuphb %v1, %v24
58+
; CHECK-NEXT: vmlhw %v24, %v1, %v0
59+
; CHECK-NEXT: br %r14
60+
%shuf1 = shufflevector <16 x i8> %val1, <16 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
61+
%sext1 = sext <8 x i8> %shuf1 to <8 x i16>
62+
%shuf2 = shufflevector <16 x i8> %val2, <16 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
63+
%sext2 = sext <8 x i8> %shuf2 to <8 x i16>
64+
%ret = mul <8 x i16> %sext1, %sext2
65+
ret <8 x i16> %ret
66+
}
67+
3468
; Test a v16i8 (even) -> v8i16 signed widening multiplication.
3569
define <8 x i16> @f3(<16 x i8> %val1, <16 x i8> %val2) {
3670
; CHECK-LABEL: f3:
@@ -59,6 +93,23 @@ define <8 x i16> @f4(<16 x i8> %val1, <16 x i8> %val2) {
5993
ret <8 x i16> %ret
6094
}
6195

96+
; Test a v8i16 -> v4i32 unsigned widening multiplication
97+
; which is not folded into an even/odd widening operation.
98+
define <4 x i32> @f5_not(<8 x i16> %val1, <8 x i16> %val2) {
99+
; CHECK-LABEL: f5_not:
100+
; CHECK: # %bb.0:
101+
; CHECK-NEXT: vuplhh %v0, %v24
102+
; CHECK-NEXT: vuplhh %v1, %v26
103+
; CHECK-NEXT: vmlf %v24, %v0, %v1
104+
; CHECK-NEXT: br %r14
105+
%shuf1 = shufflevector <8 x i16> %val1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
106+
%zext1 = zext <4 x i16> %shuf1 to <4 x i32>
107+
%shuf2 = shufflevector <8 x i16> %val2, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
108+
%zext2 = zext <4 x i16> %shuf2 to <4 x i32>
109+
%ret = mul <4 x i32> %zext1, %zext2
110+
ret <4 x i32> %ret
111+
}
112+
62113
; Test a v8i16 (even) -> v4i32 unsigned widening multiplication.
63114
define <4 x i32> @f5(<8 x i16> %val1, <8 x i16> %val2) {
64115
; CHECK-LABEL: f5:
@@ -87,6 +138,23 @@ define <4 x i32> @f6(<8 x i16> %val1, <8 x i16> %val2) {
87138
ret <4 x i32> %ret
88139
}
89140

141+
; Test a v8i16 -> v4i32 signed widening multiplication
142+
; which is not folded into an even/odd widening operation.
143+
define <4 x i32> @f7_not(<8 x i16> %val1, <8 x i16> %val2) {
144+
; CHECK-LABEL: f7_not:
145+
; CHECK: # %bb.0:
146+
; CHECK-NEXT: vuphh %v0, %v26
147+
; CHECK-NEXT: vuphh %v1, %v24
148+
; CHECK-NEXT: vmlf %v24, %v1, %v0
149+
; CHECK-NEXT: br %r14
150+
%shuf1 = shufflevector <8 x i16> %val1, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
151+
%sext1 = sext <4 x i16> %shuf1 to <4 x i32>
152+
%shuf2 = shufflevector <8 x i16> %val2, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
153+
%sext2 = sext <4 x i16> %shuf2 to <4 x i32>
154+
%ret = mul <4 x i32> %sext1, %sext2
155+
ret <4 x i32> %ret
156+
}
157+
90158
; Test a v8i16 (even) -> v4i32 signed widening multiplication.
91159
define <4 x i32> @f7(<8 x i16> %val1, <8 x i16> %val2) {
92160
; CHECK-LABEL: f7:
@@ -115,6 +183,29 @@ define <4 x i32> @f8(<8 x i16> %val1, <8 x i16> %val2) {
115183
ret <4 x i32> %ret
116184
}
117185

186+
; Test a v4i32 -> v2i64 unsigned widening multiplication
187+
; which is not folded into an even/odd widening operation.
188+
define <2 x i64> @f9_not(<4 x i32> %val1, <4 x i32> %val2) {
189+
; CHECK-LABEL: f9_not:
190+
; CHECK: # %bb.0:
191+
; CHECK-NEXT: vuplhf %v0, %v24
192+
; CHECK-NEXT: vuplhf %v1, %v26
193+
; CHECK-NEXT: vlgvg %r0, %v1, 1
194+
; CHECK-NEXT: vlgvg %r1, %v0, 1
195+
; CHECK-NEXT: msgr %r1, %r0
196+
; CHECK-NEXT: vlgvg %r0, %v1, 0
197+
; CHECK-NEXT: vlgvg %r2, %v0, 0
198+
; CHECK-NEXT: msgr %r2, %r0
199+
; CHECK-NEXT: vlvgp %v24, %r2, %r1
200+
; CHECK-NEXT: br %r14
201+
%shuf1 = shufflevector <4 x i32> %val1, <4 x i32> poison, <2 x i32> <i32 0, i32 1>
202+
%zext1 = zext <2 x i32> %shuf1 to <2 x i64>
203+
%shuf2 = shufflevector <4 x i32> %val2, <4 x i32> poison, <2 x i32> <i32 0, i32 1>
204+
%zext2 = zext <2 x i32> %shuf2 to <2 x i64>
205+
%ret = mul <2 x i64> %zext1, %zext2
206+
ret <2 x i64> %ret
207+
}
208+
118209
; Test a v4i32 (even) -> v2i64 unsigned widening multiplication.
119210
define <2 x i64> @f9(<4 x i32> %val1, <4 x i32> %val2) {
120211
; CHECK-LABEL: f9:
@@ -143,6 +234,29 @@ define <2 x i64> @f10(<4 x i32> %val1, <4 x i32> %val2) {
143234
ret <2 x i64> %ret
144235
}
145236

237+
; Test a v4i32 -> v2i64 signed widening multiplication
238+
; which is not folded into an even/odd widening operation.
239+
define <2 x i64> @f11_not(<4 x i32> %val1, <4 x i32> %val2) {
240+
; CHECK-LABEL: f11_not:
241+
; CHECK: # %bb.0:
242+
; CHECK-NEXT: vuphf %v0, %v24
243+
; CHECK-NEXT: vuphf %v1, %v26
244+
; CHECK-NEXT: vlgvg %r0, %v1, 1
245+
; CHECK-NEXT: vlgvg %r1, %v0, 1
246+
; CHECK-NEXT: msgr %r1, %r0
247+
; CHECK-NEXT: vlgvg %r0, %v1, 0
248+
; CHECK-NEXT: vlgvg %r2, %v0, 0
249+
; CHECK-NEXT: msgr %r2, %r0
250+
; CHECK-NEXT: vlvgp %v24, %r2, %r1
251+
; CHECK-NEXT: br %r14
252+
%shuf1 = shufflevector <4 x i32> %val1, <4 x i32> poison, <2 x i32> <i32 0, i32 1>
253+
%sext1 = sext <2 x i32> %shuf1 to <2 x i64>
254+
%shuf2 = shufflevector <4 x i32> %val2, <4 x i32> poison, <2 x i32> <i32 0, i32 1>
255+
%sext2 = sext <2 x i32> %shuf2 to <2 x i64>
256+
%ret = mul <2 x i64> %sext1, %sext2
257+
ret <2 x i64> %ret
258+
}
259+
146260
; Test a v4i32 (even) -> v2i64 signed widening multiplication.
147261
define <2 x i64> @f11(<4 x i32> %val1, <4 x i32> %val2) {
148262
; CHECK-LABEL: f11:

0 commit comments

Comments
 (0)