[llvm] r230177 - [DagCombiner] Generalized BuildVector Vector Concatenation

Eric Christopher echristo at gmail.com
Tue Feb 24 11:16:45 PST 2015


Hi Simon,

This caused PR22678 and I've gone ahead and reverted and cc'd you on the
bug. Sorry for the inconvenience!

-eric

On Sun Feb 22 2015 at 10:22:53 AM Simon Pilgrim <llvm-dev at redking.me.uk>
wrote:

> Author: rksimon
> Date: Sun Feb 22 12:17:28 2015
> New Revision: 230177
>
> URL: http://llvm.org/viewvc/llvm-project?rev=230177&view=rev
> Log:
> [DagCombiner] Generalized BuildVector Vector Concatenation
>
> The CONCAT_VECTORS combiner pass can transform the concat of two
> BUILD_VECTOR nodes into a single BUILD_VECTOR node.
>
> This patch generalises this to support any number of BUILD_VECTOR nodes,
> and also permits UNDEF nodes to be included as well.
>
> This was noticed as AVX vec128 -> vec256 canonicalization sometimes
> creates a CONCAT_VECTOR with a real vec128 lower and an vec128 UNDEF upper.
>
> Differential Revision: http://reviews.llvm.org/D7816
>
> Modified:
>     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>     llvm/trunk/test/CodeGen/X86/vector-zext.ll
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> CodeGen/SelectionDAG/DAGCombiner.cpp?rev=230177&r1=
> 230176&r2=230177&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Feb 22
> 12:17:28 2015
> @@ -11430,36 +11430,51 @@ SDValue DAGCombiner::visitCONCAT_VECTORS
>      }
>    }
>
> +  // Fold any combination of BUILD_VECTOR or UNDEF nodes into one
> BUILD_VECTOR.
> +  // We have already tested above for an UNDEF only concatenation.
>    // fold (concat_vectors (BUILD_VECTOR A, B, ...), (BUILD_VECTOR C, D,
> ...))
>    // -> (BUILD_VECTOR A, B, ..., C, D, ...)
> -  if (N->getNumOperands() == 2 &&
> -      N->getOperand(0).getOpcode() == ISD::BUILD_VECTOR &&
> -      N->getOperand(1).getOpcode() == ISD::BUILD_VECTOR) {
> -    EVT VT = N->getValueType(0);
> -    SDValue N0 = N->getOperand(0);
> -    SDValue N1 = N->getOperand(1);
> +  auto IsBuildVectorOrUndef = [](const SDValue &Op) {
> +    return ISD::UNDEF == Op.getOpcode() || ISD::BUILD_VECTOR ==
> Op.getOpcode();
> +  };
> +  bool AllBuildVectorsOrUndefs =
> +      std::all_of(N->op_begin(), N->op_end(), IsBuildVectorOrUndef);
> +  if (AllBuildVectorsOrUndefs) {
>      SmallVector<SDValue, 8> Opnds;
> -    unsigned BuildVecNumElts =  N0.getNumOperands();
> +    EVT SVT = VT.getScalarType();
>
> -    EVT SclTy0 = N0.getOperand(0)->getValueType(0);
> -    EVT SclTy1 = N1.getOperand(0)->getValueType(0);
> -    if (SclTy0.isFloatingPoint()) {
> -      for (unsigned i = 0; i != BuildVecNumElts; ++i)
> -        Opnds.push_back(N0.getOperand(i));
> -      for (unsigned i = 0; i != BuildVecNumElts; ++i)
> -        Opnds.push_back(N1.getOperand(i));
> -    } else {
> +    EVT MinVT = SVT;
> +    if (!SVT.isFloatingPoint())
>        // If BUILD_VECTOR are from built from integer, they may have
> different
>        // operand types. Get the smaller type and truncate all operands to
> it.
> -      EVT MinTy = SclTy0.bitsLE(SclTy1) ? SclTy0 : SclTy1;
> -      for (unsigned i = 0; i != BuildVecNumElts; ++i)
> -        Opnds.push_back(DAG.getNode(ISD::TRUNCATE, SDLoc(N), MinTy,
> -                        N0.getOperand(i)));
> -      for (unsigned i = 0; i != BuildVecNumElts; ++i)
> -        Opnds.push_back(DAG.getNode(ISD::TRUNCATE, SDLoc(N), MinTy,
> -                        N1.getOperand(i)));
> +      for (const SDValue &Op : N->ops()) {
> +        EVT OpSVT = Op.getValueType().getScalarType();
> +        MinVT = MinVT.bitsLE(OpSVT) ? MinVT : OpSVT;
> +      }
> +
> +    for (const SDValue &Op : N->ops()) {
> +      EVT OpVT = Op.getValueType();
> +      unsigned NumElts = OpVT.getVectorNumElements();
> +
> +      if (ISD::UNDEF == Op.getOpcode())
> +        for (unsigned i = 0; i != NumElts; ++i)
> +          Opnds.push_back(DAG.getUNDEF(MinVT));
> +
> +      if (ISD::BUILD_VECTOR == Op.getOpcode()) {
> +        if (SVT.isFloatingPoint()) {
> +          assert(SVT == OpVT.getScalarType() && "Concat vector type
> mismatch");
> +          for (unsigned i = 0; i != NumElts; ++i)
> +            Opnds.push_back(Op.getOperand(i));
> +        } else {
> +          for (unsigned i = 0; i != NumElts; ++i)
> +            Opnds.push_back(
> +                DAG.getNode(ISD::TRUNCATE, SDLoc(N), MinVT,
> Op.getOperand(i)));
> +        }
> +      }
>      }
>
> +    assert(VT.getVectorNumElements() == Opnds.size() &&
> +           "Concat vector type mismatch");
>      return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), VT, Opnds);
>    }
>
>
> Modified: llvm/trunk/test/CodeGen/X86/vector-zext.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> CodeGen/X86/vector-zext.ll?rev=230177&r1=230176&r2=230177&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/CodeGen/X86/vector-zext.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/vector-zext.ll Sun Feb 22 12:17:28 2015
> @@ -358,22 +358,16 @@ define <8 x i32> @shuf_zext_8i16_to_8i32
>  ;
>  ; AVX1-LABEL: shuf_zext_8i16_to_8i32:
>  ; AVX1:       # BB#0: # %entry
> -; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
> -; AVX1-NEXT:    vpshuflw {{.*#+}} xmm1 = xmm1[0,0,0,0,4,5,6,7]
> -; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
> -; AVX1-NEXT:    vpunpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[
> 1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
> -; AVX1-NEXT:    vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[
> 1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
> -; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
> +; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
> +; AVX1-NEXT:    vpunpckhwd {{.*#+}} xmm1 = xmm0[4],xmm1[4],xmm0[5],xmm1[
> 5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
> +; AVX1-NEXT:    vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,
> xmm0[2],zero,xmm0[3],zero
> +; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
>  ; AVX1-NEXT:    retq
>  ;
>  ; AVX2-LABEL: shuf_zext_8i16_to_8i32:
>  ; AVX2:       # BB#0: # %entry
> -; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
> -; AVX2-NEXT:    vpbroadcastw %xmm1, %xmm1
> -; AVX2-NEXT:    vpshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
> -; AVX2-NEXT:    vpunpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[
> 1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
> -; AVX2-NEXT:    vpunpcklwd{{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[
> 1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
> -; AVX2-NEXT:    vinserti128 $1, %xmm2, %ymm0, %ymm0
> +; AVX2-NEXT:    # kill
> +; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,
> xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,
> xmm0[6],zero,xmm0[7],zero
>  ; AVX2-NEXT:    retq
>  entry:
>    %B = shufflevector <8 x i16> %A, <8 x i16> zeroinitializer, <16 x i32>
> <i32 0, i32 8, i32 1, i32 8, i32 2, i32 8, i32 3, i32 8, i32 4, i32 8, i32
> 5, i32 8, i32 6, i32 8, i32 7, i32 8>
> @@ -410,22 +404,17 @@ define <4 x i64> @shuf_zext_4i32_to_4i64
>  ;
>  ; AVX1-LABEL: shuf_zext_4i32_to_4i64:
>  ; AVX1:       # BB#0: # %entry
> -; AVX1-NEXT:    vxorps %xmm1, %xmm1, %xmm1
> -; AVX1-NEXT:    vshufps {{.*#+}} xmm2 = xmm0[0,1],xmm1[0,0]
> -; AVX1-NEXT:    vshufps {{.*#+}} xmm2 = xmm2[0,2,1,3]
> -; AVX1-NEXT:    vblendpd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
> -; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,0,3,0]
> -; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm2, %ymm0
> +; AVX1-NEXT:    vinsertps {{.*#+}} xmm1 = xmm0[0],zero,xmm0[1],zero
> +; AVX1-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
> +; AVX1-NEXT:    vblendpd {{.*#+}} xmm0 = xmm2[0],xmm0[1]
> +; AVX1-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,0,3,0]
> +; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
>  ; AVX1-NEXT:    retq
>  ;
>  ; AVX2-LABEL: shuf_zext_4i32_to_4i64:
>  ; AVX2:       # BB#0: # %entry
>  ; AVX2-NEXT:    # kill
>  ; AVX2-NEXT:    vpmovzxdq {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,
> xmm0[2],zero,xmm0[3],zero
> -; AVX2-NEXT:    xorl %eax, %eax
> -; AVX2-NEXT:    vmovd %eax, %xmm1
> -; AVX2-NEXT:    vpbroadcastd %xmm1, %ymm1
> -; AVX2-NEXT:    vpblendd {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[
> 3],ymm0[4],ymm1[5],ymm0[6],ymm1[7]
>  ; AVX2-NEXT:    retq
>  entry:
>    %B = shufflevector <4 x i32> %A, <4 x i32> zeroinitializer, <8 x i32>
> <i32 0, i32 4, i32 1, i32 4, i32 2, i32 4, i32 3, i32 4>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150224/12956c85/attachment.html>


More information about the llvm-commits mailing list