summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp21
1 files changed, 19 insertions, 2 deletions
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<SDValue, 5> 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);
OpenPOWER on IntegriCloud