diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a277d8ebba4db..ee4cdbc1a9400 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -37118,8 +37118,12 @@ static SDValue canonicalizeShuffleWithBinOps(SDValue N, SelectionDAG &DAG, SDValue Op10 = peekThroughOneUseBitcasts(N1.getOperand(0)); SDValue Op01 = peekThroughOneUseBitcasts(N0.getOperand(1)); SDValue Op11 = peekThroughOneUseBitcasts(N1.getOperand(1)); - if ((IsMergeableWithShuffle(Op00) && IsMergeableWithShuffle(Op10)) || - (IsMergeableWithShuffle(Op01) && IsMergeableWithShuffle(Op11))) { + // Ensure the total number of shuffles doesn't increase by folding this + // shuffle through to the source ops. + if (((IsMergeableWithShuffle(Op00) && IsMergeableWithShuffle(Op10)) || + (IsMergeableWithShuffle(Op01) && IsMergeableWithShuffle(Op11))) || + ((IsMergeableWithShuffle(Op00) || IsMergeableWithShuffle(Op10)) && + (IsMergeableWithShuffle(Op01) || IsMergeableWithShuffle(Op11)))) { SDValue LHS, RHS; Op00 = DAG.getBitcast(ShuffleVT, Op00); Op10 = DAG.getBitcast(ShuffleVT, Op10); diff --git a/llvm/test/CodeGen/X86/haddsub-3.ll b/llvm/test/CodeGen/X86/haddsub-3.ll index 3be93b570f84c..7f791fc76ac5f 100644 --- a/llvm/test/CodeGen/X86/haddsub-3.ll +++ b/llvm/test/CodeGen/X86/haddsub-3.ll @@ -131,21 +131,17 @@ define <4 x float> @PR48823(<4 x float> %0, <4 x float> %1) { ; SSE2-LABEL: PR48823: ; SSE2: # %bb.0: ; SSE2-NEXT: movaps %xmm0, %xmm2 -; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[1,1],xmm0[1,1] +; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[1,1],xmm1[2,3] +; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,2] ; SSE2-NEXT: subps %xmm2, %xmm0 -; SSE2-NEXT: movaps %xmm1, %xmm2 -; SSE2-NEXT: shufps {{.*#+}} xmm2 = xmm2[2,2],xmm1[2,2] -; SSE2-NEXT: subps %xmm1, %xmm2 -; SSE2-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3] ; SSE2-NEXT: retq ; ; SSSE3-SLOW-LABEL: PR48823: ; SSSE3-SLOW: # %bb.0: -; SSSE3-SLOW-NEXT: movshdup {{.*#+}} xmm2 = xmm0[1,1,3,3] +; SSSE3-SLOW-NEXT: movaps %xmm0, %xmm2 +; SSSE3-SLOW-NEXT: shufps {{.*#+}} xmm2 = xmm2[1,1],xmm1[2,3] +; SSSE3-SLOW-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,2] ; SSSE3-SLOW-NEXT: subps %xmm2, %xmm0 -; SSSE3-SLOW-NEXT: movsldup {{.*#+}} xmm2 = xmm1[0,0,2,2] -; SSSE3-SLOW-NEXT: subps %xmm1, %xmm2 -; SSSE3-SLOW-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3] ; SSSE3-SLOW-NEXT: retq ; ; SSSE3-FAST-LABEL: PR48823: @@ -155,11 +151,9 @@ define <4 x float> @PR48823(<4 x float> %0, <4 x float> %1) { ; ; AVX1-SLOW-LABEL: PR48823: ; AVX1-SLOW: # %bb.0: -; AVX1-SLOW-NEXT: vmovshdup {{.*#+}} xmm2 = xmm0[1,1,3,3] +; AVX1-SLOW-NEXT: vshufps {{.*#+}} xmm2 = xmm0[1,1],xmm1[2,3] +; AVX1-SLOW-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,2] ; AVX1-SLOW-NEXT: vsubps %xmm2, %xmm0, %xmm0 -; AVX1-SLOW-NEXT: vmovsldup {{.*#+}} xmm2 = xmm1[0,0,2,2] -; AVX1-SLOW-NEXT: vsubps %xmm1, %xmm2, %xmm1 -; AVX1-SLOW-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] ; AVX1-SLOW-NEXT: retq ; ; AVX1-FAST-LABEL: PR48823: @@ -169,11 +163,9 @@ define <4 x float> @PR48823(<4 x float> %0, <4 x float> %1) { ; ; AVX2-LABEL: PR48823: ; AVX2: # %bb.0: -; AVX2-NEXT: vmovshdup {{.*#+}} xmm2 = xmm0[1,1,3,3] +; AVX2-NEXT: vshufps {{.*#+}} xmm2 = xmm0[1,1],xmm1[2,3] +; AVX2-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,2] ; AVX2-NEXT: vsubps %xmm2, %xmm0, %xmm0 -; AVX2-NEXT: vmovsldup {{.*#+}} xmm2 = xmm1[0,0,2,2] -; AVX2-NEXT: vsubps %xmm1, %xmm2, %xmm1 -; AVX2-NEXT: vblendps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3] ; AVX2-NEXT: retq %3 = shufflevector <4 x float> %0, <4 x float> poison, <4 x i32> %4 = fsub <4 x float> %0, %3