From eb99165b97b79c3ccc7b5ebcd445a98b4240e171 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 15 Jul 2019 18:17:23 +0000 Subject: [x86] try to keep FP casted+truncated+extracted vector element out of GPRs inttofp (trunc (extelt X, 0)) --> inttofp (extelt (bitcast X), 0) We have pseudo-vectorization of scalar int to FP casts, so this tries to make that more likely by replacing a truncate with a bitcast. I didn't see any test diffs starting from 'uitofp', so I left that as a TODO. We can't only match the shorter trunc+extract pattern because there's an opposing transform somewhere, so we infinite loop. Waiting to try this during lowering is another possibility. A motivating case is shown in PR39975 and included in the test diffs here: https://bugs.llvm.org/show_bug.cgi?id=39975 Differential Revision: https://reviews.llvm.org/D64710 llvm-svn: 366098 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'llvm/lib') diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 47389f2df32..34a85806f56 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -42430,6 +42430,41 @@ static SDValue combineVectorCompareAndMaskUnaryOp(SDNode *N, return SDValue(); } +/// If we are converting a value to floating-point, try to replace scalar +/// truncate of an extracted vector element with a bitcast. This tries to keep +/// the sequence on XMM registers rather than moving between vector and GPRs. +static SDValue combineToFPTruncExtElt(SDNode *N, SelectionDAG &DAG) { + // TODO: This is currently only used by combineSIntToFP, but it is generalized + // to allow being called by any similar cast opcode. + // TODO: Consider merging this into lowering: vectorizeExtractedCast(). + SDValue Trunc = N->getOperand(0); + if (!Trunc.hasOneUse() || Trunc.getOpcode() != ISD::TRUNCATE) + return SDValue(); + + SDValue ExtElt = Trunc.getOperand(0); + if (!ExtElt.hasOneUse() || ExtElt.getOpcode() != ISD::EXTRACT_VECTOR_ELT || + !isNullConstant(ExtElt.getOperand(1))) + return SDValue(); + + EVT TruncVT = Trunc.getValueType(); + EVT SrcVT = ExtElt.getValueType(); + unsigned DestWidth = TruncVT.getSizeInBits(); + unsigned SrcWidth = SrcVT.getSizeInBits(); + if (SrcWidth % DestWidth != 0) + return SDValue(); + + // inttofp (trunc (extelt X, 0)) --> inttofp (extelt (bitcast X), 0) + EVT SrcVecVT = ExtElt.getOperand(0).getValueType(); + unsigned VecWidth = SrcVecVT.getSizeInBits(); + unsigned NumElts = VecWidth / DestWidth; + EVT BitcastVT = EVT::getVectorVT(*DAG.getContext(), TruncVT, NumElts); + SDValue BitcastVec = DAG.getBitcast(BitcastVT, ExtElt.getOperand(0)); + SDLoc DL(N); + SDValue NewExtElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, TruncVT, + BitcastVec, ExtElt.getOperand(1)); + return DAG.getNode(N->getOpcode(), DL, N->getValueType(0), NewExtElt); +} + static SDValue combineUIntToFP(SDNode *N, SelectionDAG &DAG, const X86Subtarget &Subtarget) { SDValue Op0 = N->getOperand(0); @@ -42523,6 +42558,10 @@ static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG, return FILDChain; } } + + if (SDValue V = combineToFPTruncExtElt(N, DAG)) + return V; + return SDValue(); } -- cgit v1.2.3