From 1115b2c27ea7eab0fa9fd91e6a3fdd61e33deba0 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 17 Feb 2015 16:54:32 +0000 Subject: [PATCH] Canonicalize splats as build_vectors (PR22283) This is a follow-on patch to: http://reviews.llvm.org/D7093 That patch canonicalized constant splats as build_vectors, and this patch removes the constant check so we can canonicalize all splats as build_vectors. This fixes the 2nd test case in PR22283: http://llvm.org/bugs/show_bug.cgi?id=22283 The unfortunate code duplication between SelectionDAG and DAGCombiner is discussed in the earlier patch review. At least this patch is just removing code... This improves an existing x86 AVX test and changes codegen in an ARM test. Differential Revision: http://reviews.llvm.org/D7389 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229511 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 21 +++++++++------------ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 ++++++++++------------- test/CodeGen/ARM/vdup.ll | 6 +++--- test/CodeGen/X86/vector-shuffle-256-v4.ll | 3 +-- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 92164e92543..69efae738af 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11749,20 +11749,17 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { if (AllSame) return N0; - // If the splatted element is a constant, just build the vector out of - // constants directly. + // Canonicalize any other splat as a build_vector. const SDValue &Splatted = V->getOperand(SVN->getSplatIndex()); - if (isa(Splatted) || isa(Splatted)) { - SmallVector Ops(NumElts, Splatted); - SDValue NewBV = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), - V->getValueType(0), Ops); + SmallVector Ops(NumElts, Splatted); + SDValue NewBV = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), + V->getValueType(0), Ops); - // We may have jumped through bitcasts, so the type of the - // BUILD_VECTOR may not match the type of the shuffle. - if (V->getValueType(0) != VT) - NewBV = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, NewBV); - return NewBV; - } + // We may have jumped through bitcasts, so the type of the + // BUILD_VECTOR may not match the type of the shuffle. + if (V->getValueType(0) != VT) + NewBV = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, NewBV); + return NewBV; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 1e0e196389d..9466f4dd060 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1581,22 +1581,19 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, return N1; } - // If the shuffle itself creates a constant splat, build the vector - // directly. + // If the shuffle itself creates a splat, build the vector directly. if (AllSame && SameNumElts) { - const SDValue &Splatted = BV->getOperand(MaskVec[0]); - if (isa(Splatted) || isa(Splatted)) { - SmallVector Ops(NElts, Splatted); + const SDValue &Splatted = BV->getOperand(MaskVec[0]); + SmallVector Ops(NElts, Splatted); - SDValue NewBV = - getNode(ISD::BUILD_VECTOR, dl, BV->getValueType(0), Ops); + EVT BuildVT = BV->getValueType(0); + SDValue NewBV = getNode(ISD::BUILD_VECTOR, dl, BuildVT, Ops); - // We may have jumped through bitcasts, so the type of the - // BUILD_VECTOR may not match the type of the shuffle. - if (BV->getValueType(0) != VT) - NewBV = getNode(ISD::BITCAST, dl, VT, NewBV); - return NewBV; - } + // We may have jumped through bitcasts, so the type of the + // BUILD_VECTOR may not match the type of the shuffle. + if (BuildVT != VT) + NewBV = getNode(ISD::BITCAST, dl, VT, NewBV); + return NewBV; } } } diff --git a/test/CodeGen/ARM/vdup.ll b/test/CodeGen/ARM/vdup.ll index 89f355c6875..6f8b3dda9cd 100644 --- a/test/CodeGen/ARM/vdup.ll +++ b/test/CodeGen/ARM/vdup.ll @@ -347,17 +347,17 @@ define <2 x float> @check_spr_splat2(<2 x float> %p, i16 %q) { define <4 x float> @check_spr_splat4(<4 x float> %p, i16 %q) { ;CHECK-LABEL: check_spr_splat4: -;CHECK: vdup.32 q +;CHECK: vld1.16 %conv = sitofp i16 %q to float %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 0 %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> zeroinitializer %sub = fsub <4 x float> %splat.splat, %p ret <4 x float> %sub } - +; Same codegen as above test; scalar is splatted using vld1, so shuffle index is irrelevant. define <4 x float> @check_spr_splat4_lane1(<4 x float> %p, i16 %q) { ;CHECK-LABEL: check_spr_splat4_lane1: -;CHECK: vdup.32 q{{.*}}, d{{.*}}[1] +;CHECK: vld1.16 %conv = sitofp i16 %q to float %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 1 %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> diff --git a/test/CodeGen/X86/vector-shuffle-256-v4.ll b/test/CodeGen/X86/vector-shuffle-256-v4.ll index 7b8c1d62fc4..bb08b941566 100644 --- a/test/CodeGen/X86/vector-shuffle-256-v4.ll +++ b/test/CodeGen/X86/vector-shuffle-256-v4.ll @@ -885,8 +885,7 @@ define <4 x double> @splat_mem_v4f64(double* %ptr) { define <4 x i64> @splat_mem_v4i64(i64* %ptr) { ; AVX1-LABEL: splat_mem_v4i64: ; AVX1: # BB#0: -; AVX1-NEXT: vmovddup {{.*#+}} xmm0 = mem[0,0] -; AVX1-NEXT: vinsertf128 $1, %xmm0, %ymm0, %ymm0 +; AVX1-NEXT: vbroadcastsd (%rdi), %ymm0 ; AVX1-NEXT: retq ; ; AVX2-LABEL: splat_mem_v4i64: