<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Thanks for the test case James, I'll take a look and get back to
    you.<br>
    <br>
    <div class="moz-cite-prefix">On 10/04/2015 12:53, James Molloy
      wrote:<br>
    </div>
    <blockquote
cite="mid:CALCTSA2a2t902w68YZocvQnGsSFjVUyP81Se-NaBbXuEUMp-MA@mail.gmail.com"
      type="cite">
      <div dir="ltr">Hi Simon,<br>
        <br>
        <div>This commit was found to be faulty by random testing. The
          attached .ll file, when run with "llc crash-2.ll" will fall
          over in instruction selection.</div>
        <div><br>
        </div>
        <div>The actual problem is an illegal BUILD_VECTOR is being
          created after type legalization (i8/i16 are illegal on
          ARM/AArch64).</div>
        <div><br>
        </div>
        <div>Would you mind please having a look?</div>
        <div><br>
        </div>
        <div>Cheers,</div>
        <div><br>
        </div>
        <div>James</div>
        <br>
        <div class="gmail_quote">On Wed, 25 Mar 2015 at 22:38 Simon
          Pilgrim <<a moz-do-not-send="true"
            href="mailto:llvm-dev@redking.me.uk">llvm-dev@redking.me.uk</a>>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
            rksimon<br>
            Date: Wed Mar 25 17:30:31 2015<br>
            New Revision: 233224<br>
            <br>
            URL: <a moz-do-not-send="true"
              href="http://llvm.org/viewvc/llvm-project?rev=233224&view=rev"
              target="_blank">http://llvm.org/viewvc/llvm-project?rev=233224&view=rev</a><br>
            Log:<br>
            [DAGCombiner] Add support for TRUNCATE + FP_EXTEND vector
            constant folding<br>
            <br>
            This patch adds supports for the vector constant folding of
            TRUNCATE and FP_EXTEND instructions and tidies up the
            SINT_TO_FP and UINT_TO_FP instructions to match.<br>
            <br>
            It also moves the vector constant folding for the FNEG and
            FABS instructions to use the DAG.getNode() functionality
            like the other unary instructions.<br>
            <br>
            Differential Revision: <a moz-do-not-send="true"
              href="http://reviews.llvm.org/D8593" target="_blank">http://reviews.llvm.org/D8593</a><br>
            <br>
            Modified:<br>
                llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h<br>
                llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp<br>
                llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp<br>
                llvm/trunk/test/CodeGen/X86/vec_fpext.ll<br>
                llvm/trunk/test/CodeGen/X86/vector-trunc.ll<br>
            <br>
            Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h<br>
            URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=233224&r1=233223&r2=233224&view=diff"
              target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=233224&r1=233223&r2=233224&view=diff</a><br>
            ==============================================================================<br>
            --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
            (original)<br>
            +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Wed
            Mar 25 17:30:31 2015<br>
            @@ -94,6 +94,10 @@ namespace ISD {<br>
               /// all ConstantSDNode or undef.<br>
               bool isBuildVectorOfConstantSDNodes(const SDNode *N);<br>
            <br>
            +  /// \brief Return true if the specified node is a
            BUILD_VECTOR node of<br>
            +  /// all ConstantFPSDNode or undef.<br>
            +  bool isBuildVectorOfConstantFPSDNodes(const SDNode *N);<br>
            +<br>
               /// Return true if the specified node is a<br>
               /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node
            where only the low<br>
               /// element is not an undef.<br>
            <br>
            Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp<br>
            URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=233224&r1=233223&r2=233224&view=diff"
              target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=233224&r1=233223&r2=233224&view=diff</a><br>
            ==============================================================================<br>
            --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
            (original)<br>
            +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed
            Mar 25 17:30:31 2015<br>
            @@ -251,7 +251,6 @@ namespace {<br>
                 SDValue visitORLike(SDValue N0, SDValue N1, SDNode
            *LocReference);<br>
                 SDValue visitXOR(SDNode *N);<br>
                 SDValue SimplifyVBinOp(SDNode *N);<br>
            -    SDValue SimplifyVUnaryOp(SDNode *N);<br>
                 SDValue visitSHL(SDNode *N);<br>
                 SDValue visitSRA(SDNode *N);<br>
                 SDValue visitSRL(SDNode *N);<br>
            @@ -716,6 +715,22 @@ static SDNode
            *isConstantBuildVectorOrCo<br>
               return nullptr;<br>
             }<br>
            <br>
            +static SDNode *isConstantIntBuildVectorOrConstantInt(SDValue
            N) {<br>
            +  if (isa<ConstantSDNode>(N))<br>
            +    return N.getNode();<br>
            +  if (ISD::isBuildVectorOfConstantSDNodes(N.getNode()))<br>
            +    return N.getNode();<br>
            +  return nullptr;<br>
            +}<br>
            +<br>
            +static SDNode *isConstantFPBuildVectorOrConstantFP(SDValue
            N) {<br>
            +  if (isa<ConstantFPSDNode>(N))<br>
            +    return N.getNode();<br>
            +  if (ISD::isBuildVectorOfConstantFPSDNodes(N.getNode()))<br>
            +    return N.getNode();<br>
            +  return nullptr;<br>
            +}<br>
            +<br>
             // \brief Returns the SDNode if it is a constant splat
            BuildVector or constant<br>
             // int.<br>
             static ConstantSDNode *isConstOrConstSplat(SDValue N) {<br>
            @@ -6557,7 +6572,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNod<br>
               if (N0.getValueType() == N->getValueType(0))<br>
                 return N0;<br>
               // fold (truncate c1) -> c1<br>
            -  if (isa<ConstantSDNode>(N0))<br>
            +  if (isConstantIntBuildVectorOrConstantInt(N0))<br>
                 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, N0);<br>
               // fold (truncate (truncate x)) -> (truncate x)<br>
               if (N0.getOpcode() == ISD::TRUNCATE)<br>
            @@ -7947,8 +7962,7 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDN<br>
               EVT OpVT = N0.getValueType();<br>
            <br>
               // fold (sint_to_fp c1) -> c1fp<br>
            -  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);<br>
            -  if (N0C &&<br>
            +  if (isConstantIntBuildVectorOrConstantInt(N0) &&<br>
                   // ...but only if the target supports immediate
            floating-point values<br>
                   (!LegalOperations ||<br>
                    TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP,
            VT)))<br>
            @@ -8000,8 +8014,7 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDN<br>
               EVT OpVT = N0.getValueType();<br>
            <br>
               // fold (uint_to_fp c1) -> c1fp<br>
            -  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);<br>
            -  if (N0C &&<br>
            +  if (isConstantIntBuildVectorOrConstantInt(N0) &&<br>
                   // ...but only if the target supports immediate
            floating-point values<br>
                   (!LegalOperations ||<br>
                    TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP,
            VT)))<br>
            @@ -8159,7 +8172,6 @@ SDValue DAGCombiner::visitFP_ROUND_INREG<br>
            <br>
             SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {<br>
               SDValue N0 = N->getOperand(0);<br>
            -  ConstantFPSDNode *N0CFP =
            dyn_cast<ConstantFPSDNode>(N0);<br>
               EVT VT = N->getValueType(0);<br>
            <br>
               // If this is fp_round(fpextend), don't fold it, allow
            ourselves to be folded.<br>
            @@ -8168,7 +8180,7 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNo<br>
                 return SDValue();<br>
            <br>
               // fold (fp_extend c1fp) -> c1fp<br>
            -  if (N0CFP)<br>
            +  if (isConstantFPBuildVectorOrConstantFP(N0))<br>
                 return DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, N0);<br>
            <br>
               // Turn fp_extend(fp_round(X, 1)) -> x since the
            fp_round doesn't affect the<br>
            @@ -8243,14 +8255,9 @@ SDValue DAGCombiner::visitFNEG(SDNode
            *N<br>
               SDValue N0 = N->getOperand(0);<br>
               EVT VT = N->getValueType(0);<br>
            <br>
            -  if (VT.isVector()) {<br>
            -    SDValue FoldedVOp = SimplifyVUnaryOp(N);<br>
            -    if (FoldedVOp.getNode()) return FoldedVOp;<br>
            -  }<br>
            -<br>
               // Constant fold FNEG.<br>
            -  if (isa<ConstantFPSDNode>(N0))<br>
            -    return DAG.getNode(ISD::FNEG, SDLoc(N), VT,
            N->getOperand(0));<br>
            +  if (isConstantFPBuildVectorOrConstantFP(N0))<br>
            +    return DAG.getNode(ISD::FNEG, SDLoc(N), VT, N0);<br>
            <br>
               if (isNegatibleForFree(N0, LegalOperations,
            DAG.getTargetLoweringInfo(),<br>
                                      &DAG.getTarget().Options))<br>
            @@ -8345,13 +8352,8 @@ SDValue DAGCombiner::visitFABS(SDNode
            *N<br>
               SDValue N0 = N->getOperand(0);<br>
               EVT VT = N->getValueType(0);<br>
            <br>
            -  if (VT.isVector()) {<br>
            -    SDValue FoldedVOp = SimplifyVUnaryOp(N);<br>
            -    if (FoldedVOp.getNode()) return FoldedVOp;<br>
            -  }<br>
            -<br>
               // fold (fabs c1) -> fabs(c1)<br>
            -  if (isa<ConstantFPSDNode>(N0))<br>
            +  if (isConstantFPBuildVectorOrConstantFP(N0))<br>
                 return DAG.getNode(ISD::FABS, SDLoc(N), VT, N0);<br>
            <br>
               // fold (fabs (fabs x)) -> (fabs x)<br>
            @@ -12401,38 +12403,6 @@ SDValue
            DAGCombiner::SimplifyVBinOp(SDNo<br>
               return SDValue();<br>
             }<br>
            <br>
            -/// Visit a binary vector operation, like FABS/FNEG.<br>
            -SDValue DAGCombiner::SimplifyVUnaryOp(SDNode *N) {<br>
            -  assert(N->getValueType(0).isVector() &&<br>
            -         "SimplifyVUnaryOp only works on vectors!");<br>
            -<br>
            -  SDValue N0 = N->getOperand(0);<br>
            -<br>
            -  if (N0.getOpcode() != ISD::BUILD_VECTOR)<br>
            -    return SDValue();<br>
            -<br>
            -  // Operand is a BUILD_VECTOR node, see if we can constant
            fold it.<br>
            -  SmallVector<SDValue, 8> Ops;<br>
            -  for (unsigned i = 0, e = N0.getNumOperands(); i != e;
            ++i) {<br>
            -    SDValue Op = N0.getOperand(i);<br>
            -    if (Op.getOpcode() != ISD::UNDEF &&<br>
            -        Op.getOpcode() != ISD::ConstantFP)<br>
            -      break;<br>
            -    EVT EltVT = Op.getValueType();<br>
            -    SDValue FoldOp = DAG.getNode(N->getOpcode(),
            SDLoc(N0), EltVT, Op);<br>
            -    if (FoldOp.getOpcode() != ISD::UNDEF &&<br>
            -        FoldOp.getOpcode() != ISD::ConstantFP)<br>
            -      break;<br>
            -    Ops.push_back(FoldOp);<br>
            -    AddToWorklist(FoldOp.getNode());<br>
            -  }<br>
            -<br>
            -  if (Ops.size() != N0.getNumOperands())<br>
            -    return SDValue();<br>
            -<br>
            -  return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N),
            N0.getValueType(), Ops);<br>
            -}<br>
            -<br>
             SDValue DAGCombiner::SimplifySelect(SDLoc DL, SDValue N0,<br>
                                                 SDValue N1, SDValue
            N2){<br>
               assert(N0.getOpcode() ==ISD::SETCC && "First
            argument must be a SetCC node!");<br>
            <br>
            Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp<br>
            URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=233224&r1=233223&r2=233224&view=diff"
              target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=233224&r1=233223&r2=233224&view=diff</a><br>
            ==============================================================================<br>
            --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
            (original)<br>
            +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed
            Mar 25 17:30:31 2015<br>
            @@ -196,6 +196,22 @@ bool ISD::isBuildVectorOfConstantSDNodes<br>
               return true;<br>
             }<br>
            <br>
            +/// \brief Return true if the specified node is a
            BUILD_VECTOR node of<br>
            +/// all ConstantFPSDNode or undef.<br>
            +bool ISD::isBuildVectorOfConstantFPSDNodes(const SDNode *N)
            {<br>
            +  if (N->getOpcode() != ISD::BUILD_VECTOR)<br>
            +    return false;<br>
            +<br>
            +  for (unsigned i = 0, e = N->getNumOperands(); i != e;
            ++i) {<br>
            +    SDValue Op = N->getOperand(i);<br>
            +    if (Op.getOpcode() == ISD::UNDEF)<br>
            +      continue;<br>
            +    if (!isa<ConstantFPSDNode>(Op))<br>
            +      return false;<br>
            +  }<br>
            +  return true;<br>
            +}<br>
            +<br>
             /// isScalarToVector - Return true if the specified node is
            a<br>
             /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where
            only the low<br>
             /// element is not an undef.<br>
            @@ -2827,7 +2843,7 @@ SDValue SelectionDAG::getNode(unsigned
            O<br>
                 }<br>
               }<br>
            <br>
            -  // Constant fold unary operations with a vector integer
            operand.<br>
            +  // Constant fold unary operations with a vector integer
            or float operand.<br>
               if (BuildVectorSDNode *BV =
            dyn_cast<BuildVectorSDNode>(Operand.getNode())) {<br>
                 if (BV->isConstant()) {<br>
                   switch (Opcode) {<br>
            @@ -2835,6 +2851,10 @@ SDValue
            SelectionDAG::getNode(unsigned O<br>
                     // FIXME: Entirely reasonable to perform folding of
            other unary<br>
                     // operations here as the need arises.<br>
                     break;<br>
            +      case ISD::FNEG:<br>
            +      case ISD::FABS:<br>
            +      case ISD::FP_EXTEND:<br>
            +      case ISD::TRUNCATE:<br>
                   case ISD::UINT_TO_FP:<br>
                   case ISD::SINT_TO_FP: {<br>
                     // Let the above scalar folding handle the folding
            of each element.<br>
            @@ -2842,9 +2862,14 @@ SDValue
            SelectionDAG::getNode(unsigned O<br>
                     for (int i = 0, e = VT.getVectorNumElements(); i !=
            e; ++i) {<br>
                       SDValue OpN = BV->getOperand(i);<br>
                       OpN = getNode(Opcode, DL,
            VT.getVectorElementType(), OpN);<br>
            +          if (OpN.getOpcode() != ISD::UNDEF &&<br>
            +              OpN.getOpcode() != ISD::Constant &&<br>
            +              OpN.getOpcode() != ISD::ConstantFP)<br>
            +            break;<br>
                       Ops.push_back(OpN);<br>
                     }<br>
            -        return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);<br>
            +        if (Ops.size() == VT.getVectorNumElements())<br>
            +          return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);<br>
                   }<br>
                   }<br>
                 }<br>
            <br>
            Modified: llvm/trunk/test/CodeGen/X86/vec_fpext.ll<br>
            URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_fpext.ll?rev=233224&r1=233223&r2=233224&view=diff"
              target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_fpext.ll?rev=233224&r1=233223&r2=233224&view=diff</a><br>
            ==============================================================================<br>
            --- llvm/trunk/test/CodeGen/X86/vec_fpext.ll (original)<br>
            +++ llvm/trunk/test/CodeGen/X86/vec_fpext.ll Wed Mar 25
            17:30:31 2015<br>
            @@ -42,3 +42,15 @@ entry:<br>
               store <8 x double> %1, <8 x double>* %out,
            align 1<br>
               ret void<br>
             }<br>
            +<br>
            +define <2 x double> @fpext_fromconst() {<br>
            +; CHECK-LABEL: fpext_fromconst:<br>
            +; AVX-LABEL: fpext_fromconst:<br>
            +entry:<br>
            +; CHECK: movaps {{.*#+}} xmm0 =
            [1.000000e+00,-2.000000e+00]<br>
            +; AVX: vmovaps {{.*#+}} xmm0 = [1.000000e+00,-2.000000e+00]<br>
            +  %0  = insertelement <2 x float> undef, float 1.0,
            i32 0<br>
            +  %1  = insertelement <2 x float> %0, float -2.0, i32
            1<br>
            +  %2  = fpext <2 x float> %1 to <2 x double><br>
            +  ret <2 x double> %2<br>
            +}<br>
            <br>
            Modified: llvm/trunk/test/CodeGen/X86/vector-trunc.ll<br>
            URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-trunc.ll?rev=233224&r1=233223&r2=233224&view=diff"
              target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-trunc.ll?rev=233224&r1=233223&r2=233224&view=diff</a><br>
            ==============================================================================<br>
            --- llvm/trunk/test/CodeGen/X86/vector-trunc.ll (original)<br>
            +++ llvm/trunk/test/CodeGen/X86/vector-trunc.ll Wed Mar 25
            17:30:31 2015<br>
            @@ -221,3 +221,20 @@ entry:<br>
               %1 = bitcast <8 x i8> %0 to i64<br>
               ret i64 %1<br>
             }<br>
            +<br>
            +define <16 x i8> @trunc16i64_const() {<br>
            +; SSE-LABEL:  trunc16i64_const<br>
            +; SSE:        # BB#0: # %entry<br>
            +; SSE-NEXT:   xorps %xmm0, %xmm0<br>
            +; SSE-NEXT:   retq<br>
            +;<br>
            +; AVX-LABEL:  trunc16i64_const<br>
            +; AVX:        # BB#0: # %entry<br>
            +; AVX-NEXT:   vxorps %xmm0, %xmm0, %xmm0<br>
            +; AVX-NEXT:   retq<br>
            +<br>
            +entry:<br>
            +  %0 = trunc <16 x i64> zeroinitializer to <16 x
            i8><br>
            +  %1 = shufflevector <16 x i8> %0, <16 x i8>
            %0, <16 x i32> <i32 28, i32 30, i32 0, i32 2, i32
            4, i32 6, i32 8, i32 10, i32 undef, i32 14, i32 16, i32 18,
            i32 20, i32 22, i32 24, i32 26><br>
            +  ret <16 x i8> %1<br>
            +}<br>
            <br>
            <br>
            _______________________________________________<br>
            llvm-commits mailing list<br>
            <a moz-do-not-send="true"
              href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
            <a moz-do-not-send="true"
              href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits"
              target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>