From e85ff4f732627c664778a3d07adbb8106769d92d Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 16 Nov 2017 20:23:22 +0000 Subject: [X86] Pre-truncate gather/scatter indices that have element sizes larger than 64-bits before Legalize. The wider element type will normally cause legalize to try to split and scalarize the gather/scatter, but we can't handle that. Instead, truncate the index early so the gather/scatter node is insulated from the legalization. This really shouldn't happen in practice since InstCombine will normalize index types to the same size as pointers. llvm-svn: 318452 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'llvm/lib/Target/X86') diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 67420fe0ea3..5c2e13134df 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -35829,8 +35829,25 @@ static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG, return SDValue(); } -static SDValue combineGatherScatter(SDNode *N, SelectionDAG &DAG) { +static SDValue combineGatherScatter(SDNode *N, SelectionDAG &DAG, + TargetLowering::DAGCombinerInfo &DCI) { SDLoc DL(N); + + // Pre-shrink oversized index elements to avoid triggering scalarization. + if (DCI.isBeforeLegalize()) { + SDValue Index = N->getOperand(4); + if (Index.getValueType().getScalarSizeInBits() > 64) { + EVT IndexVT = EVT::getVectorVT(*DAG.getContext(), MVT::i64, + Index.getValueType().getVectorNumElements()); + SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, IndexVT, Index); + SmallVector NewOps(N->op_begin(), N->op_end()); + NewOps[4] = Trunc; + DAG.UpdateNodeOperands(N, NewOps); + DCI.AddToWorklist(N); + return SDValue(N, 0); + } + } + // Gather and Scatter instructions use k-registers for masks. The type of // the masks is v*i1. So the mask will be truncated anyway. // The SIGN_EXTEND_INREG my be dropped. @@ -36949,7 +36966,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, case X86ISD::FMADDSUB: case X86ISD::FMSUBADD: return combineFMADDSUB(N, DAG, Subtarget); case ISD::MGATHER: - case ISD::MSCATTER: return combineGatherScatter(N, DAG); + case ISD::MSCATTER: return combineGatherScatter(N, DAG, DCI); case X86ISD::TESTM: return combineTestM(N, DAG, Subtarget); case X86ISD::PCMPEQ: case X86ISD::PCMPGT: return combineVectorCompare(N, DAG, Subtarget); -- cgit v1.2.3