diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 28 | 
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f654f1d7a72..9f6a0b76e06 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -44659,6 +44659,34 @@ static SDValue combinePMULDQ(SDNode *N, SelectionDAG &DAG,    if (TLI.SimplifyDemandedBits(SDValue(N, 0), APInt::getAllOnesValue(64), DCI))      return SDValue(N, 0); +  // If the input is an extend_invec and the SimplifyDemandedBits call didn't +  // convert it to any_extend_invec, due to the LegalOperations check, do the +  // conversion directly to a vector shuffle manually. This exposes combine +  // opportunities missed by combineExtInVec not calling +  // combineX86ShufflesRecursively on SSE4.1 targets. +  // FIXME: This is basically a hack around several other issues related to +  // ANY_EXTEND_VECTOR_INREG. +  if (N->getValueType(0) == MVT::v2i64 && LHS.hasOneUse() && +      (LHS.getOpcode() == ISD::ZERO_EXTEND_VECTOR_INREG || +       LHS.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG) && +      LHS.getOperand(0).getValueType() == MVT::v4i32) { +    SDLoc dl(N); +    LHS = DAG.getVectorShuffle(MVT::v4i32, dl, LHS.getOperand(0), +                               LHS.getOperand(0), { 0, -1, 1, -1 }); +    LHS = DAG.getBitcast(MVT::v2i64, LHS); +    return DAG.getNode(N->getOpcode(), dl, MVT::v2i64, LHS, RHS); +  } +  if (N->getValueType(0) == MVT::v2i64 && RHS.hasOneUse() && +      (RHS.getOpcode() == ISD::ZERO_EXTEND_VECTOR_INREG || +       RHS.getOpcode() == ISD::SIGN_EXTEND_VECTOR_INREG) && +      RHS.getOperand(0).getValueType() == MVT::v4i32) { +    SDLoc dl(N); +    RHS = DAG.getVectorShuffle(MVT::v4i32, dl, RHS.getOperand(0), +                               RHS.getOperand(0), { 0, -1, 1, -1 }); +    RHS = DAG.getBitcast(MVT::v2i64, RHS); +    return DAG.getNode(N->getOpcode(), dl, MVT::v2i64, LHS, RHS); +  } +    return SDValue();  }  | 

