summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 159ce60af45..4331cb9c231 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -40179,6 +40179,41 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
MVT::v16i8, St->getMemOperand());
}
+ // Look for a truncating store to a less than 128 bit vector that has been
+ // truncated from an any_extend_inreg from a 128 bit vector with the same
+ // element size. We can use a 64/32/16-bit extractelement and store that.
+ // Disabling this when widening legalization is in effect since the trunc
+ // store would have been unlikely to be created in that case. Only doing this
+ // when truncstore is legal since it would otherwise be decomposed below and
+ // then combined away.
+ if (St->isTruncatingStore() && TLI.isTruncStoreLegal(VT, StVT) &&
+ StoredVal.getOpcode() == ISD::ANY_EXTEND_VECTOR_INREG &&
+ StoredVal.getValueType().is128BitVector() &&
+ !ExperimentalVectorWideningLegalization) {
+ EVT OrigVT = StoredVal.getOperand(0).getValueType();
+ if (OrigVT.is128BitVector() &&
+ OrigVT.getVectorElementType() == StVT.getVectorElementType()) {
+ unsigned StoreSize = StVT.getSizeInBits();
+ assert((128 % StoreSize == 0) && "Unexpected store size!");
+ MVT IntVT = MVT::getIntegerVT(StoreSize);
+ MVT CastVT = MVT::getVectorVT(IntVT, 128 / StoreSize);
+ StoredVal = DAG.getBitcast(CastVT, StoredVal.getOperand(0));
+ // Use extract_store for the 64-bit case to support 32-bit targets.
+ if (IntVT == MVT::i64) {
+ SDVTList Tys = DAG.getVTList(MVT::Other);
+ SDValue Ops[] = {St->getChain(), StoredVal, St->getBasePtr()};
+ return DAG.getMemIntrinsicNode(X86ISD::VEXTRACT_STORE, dl, Tys, Ops,
+ IntVT, St->getMemOperand());
+ }
+
+ // Otherwise just use an extract and store.
+ StoredVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, IntVT, StoredVal,
+ DAG.getIntPtrConstant(0, dl));
+ return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(),
+ St->getMemOperand());
+ }
+ }
+
// Optimize trunc store (of multiple scalars) to shuffle and store.
// First, pack all of the elements in one place. Next, store to memory
// in fewer chunks.
OpenPOWER on IntegriCloud