mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
[DAG] Commute shuffle(splat(A,u), shuffle(C,D)) -> shuffle'(shuffle(C,D), splat(A,u))
We only merge shuffles if the inner (LHS) shuffle is a non-splat, so commute these shuffles to improve merging of multiple shuffles.
This commit is contained in:
parent
ffe72f987f
commit
5dbe5d2c91
@ -20799,26 +20799,35 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
|
||||
}
|
||||
}
|
||||
|
||||
// Canonicalize shuffles according to rules:
|
||||
// shuffle(A, shuffle(A, B)) -> shuffle(shuffle(A,B), A)
|
||||
// shuffle(B, shuffle(A, B)) -> shuffle(shuffle(A,B), B)
|
||||
// shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B)
|
||||
if (N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
|
||||
N0.getOpcode() != ISD::VECTOR_SHUFFLE && Level < AfterLegalizeDAG &&
|
||||
TLI.isTypeLegal(VT)) {
|
||||
// The incoming shuffle must be of the same type as the result of the
|
||||
// current shuffle.
|
||||
assert(N1->getOperand(0).getValueType() == VT &&
|
||||
"Shuffle types don't match");
|
||||
if (Level < AfterLegalizeDAG && TLI.isTypeLegal(VT)) {
|
||||
// Canonicalize shuffles according to rules:
|
||||
// shuffle(A, shuffle(A, B)) -> shuffle(shuffle(A,B), A)
|
||||
// shuffle(B, shuffle(A, B)) -> shuffle(shuffle(A,B), B)
|
||||
// shuffle(B, shuffle(A, Undef)) -> shuffle(shuffle(A, Undef), B)
|
||||
if (N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
|
||||
N0.getOpcode() != ISD::VECTOR_SHUFFLE) {
|
||||
// The incoming shuffle must be of the same type as the result of the
|
||||
// current shuffle.
|
||||
assert(N1->getOperand(0).getValueType() == VT &&
|
||||
"Shuffle types don't match");
|
||||
|
||||
SDValue SV0 = N1->getOperand(0);
|
||||
SDValue SV1 = N1->getOperand(1);
|
||||
bool HasSameOp0 = N0 == SV0;
|
||||
bool IsSV1Undef = SV1.isUndef();
|
||||
if (HasSameOp0 || IsSV1Undef || N0 == SV1)
|
||||
// Commute the operands of this shuffle so that next rule
|
||||
// will trigger.
|
||||
SDValue SV0 = N1->getOperand(0);
|
||||
SDValue SV1 = N1->getOperand(1);
|
||||
bool HasSameOp0 = N0 == SV0;
|
||||
bool IsSV1Undef = SV1.isUndef();
|
||||
if (HasSameOp0 || IsSV1Undef || N0 == SV1)
|
||||
// Commute the operands of this shuffle so merging below will trigger.
|
||||
return DAG.getCommutedVectorShuffle(*SVN);
|
||||
}
|
||||
|
||||
// Canonicalize splat shuffles to the RHS to improve merging below.
|
||||
// shuffle(splat(A,u), shuffle(C,D)) -> shuffle'(shuffle(C,D), splat(A,u))
|
||||
if (N0.getOpcode() == ISD::VECTOR_SHUFFLE &&
|
||||
N1.getOpcode() == ISD::VECTOR_SHUFFLE &&
|
||||
cast<ShuffleVectorSDNode>(N0)->isSplat() &&
|
||||
!cast<ShuffleVectorSDNode>(N1)->isSplat()) {
|
||||
return DAG.getCommutedVectorShuffle(*SVN);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the combined shuffle mask for a shuffle with SV0 as the first
|
||||
|
@ -583,17 +583,11 @@ define <4 x float> @add_ps_016(<4 x float> %0, <4 x float> %1) {
|
||||
; SSE-NEXT: movaps %xmm1, %xmm0
|
||||
; SSE-NEXT: retq
|
||||
;
|
||||
; AVX-SLOW-LABEL: add_ps_016:
|
||||
; AVX-SLOW: # %bb.0:
|
||||
; AVX-SLOW-NEXT: vhaddps %xmm0, %xmm1, %xmm0
|
||||
; AVX-SLOW-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[1,0,3,3]
|
||||
; AVX-SLOW-NEXT: retq
|
||||
;
|
||||
; AVX-FAST-LABEL: add_ps_016:
|
||||
; AVX-FAST: # %bb.0:
|
||||
; AVX-FAST-NEXT: vhaddps %xmm0, %xmm1, %xmm0
|
||||
; AVX-FAST-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[1,0,3,1]
|
||||
; AVX-FAST-NEXT: retq
|
||||
; AVX-LABEL: add_ps_016:
|
||||
; AVX: # %bb.0:
|
||||
; AVX-NEXT: vhaddps %xmm0, %xmm1, %xmm0
|
||||
; AVX-NEXT: vpermilps {{.*#+}} xmm0 = xmm0[1,0,3,3]
|
||||
; AVX-NEXT: retq
|
||||
%3 = shufflevector <4 x float> %1, <4 x float> %0, <2 x i32> <i32 0, i32 6>
|
||||
%4 = shufflevector <4 x float> %1, <4 x float> %0, <2 x i32> <i32 1, i32 7>
|
||||
%5 = fadd <2 x float> %3, %4
|
||||
|
Loading…
Reference in New Issue
Block a user