diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 880db37675f..ecda6f536bf 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -35032,6 +35032,53 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG, St->getAlignment(), St->getMemOperand()->getFlags()); } + // Widen v2i1/v4i1 stores to v8i1. + if ((VT == MVT::v2i1 || VT == MVT::v4i1) && VT == StVT && + Subtarget.hasAVX512()) { + unsigned NumConcats = 8 / VT.getVectorNumElements(); + SmallVector<SDValue, 4> Ops(NumConcats, DAG.getUNDEF(VT)); + Ops[0] = StoredVal; + StoredVal = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v8i1, Ops); + return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(), + St->getPointerInfo(), St->getAlignment(), + St->getMemOperand()->getFlags()); + } + + // Turn vXi1 stores of constants into a scalar store. + if ((VT == MVT::v8i1 || VT == MVT::v16i1 || VT == MVT::v32i1 || + VT == MVT::v64i1) && VT == StVT && TLI.isTypeLegal(VT) && + ISD::isBuildVectorOfConstantSDNodes(StoredVal.getNode())) { + // If its a v64i1 store without 64-bit support, we need two stores. + if (VT == MVT::v64i1 && !Subtarget.is64Bit()) { + SDValue Lo = DAG.getBuildVector(MVT::v32i1, dl, + StoredVal->ops().slice(0, 32)); + Lo = combinevXi1ConstantToInteger(Lo, DAG); + SDValue Hi = DAG.getBuildVector(MVT::v32i1, dl, + StoredVal->ops().slice(32, 32)); + Hi = combinevXi1ConstantToInteger(Hi, DAG); + + unsigned Alignment = St->getAlignment(); + + SDValue Ptr0 = St->getBasePtr(); + SDValue Ptr1 = DAG.getMemBasePlusOffset(Ptr0, 4, dl); + + SDValue Ch0 = + DAG.getStore(St->getChain(), dl, Lo, Ptr0, St->getPointerInfo(), + Alignment, St->getMemOperand()->getFlags()); + SDValue Ch1 = + DAG.getStore(St->getChain(), dl, Hi, Ptr1, + St->getPointerInfo().getWithOffset(4), + MinAlign(Alignment, 4U), + St->getMemOperand()->getFlags()); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ch0, Ch1); + } + + StoredVal = combinevXi1ConstantToInteger(StoredVal, DAG); + return DAG.getStore(St->getChain(), dl, StoredVal, St->getBasePtr(), + St->getPointerInfo(), St->getAlignment(), + St->getMemOperand()->getFlags()); + } + // If we are saving a concatenation of two XMM registers and 32-byte stores // are slow, such as on Sandy Bridge, perform two 16-byte stores. bool Fast; |