[llvm] r237885 - [X86][SSE] Improve support for 128-bit vector sign extension

Simon Pilgrim llvm-dev at redking.me.uk
Sat Jun 20 09:30:57 PDT 2015


Thanks Jeroen - fixed in rL240223. Simon.

> On 19 Jun 2015, at 10:21, Jeroen Ketema <jeroen at codeplay.com> wrote:
> 
> This commit breaks compilation on ivybridge with Debug builds
> 
> > llc.exe test.ll  -mcpu ivybridge
> 
> Assertion failed: VT.getVectorElementType() == N1.getValueType().getVectorElementType() && "Extract subvector VTs must have the same element type!", file ...\llvm\lib\CodeGen\SelectionDAG\SelectionDAG.cpp, line 3549
> 
> where test.ll is:
> 
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
> 
> %Arguments = type <{ <8 x i8>, <8 x i16>, <8 x float> addrspace(1)* }>
> 
> ; Function Attrs: nounwind
> define void @foo(%Arguments* nocapture readonly %args) #0 {
> body:
>  %0 = load %Arguments, %Arguments* %args, align 1
>  %1 = extractvalue %Arguments %0, 1
>  %2 = extractvalue %Arguments %0, 2
>  %3 = sitofp <8 x i16> %1 to <8 x float>
>  store <8 x float> %3, <8 x float> addrspace(1)* %2, align 32
>  ret void
> }
> 
> attributes #0 = { nounwind }
> 
> !llvm.ident = !{!0, !0, !0}
> 
> !0 = !{!"clang version 3.7.0 "}
> 
> On 21/05/2015 11:05, Simon Pilgrim wrote:
>> Author: rksimon
>> Date: Thu May 21 05:05:03 2015
>> New Revision: 237885
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=237885&view=rev
>> Log:
>> [X86][SSE] Improve support for 128-bit vector sign extension
>> 
>> This patch improves support for sign extension of the lower lanes of vectors of integers by making use of the SSE41 pmovsx* sign extension instructions where possible, and optimizing the sign extension by shifts on pre-SSE41 targets (avoiding the use of i64 arithmetic shifts which require scalarization).
>> 
>> It converts SIGN_EXTEND nodes to SIGN_EXTEND_VECTOR_INREG where necessary, that more closely matches the pmovsx* instruction than the default approach of using SIGN_EXTEND_INREG which splits the operation (into an ANY_EXTEND lowered to a shuffle followed by shifts) making instruction matching difficult during lowering. Necessary support for SIGN_EXTEND_VECTOR_INREG has been added to the DAGCombiner.
>> 
>> Differential Revision: http://reviews.llvm.org/D9848
>> 
>> Modified:
>>     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>>     llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>>     llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>     llvm/trunk/test/CodeGen/X86/pr15267.ll
>>     llvm/trunk/test/CodeGen/X86/vec_cast2.ll
>>     llvm/trunk/test/CodeGen/X86/vector-sext.ll
>>     llvm/trunk/test/CodeGen/X86/vselect-avx.ll
>> 
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu May 21 05:05:03 2015
>> @@ -268,6 +268,7 @@ namespace {
>>      SDValue visitZERO_EXTEND(SDNode *N);
>>      SDValue visitANY_EXTEND(SDNode *N);
>>      SDValue visitSIGN_EXTEND_INREG(SDNode *N);
>> +    SDValue visitSIGN_EXTEND_VECTOR_INREG(SDNode *N);
>>      SDValue visitTRUNCATE(SDNode *N);
>>      SDValue visitBITCAST(SDNode *N);
>>      SDValue visitBUILD_PAIR(SDNode *N);
>> @@ -1347,6 +1348,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
>>    case ISD::ZERO_EXTEND:        return visitZERO_EXTEND(N);
>>    case ISD::ANY_EXTEND:         return visitANY_EXTEND(N);
>>    case ISD::SIGN_EXTEND_INREG:  return visitSIGN_EXTEND_INREG(N);
>> +  case ISD::SIGN_EXTEND_VECTOR_INREG: return visitSIGN_EXTEND_VECTOR_INREG(N);
>>    case ISD::TRUNCATE:           return visitTRUNCATE(N);
>>    case ISD::BITCAST:            return visitBITCAST(N);
>>    case ISD::BUILD_PAIR:         return visitBUILD_PAIR(N);
>> @@ -5541,7 +5543,8 @@ static SDNode *tryToFoldExtendOfConstant
>>    EVT VT = N->getValueType(0);
>>      assert((Opcode == ISD::SIGN_EXTEND || Opcode == ISD::ZERO_EXTEND ||
>> -         Opcode == ISD::ANY_EXTEND) && "Expected EXTEND dag node in input!");
>> +         Opcode == ISD::ANY_EXTEND || Opcode == ISD::SIGN_EXTEND_VECTOR_INREG)
>> +         && "Expected EXTEND dag node in input!");
>>      // fold (sext c1) -> c1
>>    // fold (zext c1) -> c1
>> @@ -5563,7 +5566,7 @@ static SDNode *tryToFoldExtendOfConstant
>>    unsigned EVTBits = N0->getValueType(0).getScalarType().getSizeInBits();
>>    unsigned ShAmt = VTBits - EVTBits;
>>    SmallVector<SDValue, 8> Elts;
>> -  unsigned NumElts = N0->getNumOperands();
>> +  unsigned NumElts = VT.getVectorNumElements();
>>    SDLoc DL(N);
>>      for (unsigned i=0; i != NumElts; ++i) {
>> @@ -5576,7 +5579,7 @@ static SDNode *tryToFoldExtendOfConstant
>>      SDLoc DL(Op);
>>      ConstantSDNode *CurrentND = cast<ConstantSDNode>(Op);
>>      const APInt &C = APInt(VTBits, CurrentND->getAPIntValue().getZExtValue());
>> -    if (Opcode == ISD::SIGN_EXTEND)
>> +    if (Opcode == ISD::SIGN_EXTEND || Opcode == ISD::SIGN_EXTEND_VECTOR_INREG)
>>        Elts.push_back(DAG.getConstant(C.shl(ShAmt).ashr(ShAmt).getZExtValue(),
>>                                       DL, SVT));
>>      else
>> @@ -6804,6 +6807,20 @@ SDValue DAGCombiner::visitSIGN_EXTEND_IN
>>      return SDValue();
>>  }
>> +
>> +SDValue DAGCombiner::visitSIGN_EXTEND_VECTOR_INREG(SDNode *N) {
>> +  SDValue N0 = N->getOperand(0);
>> +  EVT VT = N->getValueType(0);
>> +
>> +  if (N0.getOpcode() == ISD::UNDEF)
>> +    return DAG.getUNDEF(VT);
>> +
>> +  if (SDNode *Res = tryToFoldExtendOfConstant(N, TLI, DAG, LegalTypes,
>> +                                              LegalOperations))
>> +    return SDValue(Res, 0);
>> +
>> +  return SDValue();
>> +}
>>    SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
>>    SDValue N0 = N->getOperand(0);
>> 
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu May 21 05:05:03 2015
>> @@ -3429,12 +3429,35 @@ SDValue SelectionDAG::getNode(unsigned O
>>      assert(EVT.bitsLE(VT) && "Not extending!");
>>      if (EVT == VT) return N1;  // Not actually extending
>>  +    auto SignExtendInReg = [&](APInt Val) {
>> +      unsigned FromBits = EVT.getScalarType().getSizeInBits();
>> +      Val <<= Val.getBitWidth() - FromBits;
>> +      Val = Val.ashr(Val.getBitWidth() - FromBits);
>> +      return getConstant(Val, DL, VT.getScalarType());
>> +    };
>> +
>>      if (N1C) {
>>        APInt Val = N1C->getAPIntValue();
>> -      unsigned FromBits = EVT.getScalarType().getSizeInBits();
>> -      Val <<= Val.getBitWidth()-FromBits;
>> -      Val = Val.ashr(Val.getBitWidth()-FromBits);
>> -      return getConstant(Val, DL, VT);
>> +      return SignExtendInReg(Val);
>> +    }
>> +    if (ISD::isBuildVectorOfConstantSDNodes(N1.getNode())) {
>> +      SmallVector<SDValue, 8> Ops;
>> +      for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
>> +        SDValue Op = N1.getOperand(i);
>> +        if (Op.getValueType() != VT.getScalarType()) break;
>> +        if (Op.getOpcode() == ISD::UNDEF) {
>> +          Ops.push_back(Op);
>> +          continue;
>> +        }
>> +        if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getNode())) {
>> +          APInt Val = C->getAPIntValue();
>> +          Ops.push_back(SignExtendInReg(Val));
>> +          continue;
>> +        }
>> +        break;
>> +      }
>> +      if (Ops.size() == VT.getVectorNumElements())
>> +        return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
>>      }
>>      break;
>>    }
>> 
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu May 21 05:05:03 2015
>> @@ -1004,6 +1004,10 @@ X86TargetLowering::X86TargetLowering(con
>>    }
>>      if (Subtarget->hasSSE2()) {
>> +    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v2i64, Custom);
>> +    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v4i32, Custom);
>> +    setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, MVT::v8i16, Custom);
>> +
>>      setOperationAction(ISD::SRL,               MVT::v8i16, Custom);
>>      setOperationAction(ISD::SRL,               MVT::v16i8, Custom);
>>  @@ -13914,6 +13918,63 @@ static SDValue LowerSIGN_EXTEND_AVX512(S
>>    return DAG.getNode(X86ISD::VTRUNC, dl, VT, V);
>>  }
>>  +static SDValue LowerSIGN_EXTEND_VECTOR_INREG(SDValue Op,
>> +                                             const X86Subtarget *Subtarget,
>> +                                             SelectionDAG &DAG) {
>> +  SDValue In = Op->getOperand(0);
>> +  MVT VT = Op->getSimpleValueType(0);
>> +  MVT InVT = In.getSimpleValueType();
>> +  assert(VT.getSizeInBits() == InVT.getSizeInBits());
>> +
>> +  MVT SVT = VT.getScalarType();
>> +  MVT InSVT = InVT.getScalarType();
>> +  assert(SVT.getScalarSizeInBits() > InSVT.getScalarSizeInBits());
>> +
>> +  if (VT != MVT::v2i64 && VT != MVT::v4i32 && VT != MVT::v8i16)
>> +    return SDValue();
>> +  if (InSVT != MVT::i32 && InSVT != MVT::i16 && InSVT != MVT::i8)
>> +    return SDValue();
>> +
>> +  SDLoc dl(Op);
>> +
>> +  // SSE41 targets can use the pmovsx* instructions directly.
>> +  if (Subtarget->hasSSE41())
>> +    return DAG.getNode(X86ISD::VSEXT, dl, VT, In);
>> +
>> +  // pre-SSE41 targets unpack lower lanes and then sign-extend using SRAI.
>> +  SDValue Curr = In;
>> +  MVT CurrVT = InVT;
>> +
>> +  // As SRAI is only available on i16/i32 types, we expand only up to i32
>> +  // and handle i64 separately.
>> +  while (CurrVT != VT && CurrVT.getScalarType() != MVT::i32) {
>> +    Curr = DAG.getNode(X86ISD::UNPCKL, dl, CurrVT, DAG.getUNDEF(CurrVT), Curr);
>> +    MVT CurrSVT = MVT::getIntegerVT(CurrVT.getScalarSizeInBits() * 2);
>> +    CurrVT = MVT::getVectorVT(CurrSVT, CurrVT.getVectorNumElements() / 2);
>> +    Curr = DAG.getNode(ISD::BITCAST, dl, CurrVT, Curr);
>> +  }
>> +
>> +  SDValue SignExt = Curr;
>> +  if (CurrVT != InVT) {
>> +    unsigned SignExtShift =
>> +        CurrVT.getScalarSizeInBits() - InSVT.getScalarSizeInBits();
>> +    SignExt = DAG.getNode(X86ISD::VSRAI, dl, CurrVT, Curr,
>> +                          DAG.getConstant(SignExtShift, dl, MVT::i8));
>> +  }
>> +
>> +  if (CurrVT == VT)
>> +    return SignExt;
>> +
>> +  if (VT == MVT::v2i64 && CurrVT == MVT::v4i32) {
>> +    SDValue Sign = DAG.getNode(X86ISD::VSRAI, dl, CurrVT, Curr,
>> +                               DAG.getConstant(31, dl, MVT::i8));
>> +    SDValue Ext = DAG.getVectorShuffle(CurrVT, dl, SignExt, Sign, {0, 4, 1, 5});
>> +    return DAG.getNode(ISD::BITCAST, dl, VT, Ext);
>> +  }
>> +
>> +  return SDValue();
>> +}
>> +
>>  static SDValue LowerSIGN_EXTEND(SDValue Op, const X86Subtarget *Subtarget,
>>                                  SelectionDAG &DAG) {
>>    MVT VT = Op->getSimpleValueType(0);
>> @@ -17580,6 +17641,8 @@ SDValue X86TargetLowering::LowerOperatio
>>    case ISD::ZERO_EXTEND:        return LowerZERO_EXTEND(Op, Subtarget, DAG);
>>    case ISD::SIGN_EXTEND:        return LowerSIGN_EXTEND(Op, Subtarget, DAG);
>>    case ISD::ANY_EXTEND:         return LowerANY_EXTEND(Op, Subtarget, DAG);
>> +  case ISD::SIGN_EXTEND_VECTOR_INREG:
>> +    return LowerSIGN_EXTEND_VECTOR_INREG(Op, Subtarget, DAG);
>>    case ISD::FP_TO_SINT:         return LowerFP_TO_SINT(Op, DAG);
>>    case ISD::FP_TO_UINT:         return LowerFP_TO_UINT(Op, DAG);
>>    case ISD::FP_EXTEND:          return LowerFP_EXTEND(Op, DAG);
>> @@ -23683,16 +23746,19 @@ static SDValue PerformSExtCombine(SDNode
>>                                    const X86Subtarget *Subtarget) {
>>    SDValue N0 = N->getOperand(0);
>>    EVT VT = N->getValueType(0);
>> -  SDLoc dl(N);
>> +  EVT SVT = VT.getScalarType();
>> +  EVT InVT = N0->getValueType(0);
>> +  EVT InSVT = InVT.getScalarType();
>> +  SDLoc DL(N);
>>      // (i8,i32 sext (sdivrem (i8 x, i8 y)) ->
>>    // (i8,i32 (sdivrem_sext_hreg (i8 x, i8 y)
>>    // This exposes the sext to the sdivrem lowering, so that it directly extends
>>    // from AH (which we otherwise need to do contortions to access).
>>    if (N0.getOpcode() == ISD::SDIVREM && N0.getResNo() == 1 &&
>> -      N0.getValueType() == MVT::i8 && VT == MVT::i32) {
>> +      InVT == MVT::i8 && VT == MVT::i32) {
>>      SDVTList NodeTys = DAG.getVTList(MVT::i8, VT);
>> -    SDValue R = DAG.getNode(X86ISD::SDIVREM8_SEXT_HREG, dl, NodeTys,
>> +    SDValue R = DAG.getNode(X86ISD::SDIVREM8_SEXT_HREG, DL, NodeTys,
>>                              N0.getOperand(0), N0.getOperand(1));
>>      DAG.ReplaceAllUsesOfValueWith(N0.getValue(0), R.getValue(0));
>>      return R.getValue(1);
>> @@ -23700,14 +23766,57 @@ static SDValue PerformSExtCombine(SDNode
>>      if (!DCI.isBeforeLegalizeOps()) {
>>      if (N0.getValueType() == MVT::i1) {
>> -      SDValue Zero = DAG.getConstant(0, dl, VT);
>> +      SDValue Zero = DAG.getConstant(0, DL, VT);
>>        SDValue AllOnes =
>> -        DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), dl, VT);
>> -      return DAG.getNode(ISD::SELECT, dl, VT, N0, AllOnes, Zero);
>> +        DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), DL, VT);
>> +      return DAG.getNode(ISD::SELECT, DL, VT, N0, AllOnes, Zero);
>>      }
>>      return SDValue();
>>    }
>>  +  if (VT.isVector()) {
>> +    auto ExtendToVec128 = [&DAG](SDLoc DL, SDValue N) {
>> +      EVT InVT = N->getValueType(0);
>> +      EVT OutVT = EVT::getVectorVT(*DAG.getContext(), InVT.getScalarType(),
>> +                                   128 / InVT.getScalarSizeInBits());
>> +      SmallVector<SDValue, 8> Opnds(128 / InVT.getSizeInBits(),
>> +                                    DAG.getUNDEF(InVT));
>> +      Opnds[0] = N;
>> +      return DAG.getNode(ISD::CONCAT_VECTORS, DL, OutVT, Opnds);
>> +    };
>> +
>> +    // If target-size is 128-bits, then convert to ISD::SIGN_EXTEND_VECTOR_INREG
>> +    // which ensures lowering to X86ISD::VSEXT (pmovsx*).
>> +    if (VT.getSizeInBits() == 128 &&
>> +        (SVT == MVT::i64 || SVT == MVT::i32 || SVT == MVT::i16) &&
>> +        (InSVT == MVT::i32 || InSVT == MVT::i16 || InSVT == MVT::i8)) {
>> +      SDValue ExOp = ExtendToVec128(DL, N0);
>> +      return DAG.getSignExtendVectorInReg(ExOp, DL, VT);
>> +    }
>> +
>> +    // On pre-AVX2 targets, split into 128-bit nodes of
>> +    // ISD::SIGN_EXTEND_VECTOR_INREG.
>> +    if (!Subtarget->hasInt256() && !(VT.getSizeInBits() % 128) &&
>> +        (SVT == MVT::i64 || SVT == MVT::i32 || SVT == MVT::i16) &&
>> +        (InSVT == MVT::i32 || InSVT == MVT::i16 || InSVT == MVT::i8)) {
>> +      unsigned NumVecs = VT.getSizeInBits() / 128;
>> +      unsigned NumSubElts = 128 / SVT.getSizeInBits();
>> +      EVT SubVT = EVT::getVectorVT(*DAG.getContext(), SVT, NumSubElts);
>> +      EVT InSubVT = EVT::getVectorVT(*DAG.getContext(), InSVT, NumSubElts);
>> +
>> +      SmallVector<SDValue, 8> Opnds;
>> +      for (unsigned i = 0, Offset = 0; i != NumVecs;
>> +           ++i, Offset += NumSubElts) {
>> +        SDValue SrcVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InSubVT, N0,
>> +                                     DAG.getIntPtrConstant(Offset, DL));
>> +        SrcVec = ExtendToVec128(DL, SrcVec);
>> +        SrcVec = DAG.getSignExtendVectorInReg(SrcVec, DL, SubVT);
>> +        Opnds.push_back(SrcVec);
>> +      }
>> +      return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Opnds);
>> +    }
>> +  }
>> +
>>    if (!Subtarget->hasFp256())
>>      return SDValue();
>>  
>> Modified: llvm/trunk/test/CodeGen/X86/pr15267.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr15267.ll?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/X86/pr15267.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/pr15267.ll Thu May 21 05:05:03 2015
>> @@ -50,20 +50,22 @@ define <4 x i64> @test3(<4 x i1>* %in) n
>>  ; CHECK: movq
>>  ; CHECK: shlq
>>  ; CHECK: sarq
>> -; CHECK: vmovq
>>  ; CHECK: movq
>>  ; CHECK: shlq
>>  ; CHECK: sarq
>> -; CHECK: vmovq
>> -; CHECK: vpunpcklqdq
>> +; CHECK: vmovd
>> +; CHECK: vpinsrd
>>  ; CHECK: movq
>>  ; CHECK: shlq
>>  ; CHECK: sarq
>> -; CHECK: vmovq
>> +; CHECK: vpinsrd
>>  ; CHECK: shlq
>>  ; CHECK: sarq
>> -; CHECK: vmovq
>> -; CHECK: vpunpcklqdq
>> +; CHECK: vpinsrd
>> +; CHECK: vpmovsxdq
>> +; CHECK: vmovd
>> +; CHECK: vpinsrd
>> +; CHECK: vpmovsxdq
>>  ; CHECK: vinsertf128
>>  ; CHECK: ret
>>  
>> Modified: llvm/trunk/test/CodeGen/X86/vec_cast2.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_cast2.ll?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/X86/vec_cast2.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/vec_cast2.ll Thu May 21 05:05:03 2015
>> @@ -16,13 +16,9 @@ define <8 x float> @foo1_8(<8 x i8> %src
>>  ;
>>  ; CHECK-WIDE-LABEL: foo1_8:
>>  ; CHECK-WIDE:       ## BB#0:
>> -; CHECK-WIDE-NEXT:    vpmovzxbd {{.*#+}} xmm1 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
>> -; CHECK-WIDE-NEXT:    vpslld $24, %xmm1, %xmm1
>> -; CHECK-WIDE-NEXT:    vpsrad $24, %xmm1, %xmm1
>> -; CHECK-WIDE-NEXT:    vpunpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
>> -; CHECK-WIDE-NEXT:    vpunpckhwd {{.*#+}} xmm0 = xmm0[4,4,5,5,6,6,7,7]
>> -; CHECK-WIDE-NEXT:    vpslld $24, %xmm0, %xmm0
>> -; CHECK-WIDE-NEXT:    vpsrad $24, %xmm0, %xmm0
>> +; CHECK-WIDE-NEXT:    vpmovsxbd %xmm0, %xmm1
>> +; CHECK-WIDE-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
>> +; CHECK-WIDE-NEXT:    vpmovsxbd %xmm0, %xmm0
>>  ; CHECK-WIDE-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
>>  ; CHECK-WIDE-NEXT:    vcvtdq2ps %ymm0, %ymm0
>>  ; CHECK-WIDE-NEXT:    retl
>> @@ -40,9 +36,7 @@ define <4 x float> @foo1_4(<4 x i8> %src
>>  ;
>>  ; CHECK-WIDE-LABEL: foo1_4:
>>  ; CHECK-WIDE:       ## BB#0:
>> -; CHECK-WIDE-NEXT:    vpmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
>> -; CHECK-WIDE-NEXT:    vpslld $24, %xmm0, %xmm0
>> -; CHECK-WIDE-NEXT:    vpsrad $24, %xmm0, %xmm0
>> +; CHECK-WIDE-NEXT:    vpmovsxbd %xmm0, %xmm0
>>  ; CHECK-WIDE-NEXT:    vcvtdq2ps %xmm0, %xmm0
>>  ; CHECK-WIDE-NEXT:    retl
>>    %res = sitofp <4 x i8> %src to <4 x float>
>> 
>> Modified: llvm/trunk/test/CodeGen/X86/vector-sext.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-sext.ll?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/X86/vector-sext.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/vector-sext.ll Thu May 21 05:05:03 2015
>> @@ -10,37 +10,30 @@
>>  define <8 x i32> @sext_8i16_to_8i32(<8 x i16> %A) nounwind uwtable readnone ssp {
>>  ; SSE2-LABEL: sext_8i16_to_8i32:
>>  ; SSE2:       # BB#0: # %entry
>> -; SSE2-NEXT:    movdqa %xmm0, %xmm1
>> -; SSE2-NEXT:   # kill: XMM0<def> XMM1<kill>
>> -; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
>> -; SSE2-NEXT:    pslld $16, %xmm0
>> -; SSE2-NEXT:    psrad $16, %xmm0
>> -; SSE2-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7]
>> -; SSE2-NEXT:    pslld $16, %xmm1
>> +; SSE2-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
>> +; SSE2-NEXT:    psrad $16, %xmm2
>> +; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
>>  ; SSE2-NEXT:    psrad $16, %xmm1
>> +; SSE2-NEXT:    movdqa %xmm2, %xmm0
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: sext_8i16_to_8i32:
>>  ; SSSE3:       # BB#0: # %entry
>> -; SSSE3-NEXT:    movdqa %xmm0, %xmm1
>> -; SSSE3-NEXT:   # kill: XMM0<def> XMM1<kill>
>> -; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
>> -; SSSE3-NEXT:    pslld $16, %xmm0
>> -; SSSE3-NEXT:    psrad $16, %xmm0
>> -; SSSE3-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7]
>> -; SSSE3-NEXT:    pslld $16, %xmm1
>> +; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
>> +; SSSE3-NEXT:    psrad $16, %xmm2
>> +; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
>>  ; SSSE3-NEXT:    psrad $16, %xmm1
>> +; SSSE3-NEXT:    movdqa %xmm2, %xmm0
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: sext_8i16_to_8i32:
>>  ; SSE41:       # BB#0: # %entry
>> -; SSE41-NEXT:    movdqa %xmm0, %xmm1
>> -; SSE41-NEXT:    pmovzxwd %xmm1, %xmm0
>> -; SSE41-NEXT:    pslld $16, %xmm0
>> -; SSE41-NEXT:    psrad $16, %xmm0
>> -; SSE41-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7]
>> -; SSE41-NEXT:    pslld $16, %xmm1
>> -; SSE41-NEXT:    psrad $16, %xmm1
>> +; SSE41-NEXT:    pmovsxwd %xmm0, %xmm2
>> +; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; SSE41-NEXT:    pmovsxwd %xmm0, %xmm1
>> +; SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; SSE41-NEXT:    retq
>>  ;
>>  ; AVX1-LABEL: sext_8i16_to_8i32:
>> @@ -58,13 +51,10 @@ define <8 x i32> @sext_8i16_to_8i32(<8 x
>>  ;
>>  ; X32-SSE41-LABEL: sext_8i16_to_8i32:
>>  ; X32-SSE41:       # BB#0: # %entry
>> -; X32-SSE41-NEXT:    movdqa %xmm0, %xmm1
>> -; X32-SSE41-NEXT:    pmovzxwd %xmm1, %xmm0
>> -; X32-SSE41-NEXT:    pslld $16, %xmm0
>> -; X32-SSE41-NEXT:    psrad $16, %xmm0
>> -; X32-SSE41-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4,4,5,5,6,6,7,7]
>> -; X32-SSE41-NEXT:    pslld $16, %xmm1
>> -; X32-SSE41-NEXT:    psrad $16, %xmm1
>> +; X32-SSE41-NEXT:    pmovsxwd %xmm0, %xmm2
>> +; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; X32-SSE41-NEXT:    pmovsxwd %xmm0, %xmm1
>> +; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; X32-SSE41-NEXT:    retl
>>  entry:
>>    %B = sext <8 x i16> %A to <8 x i32>
>> @@ -74,68 +64,31 @@ entry:
>>  define <4 x i64> @sext_4i32_to_4i64(<4 x i32> %A) nounwind uwtable readnone ssp {
>>  ; SSE2-LABEL: sext_4i32_to_4i64:
>>  ; SSE2:       # BB#0: # %entry
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
>> -; SSE2-NEXT:    movd %xmm1, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm2
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
>> -; SSE2-NEXT:    movd %xmm1, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSE2-NEXT:    movd %xmm0, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> -; SSE2-NEXT:    movd %xmm0, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm0
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
>> -; SSE2-NEXT:    movdqa %xmm2, %xmm0
>> +; SSE2-NEXT:    movdqa %xmm0, %xmm2
>> +; SSE2-NEXT:    psrad $31, %xmm2
>> +; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
>> +; SSE2-NEXT:    movdqa %xmm1, %xmm2
>> +; SSE2-NEXT:    psrad $31, %xmm2
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: sext_4i32_to_4i64:
>>  ; SSSE3:       # BB#0: # %entry
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
>> -; SSSE3-NEXT:    movd %xmm1, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm2
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
>> -; SSSE3-NEXT:    movd %xmm1, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSSE3-NEXT:    movd %xmm0, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> -; SSSE3-NEXT:    movd %xmm0, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm0
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
>> -; SSSE3-NEXT:    movdqa %xmm2, %xmm0
>> +; SSSE3-NEXT:    movdqa %xmm0, %xmm2
>> +; SSSE3-NEXT:    psrad $31, %xmm2
>> +; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
>> +; SSSE3-NEXT:    movdqa %xmm1, %xmm2
>> +; SSSE3-NEXT:    psrad $31, %xmm2
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: sext_4i32_to_4i64:
>>  ; SSE41:       # BB#0: # %entry
>> -; SSE41-NEXT:    pmovzxdq %xmm0, %xmm1
>> -; SSE41-NEXT:    pextrq $1, %xmm1, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm3
>> -; SSE41-NEXT:    movd %xmm1, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm2
>> -; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
>> -; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSE41-NEXT:    pextrq $1, %xmm0, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm3
>> -; SSE41-NEXT:    movd %xmm0, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm1
>> -; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
>> +; SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
>> +; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
>>  ; SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; SSE41-NEXT:    retq
>>  ;
>> @@ -154,20 +107,9 @@ define <4 x i64> @sext_4i32_to_4i64(<4 x
>>  ;
>>  ; X32-SSE41-LABEL: sext_4i32_to_4i64:
>>  ; X32-SSE41:       # BB#0: # %entry
>> -; X32-SSE41-NEXT:    pmovzxdq %xmm0, %xmm2
>> -; X32-SSE41-NEXT:    movd %xmm2, %eax
>> -; X32-SSE41-NEXT:    sarl $31, %eax
>> -; X32-SSE41-NEXT:    pextrd $2, %xmm2, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $1, %eax, %xmm2
>> -; X32-SSE41-NEXT:    sarl $31, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $3, %ecx, %xmm2
>> -; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,2,3,3]
>> -; X32-SSE41-NEXT:    movd %xmm1, %eax
>> -; X32-SSE41-NEXT:    sarl $31, %eax
>> -; X32-SSE41-NEXT:    pextrd $2, %xmm1, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $1, %eax, %xmm1
>> -; X32-SSE41-NEXT:    sarl $31, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $3, %ecx, %xmm1
>> +; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
>> +; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
>>  ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; X32-SSE41-NEXT:    retl
>>  entry:
>> @@ -252,20 +194,26 @@ entry:
>>  define <2 x i64> @load_sext_test3(<2 x i8> *%ptr) {
>>  ; SSE2-LABEL: load_sext_test3:
>>  ; SSE2:       # BB#0: # %entry
>> -; SSE2-NEXT:    movsbq 1(%rdi), %rax
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    movsbq (%rdi), %rax
>> -; SSE2-NEXT:    movd %rax, %xmm0
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
>> +; SSE2-NEXT:    movzwl (%rdi), %eax
>> +; SSE2-NEXT:    movd %eax, %xmm0
>> +; SSE2-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
>> +; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
>> +; SSE2-NEXT:    movdqa %xmm0, %xmm1
>> +; SSE2-NEXT:    psrad $31, %xmm1
>> +; SSE2-NEXT:    psrad $24, %xmm0
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: load_sext_test3:
>>  ; SSSE3:       # BB#0: # %entry
>> -; SSSE3-NEXT:    movsbq 1(%rdi), %rax
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    movsbq (%rdi), %rax
>> -; SSSE3-NEXT:    movd %rax, %xmm0
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
>> +; SSSE3-NEXT:    movzwl (%rdi), %eax
>> +; SSSE3-NEXT:    movd %eax, %xmm0
>> +; SSSE3-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
>> +; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
>> +; SSSE3-NEXT:    movdqa %xmm0, %xmm1
>> +; SSSE3-NEXT:    psrad $31, %xmm1
>> +; SSSE3-NEXT:    psrad $24, %xmm0
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: load_sext_test3:
>> @@ -292,20 +240,22 @@ entry:
>>  define <2 x i64> @load_sext_test4(<2 x i16> *%ptr) {
>>  ; SSE2-LABEL: load_sext_test4:
>>  ; SSE2:       # BB#0: # %entry
>> -; SSE2-NEXT:    movswq 2(%rdi), %rax
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    movswq (%rdi), %rax
>> -; SSE2-NEXT:    movd %rax, %xmm0
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
>> +; SSE2-NEXT:    movd (%rdi), %xmm0
>> +; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
>> +; SSE2-NEXT:    movdqa %xmm0, %xmm1
>> +; SSE2-NEXT:    psrad $31, %xmm1
>> +; SSE2-NEXT:    psrad $16, %xmm0
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: load_sext_test4:
>>  ; SSSE3:       # BB#0: # %entry
>> -; SSSE3-NEXT:    movswq 2(%rdi), %rax
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    movswq (%rdi), %rax
>> -; SSSE3-NEXT:    movd %rax, %xmm0
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
>> +; SSSE3-NEXT:    movd (%rdi), %xmm0
>> +; SSSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3]
>> +; SSSE3-NEXT:    movdqa %xmm0, %xmm1
>> +; SSSE3-NEXT:    psrad $31, %xmm1
>> +; SSSE3-NEXT:    psrad $16, %xmm0
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: load_sext_test4:
>> @@ -332,20 +282,18 @@ entry:
>>  define <2 x i64> @load_sext_test5(<2 x i32> *%ptr) {
>>  ; SSE2-LABEL: load_sext_test5:
>>  ; SSE2:       # BB#0: # %entry
>> -; SSE2-NEXT:    movslq 4(%rdi), %rax
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    movslq (%rdi), %rax
>> -; SSE2-NEXT:    movd %rax, %xmm0
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
>> +; SSE2-NEXT:    movq (%rdi), %xmm0
>> +; SSE2-NEXT:    movdqa %xmm0, %xmm1
>> +; SSE2-NEXT:    psrad $31, %xmm1
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: load_sext_test5:
>>  ; SSSE3:       # BB#0: # %entry
>> -; SSSE3-NEXT:    movslq 4(%rdi), %rax
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    movslq (%rdi), %rax
>> -; SSSE3-NEXT:    movd %rax, %xmm0
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
>> +; SSSE3-NEXT:    movq (%rdi), %xmm0
>> +; SSSE3-NEXT:    movdqa %xmm0, %xmm1
>> +; SSSE3-NEXT:    psrad $31, %xmm1
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: load_sext_test5:
>> @@ -410,72 +358,35 @@ define <4 x i64> @sext_4i1_to_4i64(<4 x
>>  ; SSE2:       # BB#0:
>>  ; SSE2-NEXT:    pslld $31, %xmm0
>>  ; SSE2-NEXT:    psrad $31, %xmm0
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
>> -; SSE2-NEXT:    movd %xmm1, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm2
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
>> -; SSE2-NEXT:    movd %xmm1, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSE2-NEXT:    movd %xmm0, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> -; SSE2-NEXT:    movd %xmm0, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm0
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
>> -; SSE2-NEXT:    movdqa %xmm2, %xmm0
>> +; SSE2-NEXT:    movdqa %xmm0, %xmm2
>> +; SSE2-NEXT:    psrad $31, %xmm2
>> +; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
>> +; SSE2-NEXT:    movdqa %xmm1, %xmm2
>> +; SSE2-NEXT:    psrad $31, %xmm2
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: sext_4i1_to_4i64:
>>  ; SSSE3:       # BB#0:
>>  ; SSSE3-NEXT:    pslld $31, %xmm0
>>  ; SSSE3-NEXT:    psrad $31, %xmm0
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
>> -; SSSE3-NEXT:    movd %xmm1, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm2
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
>> -; SSSE3-NEXT:    movd %xmm1, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSSE3-NEXT:    movd %xmm0, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> -; SSSE3-NEXT:    movd %xmm0, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm0
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
>> -; SSSE3-NEXT:    movdqa %xmm2, %xmm0
>> +; SSSE3-NEXT:    movdqa %xmm0, %xmm2
>> +; SSSE3-NEXT:    psrad $31, %xmm2
>> +; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
>> +; SSSE3-NEXT:    movdqa %xmm1, %xmm2
>> +; SSSE3-NEXT:    psrad $31, %xmm2
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: sext_4i1_to_4i64:
>>  ; SSE41:       # BB#0:
>>  ; SSE41-NEXT:    pslld $31, %xmm0
>>  ; SSE41-NEXT:    psrad $31, %xmm0
>> -; SSE41-NEXT:    pmovzxdq %xmm0, %xmm1
>> -; SSE41-NEXT:    pextrq $1, %xmm1, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm3
>> -; SSE41-NEXT:    movd %xmm1, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm2
>> -; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
>> -; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSE41-NEXT:    pextrq $1, %xmm0, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm3
>> -; SSE41-NEXT:    movd %xmm0, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm1
>> -; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
>> +; SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
>> +; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
>>  ; SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; SSE41-NEXT:    retq
>>  ;
>> @@ -500,20 +411,9 @@ define <4 x i64> @sext_4i1_to_4i64(<4 x
>>  ; X32-SSE41:       # BB#0:
>>  ; X32-SSE41-NEXT:    pslld $31, %xmm0
>>  ; X32-SSE41-NEXT:    psrad $31, %xmm0
>> -; X32-SSE41-NEXT:    pmovzxdq %xmm0, %xmm2
>> -; X32-SSE41-NEXT:    movd %xmm2, %eax
>> -; X32-SSE41-NEXT:    sarl $31, %eax
>> -; X32-SSE41-NEXT:    pextrd $2, %xmm2, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $1, %eax, %xmm2
>> -; X32-SSE41-NEXT:    sarl $31, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $3, %ecx, %xmm2
>> -; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,2,3,3]
>> -; X32-SSE41-NEXT:    movd %xmm1, %eax
>> -; X32-SSE41-NEXT:    sarl $31, %eax
>> -; X32-SSE41-NEXT:    pextrd $2, %xmm1, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $1, %eax, %xmm1
>> -; X32-SSE41-NEXT:    sarl $31, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $3, %ecx, %xmm1
>> +; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
>> +; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
>>  ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; X32-SSE41-NEXT:    retl
>>    %extmask = sext <4 x i1> %mask to <4 x i64>
>> @@ -576,72 +476,35 @@ define <4 x i64> @sext_4i8_to_4i64(<4 x
>>  ; SSE2:       # BB#0:
>>  ; SSE2-NEXT:    pslld $24, %xmm0
>>  ; SSE2-NEXT:    psrad $24, %xmm0
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
>> -; SSE2-NEXT:    movd %xmm1, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm2
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
>> -; SSE2-NEXT:    movd %xmm1, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSE2-NEXT:    movd %xmm0, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm1
>> -; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> -; SSE2-NEXT:    movd %xmm0, %rax
>> -; SSE2-NEXT:    cltq
>> -; SSE2-NEXT:    movd %rax, %xmm0
>> -; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
>> -; SSE2-NEXT:    movdqa %xmm2, %xmm0
>> +; SSE2-NEXT:    movdqa %xmm0, %xmm2
>> +; SSE2-NEXT:    psrad $31, %xmm2
>> +; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
>> +; SSE2-NEXT:    movdqa %xmm1, %xmm2
>> +; SSE2-NEXT:    psrad $31, %xmm2
>> +; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
>>  ; SSE2-NEXT:    retq
>>  ;
>>  ; SSSE3-LABEL: sext_4i8_to_4i64:
>>  ; SSSE3:       # BB#0:
>>  ; SSSE3-NEXT:    pslld $24, %xmm0
>>  ; SSSE3-NEXT:    psrad $24, %xmm0
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,1,1,3]
>> -; SSSE3-NEXT:    movd %xmm1, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm2
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
>> -; SSSE3-NEXT:    movd %xmm1, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSSE3-NEXT:    movd %xmm0, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm1
>> -; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> -; SSSE3-NEXT:    movd %xmm0, %rax
>> -; SSSE3-NEXT:    cltq
>> -; SSSE3-NEXT:    movd %rax, %xmm0
>> -; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
>> -; SSSE3-NEXT:    movdqa %xmm2, %xmm0
>> +; SSSE3-NEXT:    movdqa %xmm0, %xmm2
>> +; SSSE3-NEXT:    psrad $31, %xmm2
>> +; SSSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
>> +; SSSE3-NEXT:    movdqa %xmm1, %xmm2
>> +; SSSE3-NEXT:    psrad $31, %xmm2
>> +; SSSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
>>  ; SSSE3-NEXT:    retq
>>  ;
>>  ; SSE41-LABEL: sext_4i8_to_4i64:
>>  ; SSE41:       # BB#0:
>>  ; SSE41-NEXT:    pslld $24, %xmm0
>>  ; SSE41-NEXT:    psrad $24, %xmm0
>> -; SSE41-NEXT:    pmovzxdq %xmm0, %xmm1
>> -; SSE41-NEXT:    pextrq $1, %xmm1, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm3
>> -; SSE41-NEXT:    movd %xmm1, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm2
>> -; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
>> -; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,2,3,3]
>> -; SSE41-NEXT:    pextrq $1, %xmm0, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm3
>> -; SSE41-NEXT:    movd %xmm0, %rax
>> -; SSE41-NEXT:    cltq
>> -; SSE41-NEXT:    movd %rax, %xmm1
>> -; SSE41-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
>> +; SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
>> +; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
>>  ; SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; SSE41-NEXT:    retq
>>  ;
>> @@ -666,20 +529,9 @@ define <4 x i64> @sext_4i8_to_4i64(<4 x
>>  ; X32-SSE41:       # BB#0:
>>  ; X32-SSE41-NEXT:    pslld $24, %xmm0
>>  ; X32-SSE41-NEXT:    psrad $24, %xmm0
>> -; X32-SSE41-NEXT:    pmovzxdq %xmm0, %xmm2
>> -; X32-SSE41-NEXT:    movd %xmm2, %eax
>> -; X32-SSE41-NEXT:    sarl $31, %eax
>> -; X32-SSE41-NEXT:    pextrd $2, %xmm2, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $1, %eax, %xmm2
>> -; X32-SSE41-NEXT:    sarl $31, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $3, %ecx, %xmm2
>> -; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,2,3,3]
>> -; X32-SSE41-NEXT:    movd %xmm1, %eax
>> -; X32-SSE41-NEXT:    sarl $31, %eax
>> -; X32-SSE41-NEXT:    pextrd $2, %xmm1, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $1, %eax, %xmm1
>> -; X32-SSE41-NEXT:    sarl $31, %ecx
>> -; X32-SSE41-NEXT:    pinsrd $3, %ecx, %xmm1
>> +; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm2
>> +; X32-SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; X32-SSE41-NEXT:    pmovsxdq %xmm0, %xmm1
>>  ; X32-SSE41-NEXT:    movdqa %xmm2, %xmm0
>>  ; X32-SSE41-NEXT:    retl
>>    %extmask = sext <4 x i8> %mask to <4 x i64>
>> 
>> Modified: llvm/trunk/test/CodeGen/X86/vselect-avx.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vselect-avx.ll?rev=237885&r1=237884&r2=237885&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/X86/vselect-avx.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/vselect-avx.ll Thu May 21 05:05:03 2015
>> @@ -14,8 +14,8 @@ target triple = "x86_64-apple-macosx"
>>  ; <rdar://problem/18675020>
>>    ; CHECK-LABEL: test:
>> -; CHECK: vmovdqa {{.*#+}} xmm0 = [65535,0,0,65535]
>> -; CHECK: vmovdqa {{.*#+}} xmm2 = [65533,124,125,14807]
>> +; CHECK: vmovdqa {{.*#+}} xmm1 = [65533,124,125,14807]
>> +; CHECK: vmovdqa {{.*#+}} xmm1 = [65535,0,0,65535]
>>  ; CHECK: ret
>>  define void @test(<4 x i16>* %a, <4 x i16>* %b) {
>>  body:
>> @@ -33,13 +33,14 @@ body:
>>  ; of the condition.
>>  ;
>>  ; CHECK-LABEL: test2:
>> -; CHECK:	vpslld	$31, %xmm0, %xmm0
>> -; CHECK-NEXT:	vpmovsxdq	%xmm0, %xmm1
>> -; CHECK-NEXT:	vpshufd	$78, %xmm0, %xmm0       ## xmm0 = xmm0[2,3,0,1]
>> -; CHECK-NEXT:	vpmovsxdq	%xmm0, %xmm0
>> -; CHECK-NEXT:	vinsertf128	$1, %xmm0, %ymm1, [[MASK:%ymm[0-9]+]]
>> -; CHECK: vblendvpd	[[MASK]]
>> -; CHECK: retq
>> +; CHECK:       vpslld $31, %xmm0, %xmm0
>> +; CHECK-NEXT:  vpsrad $31, %xmm0, %xmm0
>> +; CHECK-NEXT:  vpmovsxdq %xmm0, %xmm1
>> +; CHECK-NEXT:  vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
>> +; CHECK-NEXT:  vpmovsxdq %xmm0, %xmm0
>> +; CHECK-NEXT:  vinsertf128 $1, %xmm0, %ymm1, [[MASK:%ymm[0-9]+]]
>> +; CHECK:       vblendvpd [[MASK]]
>> +; CHECK:       retq
>>  define void @test2(double** %call1559, i64 %indvars.iv4198, <4 x i1> %tmp1895) {
>>  bb:
>>    %arrayidx1928 = getelementptr inbounds double*, double** %call1559, i64 %indvars.iv4198
>> 
>> 
>> 
>> From llvm-dev at redking.me.uk  Thu May 21 05:09:02 2015
>> From: llvm-dev at redking.me.uk (Simon Pilgrim)
>> Date: Thu, 21 May 2015 10:09:02 +0000
>> Subject: [PATCH] [X86][SSE] Improve support for 128-bit vector sign
>> 	extension
>> In-Reply-To: <differential-rev-PHID-DREV-v6d4a4rfprovxsxay5cu-req at reviews.llvm.org>
>> References: <differential-rev-PHID-DREV-v6d4a4rfprovxsxay5cu-req at reviews.llvm.org>
>> Message-ID: <1ac2e484efd8d9e72036190b7ff70c0f at localhost.localdomain>
>> 
>> REPOSITORY
>>   rL LLVM
>> 
>> http://reviews.llvm.org/D9848
>> 
>> Files:
>>   llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>>   llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>>   llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>   llvm/trunk/test/CodeGen/X86/pr15267.ll
>>   llvm/trunk/test/CodeGen/X86/vec_cast2.ll
>>   llvm/trunk/test/CodeGen/X86/vector-sext.ll
>>   llvm/trunk/test/CodeGen/X86/vselect-avx.ll
> 
> -- 
> Jeroen Ketema - Senior Software Engineer, Compilers
> Codeplay Software Ltd.
> 45 York Place, Edinburgh, EH1 3HP
> Tel: 0131 466 0503
> Fax: 0131 557 6600
> Website: http://www.codeplay.com
> Twitter: https://twitter.com/codeplaysoft
> 
> This email and any attachments may contain confidential and /or privileged
> information and is for use by the addressee only. If you are not the intended
> recipient, please notify Codeplay Software Ltd immediately and delete the message
> from your computer. You may not copy or forward it,or use or disclose its contents
> to any other person. Any views or other information in this message which do not
> relate to our business are not authorized by Codeplay software Ltd, nor does this
> message form part of any contract unless so stated.
> 
> As internet communications are capable of data corruption Codeplay Software Ltd does
> not accept any responsibility for any changes made to this message after it was
> sent. Please note that Codeplay Software Ltd does not accept any liability or
> responsibility for viruses and it is your responsibility to scan any attachments.
> 
> Company registered in England and Wales, number: 04567874
> Registered office: 81 Linkfield Street, Redhill RH1 6BY
> 
> 





More information about the llvm-commits mailing list