mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
[DAGCombiner] Improved target independent vector shuffle combine rule.
This patch improves the existing algorithm in DAGCombiner that attempts to fold shuffles according to rule: shuffle(shuffle(x, y, M1), undef, M2) -> shuffle(y, undef, M3) Before this change, there were cases where the DAGCombiner conservatively avoided folding shuffles even if the resulting mask would have been legal. That is because the algorithm wrongly assumed that commuting an illegal shuffle mask would always produce an illegal mask. With this change, we now correctly compute the commuted shuffle mask before calling method 'isShuffleMaskLegal' on it. On X86, this improves for example the codegen for the following function: define <4 x i32> @test(<4 x i32> %A, <4 x i32> %B) { %1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7> %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3> ret <4 x i32> %2 } Before this change the X86 backend (-mcpu=corei7) generated the following assembly code for function @test: shufps $-23, %xmm0, %xmm1 # xmm1 = xmm1[1,2],xmm0[2,3] movhlps %xmm1, %xmm1 # xmm1 = xmm1[1,1] movaps %xmm1, %xmm0 Now we produce: movhlps %xmm0, %xmm0 # xmm0 = xmm0[1,1] Added extra test cases in combine-vec-shuffle-2.ll to verify that we correctly fold according to the above-mentioned rule. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215555 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
48017d1bcd
commit
05a76eb9f2
@ -10838,16 +10838,30 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
|
||||
|
||||
// It may still be beneficial to combine the two shuffles if the
|
||||
// resulting shuffle is legal.
|
||||
if (TLI.isTypeLegal(VT) && TLI.isShuffleMaskLegal(Mask, VT)) {
|
||||
if (!CommuteOperands)
|
||||
// shuffle(shuffle(x, undef, M1), undef, M2) -> shuffle(x, undef, M3).
|
||||
// shuffle(shuffle(x, y, M1), undef, M2) -> shuffle(x, undef, M3)
|
||||
return DAG.getVectorShuffle(VT, SDLoc(N), N0->getOperand(0), N1,
|
||||
&Mask[0]);
|
||||
|
||||
// shuffle(shuffle(x, y, M1), undef, M2) -> shuffle(undef, y, M3)
|
||||
return DAG.getVectorShuffle(VT, SDLoc(N), N1, N0->getOperand(1),
|
||||
&Mask[0]);
|
||||
if (TLI.isTypeLegal(VT)) {
|
||||
if (!CommuteOperands) {
|
||||
if (TLI.isShuffleMaskLegal(Mask, VT))
|
||||
// shuffle(shuffle(x, undef, M1), undef, M2) -> shuffle(x, undef, M3).
|
||||
// shuffle(shuffle(x, y, M1), undef, M2) -> shuffle(x, undef, M3)
|
||||
return DAG.getVectorShuffle(VT, SDLoc(N), N0->getOperand(0), N1,
|
||||
&Mask[0]);
|
||||
} else {
|
||||
// Compute the commuted shuffle mask.
|
||||
for (unsigned i = 0; i != NumElts; ++i) {
|
||||
int idx = Mask[i];
|
||||
if (idx < 0)
|
||||
continue;
|
||||
else if (idx < (int)NumElts)
|
||||
Mask[i] = idx + NumElts;
|
||||
else
|
||||
Mask[i] = idx - NumElts;
|
||||
}
|
||||
|
||||
if (TLI.isShuffleMaskLegal(Mask, VT))
|
||||
// shuffle(shuffle(x, y, M1), undef, M2) -> shuffle(y, undef, M3)
|
||||
return DAG.getVectorShuffle(VT, SDLoc(N), N0->getOperand(1), N1,
|
||||
&Mask[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,8 @@ define <4 x i32> @test18(<4 x i32> %A, <4 x i32> %B) {
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test18
|
||||
; CHECK: blendps $11
|
||||
; CHECK-NEXT: pshufd $-59
|
||||
; CHECK-NOT: blendps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm1[1,1,0,3]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test19(<4 x i32> %A, <4 x i32> %B) {
|
||||
@ -240,6 +240,8 @@ define <4 x i32> @test21(<4 x i32> %A, <4 x i32> %B) {
|
||||
; CHECK-NEXT: pshufd $-60
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
; Test that we correctly combine shuffles according to rule
|
||||
; shuffle(shuffle(x, y), undef) -> shuffle(y, undef)
|
||||
|
||||
define <4 x i32> @test22(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
|
||||
@ -247,7 +249,69 @@ define <4 x i32> @test22(<4 x i32> %A, <4 x i32> %B) {
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test22
|
||||
; CHECK: blendps $11
|
||||
; CHECK-NEXT: pshufd $-43
|
||||
; CHECK-NOT: blendps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm1[1,1,1,3]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test23(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 5, i32 2, i32 7>
|
||||
%2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 3>
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test23
|
||||
; CHECK-NOT: blendps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm1[0,1,0,3]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test24(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 7>
|
||||
%2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 3, i32 2, i32 4>
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test24
|
||||
; CHECK-NOT: blendps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm1[0,3,2,0]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test25(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 5, i32 2, i32 4>
|
||||
%2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 1, i32 3, i32 1>
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test25
|
||||
; CHECK-NOT: shufps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm0[0,1,0,1]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test26(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 6, i32 7>
|
||||
%2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 2, i32 3>
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test26
|
||||
; CHECK-NOT: shufps
|
||||
; CHECK: movhlps {{.*}} # xmm0 = xmm0[1,1]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test27(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 2, i32 1, i32 5, i32 4>
|
||||
%2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 3, i32 2>
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test27
|
||||
; CHECK-NOT: shufps
|
||||
; CHECK-NOT: movhlps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm0[0,1,0,1]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
define <4 x i32> @test28(<4 x i32> %A, <4 x i32> %B) {
|
||||
%1 = shufflevector <4 x i32> %B, <4 x i32> %A, <4 x i32> <i32 1, i32 2, i32 4, i32 5>
|
||||
%2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 3, i32 2>
|
||||
ret <4 x i32> %2
|
||||
}
|
||||
; CHECK-LABEL: test28
|
||||
; CHECK-NOT: shufps
|
||||
; CHECK-NOT: movhlps
|
||||
; CHECK: pshufd {{.*}} # xmm0 = xmm0[0,1,1,0]
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user