<div dir="ltr">Thanks!</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-07-18 4:27 GMT+04:00 Michael Spencer <span dir="ltr"><<a href="mailto:bigcheesegs@gmail.com" target="_blank">bigcheesegs@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">- Michael Spencer<br>
<div class=""><br>
<br>
On Thu, Jul 17, 2014 at 10:19 AM, Michael Spencer <<a href="mailto:bigcheesegs@gmail.com">bigcheesegs@gmail.com</a>> wrote:<br>
> On Thu, Jul 17, 2014 at 10:07 AM, Robert Khasanov<br>
> <<a href="mailto:rob.khasanov@gmail.com">rob.khasanov@gmail.com</a>> wrote:<br>
>> Michael,<br>
>><br>
>> Could you provide conservative fix for this bug?<br>
><br>
> I'll either fix it or revert the original change today.<br>
><br>
> - Michael Spencer<br>
<br>
</div>Reverted in r213339. Will fix and recommit soon.<br>
<div class="HOEnZb"><div class="h5"><br>
- Michael Spencer<br>
<br>
><br>
>><br>
>><br>
>> 2014-07-12 2:07 GMT+04:00 Michael Spencer <<a href="mailto:bigcheesegs@gmail.com">bigcheesegs@gmail.com</a>>:<br>
>><br>
>>> On Fri, Jul 11, 2014 at 12:47 PM, Michael Spencer <<a href="mailto:bigcheesegs@gmail.com">bigcheesegs@gmail.com</a>><br>
>>> wrote:<br>
>>> > On Fri, Jul 11, 2014 at 5:36 AM, Dmitry Babokin <<a href="mailto:babokin@gmail.com">babokin@gmail.com</a>><br>
>>> > wrote:<br>
>>> >> Michael,<br>
>>> >><br>
>>> >> Your commit caused a regression described in bug 20115, could you have<br>
>>> >> a<br>
>>> >> look?<br>
>>> >><br>
>>> >> Dmitry<br>
>>> ><br>
>>> > Investigating now. Thanks for letting me know.<br>
>>> ><br>
>>> > - Michael Spencer<br>
>>><br>
>>> It seems that it creates a dependency loop by moving the use of<br>
>>> %POINT_VALUE from the extractelement up to the original load across<br>
>>> the lifetime end marker. In this specific case that would be fine if<br>
>>> the chains were fixed, but I don't believe it's always valid. I think<br>
>>> the conservative fix here is to not do this optimization if you would<br>
>>> have to move a load or an operation with possible side effects.<br>
>>><br>
>>> - Michael Spencer<br>
>>><br>
>>> ><br>
>>> >><br>
>>> >><br>
>>> >> On Thu, May 29, 2014 at 5:42 AM, Michael J. Spencer<br>
>>> >> <<a href="mailto:bigcheesegs@gmail.com">bigcheesegs@gmail.com</a>><br>
>>> >> wrote:<br>
>>> >>><br>
>>> >>> Author: mspencer<br>
>>> >>> Date: Wed May 28 20:42:45 2014<br>
>>> >>> New Revision: 209788<br>
>>> >>><br>
>>> >>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=209788&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=209788&view=rev</a><br>
>>> >>> Log:<br>
>>> >>> [x86] Fold extract_vector_elt of a load into the Load's address<br>
>>> >>> computation.<br>
>>> >>><br>
>>> >>> An address only use of an extract element of a load can be simplified<br>
>>> >>> to a<br>
>>> >>> load. Without this the result of the extract element is spilled to the<br>
>>> >>> stack so that an address is available.<br>
>>> >>><br>
>>> >>> Modified:<br>
>>> >>> Â  Â  llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp<br>
>>> >>> Â  Â  llvm/trunk/test/CodeGen/X86/vec_splat.ll<br>
>>> >>><br>
>>> >>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp<br>
>>> >>> URL:<br>
>>> >>><br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=209788&r1=209787&r2=209788&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=209788&r1=209787&r2=209788&view=diff</a><br>

>>> >>><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)<br>
>>> >>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed May 28<br>
>>> >>> 20:42:45 2014<br>
>>> >>> @@ -169,6 +169,16 @@ namespace {<br>
>>> >>> Â  Â  Â bool CombineToPostIndexedLoadStore(SDNode *N);<br>
>>> >>> Â  Â  Â bool SliceUpLoad(SDNode *N);<br>
>>> >>><br>
>>> >>> + Â  Â /// \brief Replace an ISD::EXTRACT_VECTOR_ELT of a load with a<br>
>>> >>> narrowed<br>
>>> >>> + Â  Â /// Â  load.<br>
>>> >>> + Â  Â ///<br>
>>> >>> + Â  Â /// \param EVE ISD::EXTRACT_VECTOR_ELT to be replaced.<br>
>>> >>> + Â  Â /// \param InVecVT type of the input vector to EVE with bitcasts<br>
>>> >>> resolved.<br>
>>> >>> + Â  Â /// \param EltNo index of the vector element to load.<br>
>>> >>> + Â  Â /// \param OriginalLoad load that EVE came from to be replaced.<br>
>>> >>> + Â  Â /// \returns EVE on success SDValue() on failure.<br>
>>> >>> + Â  Â SDValue ReplaceExtractVectorEltOfLoadWithNarrowedLoad(<br>
>>> >>> + Â  Â  Â  Â SDNode *EVE, EVT InVecVT, SDValue EltNo, LoadSDNode<br>
>>> >>> *OriginalLoad);<br>
>>> >>> Â  Â  Â void ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad);<br>
>>> >>> Â  Â  Â SDValue PromoteOperand(SDValue Op, EVT PVT, bool &Replace);<br>
>>> >>> Â  Â  Â SDValue SExtPromoteOperand(SDValue Op, EVT PVT);<br>
>>> >>> @@ -9675,6 +9685,86 @@ SDValue DAGCombiner::visitINSERT_VECTOR_<br>
>>> >>> Â  Â return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);<br>
>>> >>> Â }<br>
>>> >>><br>
>>> >>> +SDValue DAGCombiner::ReplaceExtractVectorEltOfLoadWithNarrowedLoad(<br>
>>> >>> + Â  Â SDNode *EVE, EVT InVecVT, SDValue EltNo, LoadSDNode<br>
>>> >>> *OriginalLoad) {<br>
>>> >>> + Â EVT ResultVT = EVE->getValueType(0);<br>
>>> >>> + Â EVT VecEltVT = InVecVT.getVectorElementType();<br>
>>> >>> + Â unsigned Align = OriginalLoad->getAlignment();<br>
>>> >>> + Â unsigned NewAlign = TLI.getDataLayout()->getABITypeAlignment(<br>
>>> >>> + Â  Â  Â VecEltVT.getTypeForEVT(*DAG.getContext()));<br>
>>> >>> +<br>
>>> >>> + Â if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD,<br>
>>> >>> VecEltVT))<br>
>>> >>> + Â  Â return SDValue();<br>
>>> >>> +<br>
>>> >>> + Â Align = NewAlign;<br>
>>> >>> +<br>
>>> >>> + Â SDValue NewPtr = OriginalLoad->getBasePtr();<br>
>>> >>> + Â SDValue Offset;<br>
>>> >>> + Â EVT PtrType = NewPtr.getValueType();<br>
>>> >>> + Â MachinePointerInfo MPI;<br>
>>> >>> + Â if (auto *ConstEltNo = dyn_cast<ConstantSDNode>(EltNo)) {<br>
>>> >>> + Â  Â int Elt = ConstEltNo->getZExtValue();<br>
>>> >>> + Â  Â unsigned PtrOff = VecEltVT.getSizeInBits() * Elt / 8;<br>
>>> >>> + Â  Â if (TLI.isBigEndian())<br>
>>> >>> + Â  Â  Â PtrOff = InVecVT.getSizeInBits() / 8 - PtrOff;<br>
>>> >>> + Â  Â Offset = DAG.getConstant(PtrOff, PtrType);<br>
>>> >>> + Â  Â MPI = OriginalLoad->getPointerInfo().getWithOffset(PtrOff);<br>
>>> >>> + Â } else {<br>
>>> >>> + Â  Â Offset = DAG.getNode(<br>
>>> >>> + Â  Â  Â  Â ISD::MUL, SDLoc(EVE), EltNo.getValueType(), EltNo,<br>
>>> >>> + Â  Â  Â  Â DAG.getConstant(VecEltVT.getStoreSize(),<br>
>>> >>> EltNo.getValueType()));<br>
>>> >>> + Â  Â if (TLI.isBigEndian())<br>
>>> >>> + Â  Â  Â Offset = DAG.getNode(<br>
>>> >>> + Â  Â  Â  Â  Â ISD::SUB, SDLoc(EVE), EltNo.getValueType(),<br>
>>> >>> + Â  Â  Â  Â  Â DAG.getConstant(InVecVT.getStoreSize(),<br>
>>> >>> EltNo.getValueType()),<br>
>>> >>> Offset);<br>
>>> >>> + Â  Â MPI = OriginalLoad->getPointerInfo();<br>
>>> >>> + Â }<br>
>>> >>> + Â NewPtr = DAG.getNode(ISD::ADD, SDLoc(EVE), PtrType, NewPtr,<br>
>>> >>> Offset);<br>
>>> >>> +<br>
>>> >>> + Â // The replacement we need to do here is a little tricky: we need<br>
>>> >>> to<br>
>>> >>> + Â // replace an extractelement of a load with a load.<br>
>>> >>> + Â // Use ReplaceAllUsesOfValuesWith to do the replacement.<br>
>>> >>> + Â // Note that this replacement assumes that the extractvalue is the<br>
>>> >>> only<br>
>>> >>> + Â // use of the load; that's okay because we don't want to perform<br>
>>> >>> this<br>
>>> >>> + Â // transformation in other cases anyway.<br>
>>> >>> + Â SDValue Load;<br>
>>> >>> + Â SDValue Chain;<br>
>>> >>> + Â if (ResultVT.bitsGT(VecEltVT)) {<br>
>>> >>> + Â  Â // If the result type of vextract is wider than the load, then<br>
>>> >>> issue<br>
>>> >>> an<br>
>>> >>> + Â  Â // extending load instead.<br>
>>> >>> + Â  Â ISD::LoadExtType ExtType = TLI.isLoadExtLegal(ISD::ZEXTLOAD,<br>
>>> >>> VecEltVT)<br>
>>> >>> + Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  ? ISD::ZEXTLOAD<br>
>>> >>> + Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  : ISD::EXTLOAD;<br>
>>> >>> + Â  Â Load = DAG.getExtLoad(ExtType, SDLoc(EVE), ResultVT,<br>
>>> >>> OriginalLoad->getChain(),<br>
>>> >>> + Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â NewPtr, MPI, VecEltVT,<br>
>>> >>> OriginalLoad->isVolatile(),<br>
>>> >>> + Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â OriginalLoad->isNonTemporal(), Align,<br>
>>> >>> + Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â OriginalLoad->getTBAAInfo());<br>
>>> >>> + Â  Â Chain = Load.getValue(1);<br>
>>> >>> + Â } else {<br>
>>> >>> + Â  Â Load = DAG.getLoad(<br>
>>> >>> + Â  Â  Â  Â VecEltVT, SDLoc(EVE), OriginalLoad->getChain(), NewPtr, MPI,<br>
>>> >>> + Â  Â  Â  Â OriginalLoad->isVolatile(), OriginalLoad->isNonTemporal(),<br>
>>> >>> + Â  Â  Â  Â OriginalLoad->isInvariant(), Align,<br>
>>> >>> OriginalLoad->getTBAAInfo());<br>
>>> >>> + Â  Â Chain = Load.getValue(1);<br>
>>> >>> + Â  Â if (ResultVT.bitsLT(VecEltVT))<br>
>>> >>> + Â  Â  Â Load = DAG.getNode(ISD::TRUNCATE, SDLoc(EVE), ResultVT, Load);<br>
>>> >>> + Â  Â else<br>
>>> >>> + Â  Â  Â Load = DAG.getNode(ISD::BITCAST, SDLoc(EVE), ResultVT, Load);<br>
>>> >>> + Â }<br>
>>> >>> + Â WorkListRemover DeadNodes(*this);<br>
>>> >>> + Â SDValue From[] = { SDValue(EVE, 0), SDValue(OriginalLoad, 1) };<br>
>>> >>> + Â SDValue To[] = { Load, Chain };<br>
>>> >>> + Â DAG.ReplaceAllUsesOfValuesWith(From, To, 2);<br>
>>> >>> + Â // Since we're explicitly calling ReplaceAllUses, add the new node<br>
>>> >>> to<br>
>>> >>> the<br>
>>> >>> + Â // worklist explicitly as well.<br>
>>> >>> + Â AddToWorkList(Load.getNode());<br>
>>> >>> + Â AddUsersToWorkList(Load.getNode()); // Add users too<br>
>>> >>> + Â // Make sure to revisit this node to clean it up; it will usually<br>
>>> >>> be<br>
>>> >>> dead.<br>
>>> >>> + Â AddToWorkList(EVE);<br>
>>> >>> + Â ++OpsNarrowed;<br>
>>> >>> + Â return SDValue(EVE, 0);<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> Â SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {<br>
>>> >>> Â  Â // (vextract (scalar_to_vector val, 0) -> val<br>
>>> >>> Â  Â SDValue InVec = N->getOperand(0);<br>
>>> >>> @@ -9743,6 +9833,38 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR<br>
>>> >>> Â  Â  Â }<br>
>>> >>> Â  Â }<br>
>>> >>><br>
>>> >>> + Â bool BCNumEltsChanged = false;<br>
>>> >>> + Â EVT ExtVT = VT.getVectorElementType();<br>
>>> >>> + Â EVT LVT = ExtVT;<br>
>>> >>> +<br>
>>> >>> + Â // If the result of load has to be truncated, then it's not<br>
>>> >>> necessarily<br>
>>> >>> + Â // profitable.<br>
>>> >>> + Â if (NVT.bitsLT(LVT) && !TLI.isTruncateFree(LVT, NVT))<br>
>>> >>> + Â  Â return SDValue();<br>
>>> >>> +<br>
>>> >>> + Â if (InVec.getOpcode() == ISD::BITCAST) {<br>
>>> >>> + Â  Â // Don't duplicate a load with other uses.<br>
>>> >>> + Â  Â if (!InVec.hasOneUse())<br>
>>> >>> + Â  Â  Â return SDValue();<br>
>>> >>> +<br>
>>> >>> + Â  Â EVT BCVT = InVec.getOperand(0).getValueType();<br>
>>> >>> + Â  Â if (!BCVT.isVector() ||<br>
>>> >>> ExtVT.bitsGT(BCVT.getVectorElementType()))<br>
>>> >>> + Â  Â  Â return SDValue();<br>
>>> >>> + Â  Â if (VT.getVectorNumElements() != BCVT.getVectorNumElements())<br>
>>> >>> + Â  Â  Â BCNumEltsChanged = true;<br>
>>> >>> + Â  Â InVec = InVec.getOperand(0);<br>
>>> >>> + Â  Â ExtVT = BCVT.getVectorElementType();<br>
>>> >>> + Â }<br>
>>> >>> +<br>
>>> >>> + Â // (vextract (vN[if]M load $addr), i) -> ([if]M load $addr + i *<br>
>>> >>> size)<br>
>>> >>> + Â if (!LegalOperations && !ConstEltNo && InVec.hasOneUse() &&<br>
>>> >>> + Â  Â  Â ISD::isNormalLoad(InVec.getNode())) {<br>
>>> >>> + Â  Â SDValue Index = N->getOperand(1);<br>
>>> >>> + Â  Â if (LoadSDNode *OrigLoad = dyn_cast<LoadSDNode>(InVec))<br>
>>> >>> + Â  Â  Â return ReplaceExtractVectorEltOfLoadWithNarrowedLoad(N, VT,<br>
>>> >>> Index,<br>
>>> >>> + Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  OrigLoad);<br>
>>> >>> + Â }<br>
>>> >>> +<br>
>>> >>> Â  Â // Perform only after legalization to ensure build_vector /<br>
>>> >>> vector_shuffle<br>
>>> >>> Â  Â // optimizations have already been done.<br>
>>> >>> Â  Â if (!LegalOperations) return SDValue();<br>
>>> >>> @@ -9753,30 +9875,6 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR<br>
>>> >>><br>
>>> >>> Â  Â if (ConstEltNo) {<br>
>>> >>> Â  Â  Â int Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();<br>
>>> >>> - Â  Â bool NewLoad = false;<br>
>>> >>> - Â  Â bool BCNumEltsChanged = false;<br>
>>> >>> - Â  Â EVT ExtVT = VT.getVectorElementType();<br>
>>> >>> - Â  Â EVT LVT = ExtVT;<br>
>>> >>> -<br>
>>> >>> - Â  Â // If the result of load has to be truncated, then it's not<br>
>>> >>> necessarily<br>
>>> >>> - Â  Â // profitable.<br>
>>> >>> - Â  Â if (NVT.bitsLT(LVT) && !TLI.isTruncateFree(LVT, NVT))<br>
>>> >>> - Â  Â  Â return SDValue();<br>
>>> >>> -<br>
>>> >>> - Â  Â if (InVec.getOpcode() == ISD::BITCAST) {<br>
>>> >>> - Â  Â  Â // Don't duplicate a load with other uses.<br>
>>> >>> - Â  Â  Â if (!InVec.hasOneUse())<br>
>>> >>> - Â  Â  Â  Â return SDValue();<br>
>>> >>> -<br>
>>> >>> - Â  Â  Â EVT BCVT = InVec.getOperand(0).getValueType();<br>
>>> >>> - Â  Â  Â if (!BCVT.isVector() ||<br>
>>> >>> ExtVT.bitsGT(BCVT.getVectorElementType()))<br>
>>> >>> - Â  Â  Â  Â return SDValue();<br>
>>> >>> - Â  Â  Â if (VT.getVectorNumElements() != BCVT.getVectorNumElements())<br>
>>> >>> - Â  Â  Â  Â BCNumEltsChanged = true;<br>
>>> >>> - Â  Â  Â InVec = InVec.getOperand(0);<br>
>>> >>> - Â  Â  Â ExtVT = BCVT.getVectorElementType();<br>
>>> >>> - Â  Â  Â NewLoad = true;<br>
>>> >>> - Â  Â }<br>
>>> >>><br>
>>> >>> Â  Â  Â LoadSDNode *LN0 = nullptr;<br>
>>> >>> Â  Â  Â const ShuffleVectorSDNode *SVN = nullptr;<br>
>>> >>> @@ -9819,6 +9917,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR<br>
>>> >>> Â  Â  Â  Â if (ISD::isNormalLoad(InVec.getNode())) {<br>
>>> >>> Â  Â  Â  Â  Â LN0 = cast<LoadSDNode>(InVec);<br>
>>> >>> Â  Â  Â  Â  Â Elt = (Idx < (int)NumElems) ? Idx : Idx - (int)NumElems;<br>
>>> >>> + Â  Â  Â  Â EltNo = DAG.getConstant(Elt, EltNo.getValueType());<br>
>>> >>> Â  Â  Â  Â }<br>
>>> >>> Â  Â  Â }<br>
>>> >>><br>
>>> >>> @@ -9831,72 +9930,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR<br>
>>> >>> Â  Â  Â if (Elt == -1)<br>
>>> >>> Â  Â  Â  Â return DAG.getUNDEF(LVT);<br>
>>> >>><br>
>>> >>> - Â  Â unsigned Align = LN0->getAlignment();<br>
>>> >>> - Â  Â if (NewLoad) {<br>
>>> >>> - Â  Â  Â // Check the resultant load doesn't need a higher alignment<br>
>>> >>> than<br>
>>> >>> the<br>
>>> >>> - Â  Â  Â // original load.<br>
>>> >>> - Â  Â  Â unsigned NewAlign =<br>
>>> >>> - Â  Â  Â  Â TLI.getDataLayout()<br>
>>> >>> -<br>
>>> >>> ->getABITypeAlignment(LVT.getTypeForEVT(*DAG.getContext()));<br>
>>> >>> -<br>
>>> >>> - Â  Â  Â if (NewAlign > Align ||<br>
>>> >>> !TLI.isOperationLegalOrCustom(ISD::LOAD,<br>
>>> >>> LVT))<br>
>>> >>> - Â  Â  Â  Â return SDValue();<br>
>>> >>> -<br>
>>> >>> - Â  Â  Â Align = NewAlign;<br>
>>> >>> - Â  Â }<br>
>>> >>> -<br>
>>> >>> - Â  Â SDValue NewPtr = LN0->getBasePtr();<br>
>>> >>> - Â  Â unsigned PtrOff = 0;<br>
>>> >>> -<br>
>>> >>> - Â  Â if (Elt) {<br>
>>> >>> - Â  Â  Â PtrOff = LVT.getSizeInBits() * Elt / 8;<br>
>>> >>> - Â  Â  Â EVT PtrType = NewPtr.getValueType();<br>
>>> >>> - Â  Â  Â if (TLI.isBigEndian())<br>
>>> >>> - Â  Â  Â  Â PtrOff = VT.getSizeInBits() / 8 - PtrOff;<br>
>>> >>> - Â  Â  Â NewPtr = DAG.getNode(ISD::ADD, SDLoc(N), PtrType, NewPtr,<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DAG.getConstant(PtrOff, PtrType));<br>
>>> >>> - Â  Â }<br>
>>> >>> -<br>
>>> >>> - Â  Â // The replacement we need to do here is a little tricky: we need<br>
>>> >>> to<br>
>>> >>> - Â  Â // replace an extractelement of a load with a load.<br>
>>> >>> - Â  Â // Use ReplaceAllUsesOfValuesWith to do the replacement.<br>
>>> >>> - Â  Â // Note that this replacement assumes that the extractvalue is<br>
>>> >>> the<br>
>>> >>> only<br>
>>> >>> - Â  Â // use of the load; that's okay because we don't want to perform<br>
>>> >>> this<br>
>>> >>> - Â  Â // transformation in other cases anyway.<br>
>>> >>> - Â  Â SDValue Load;<br>
>>> >>> - Â  Â SDValue Chain;<br>
>>> >>> - Â  Â if (NVT.bitsGT(LVT)) {<br>
>>> >>> - Â  Â  Â // If the result type of vextract is wider than the load, then<br>
>>> >>> issue an<br>
>>> >>> - Â  Â  Â // extending load instead.<br>
>>> >>> - Â  Â  Â ISD::LoadExtType ExtType = TLI.isLoadExtLegal(ISD::ZEXTLOAD,<br>
>>> >>> LVT)<br>
>>> >>> - Â  Â  Â  Â ? ISD::ZEXTLOAD : ISD::EXTLOAD;<br>
>>> >>> - Â  Â  Â Load = DAG.getExtLoad(ExtType, SDLoc(N), NVT, LN0->getChain(),<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â NewPtr,<br>
>>> >>> LN0->getPointerInfo().getWithOffset(PtrOff),<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â LVT, LN0->isVolatile(),<br>
>>> >>> LN0->isNonTemporal(),<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â Align, LN0->getTBAAInfo());<br>
>>> >>> - Â  Â  Â Chain = Load.getValue(1);<br>
>>> >>> - Â  Â } else {<br>
>>> >>> - Â  Â  Â Load = DAG.getLoad(LVT, SDLoc(N), LN0->getChain(), NewPtr,<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  LN0->getPointerInfo().getWithOffset(PtrOff),<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  LN0->isVolatile(), LN0->isNonTemporal(),<br>
>>> >>> - Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  LN0->isInvariant(), Align,<br>
>>> >>> LN0->getTBAAInfo());<br>
>>> >>> - Â  Â  Â Chain = Load.getValue(1);<br>
>>> >>> - Â  Â  Â if (NVT.bitsLT(LVT))<br>
>>> >>> - Â  Â  Â  Â Load = DAG.getNode(ISD::TRUNCATE, SDLoc(N), NVT, Load);<br>
>>> >>> - Â  Â  Â else<br>
>>> >>> - Â  Â  Â  Â Load = DAG.getNode(ISD::BITCAST, SDLoc(N), NVT, Load);<br>
>>> >>> - Â  Â }<br>
>>> >>> - Â  Â WorkListRemover DeadNodes(*this);<br>
>>> >>> - Â  Â SDValue From[] = { SDValue(N, 0), SDValue(LN0,1) };<br>
>>> >>> - Â  Â SDValue To[] = { Load, Chain };<br>
>>> >>> - Â  Â DAG.ReplaceAllUsesOfValuesWith(From, To, 2);<br>
>>> >>> - Â  Â // Since we're explcitly calling ReplaceAllUses, add the new node<br>
>>> >>> to<br>
>>> >>> the<br>
>>> >>> - Â  Â // worklist explicitly as well.<br>
>>> >>> - Â  Â AddToWorkList(Load.getNode());<br>
>>> >>> - Â  Â AddUsersToWorkList(Load.getNode()); // Add users too<br>
>>> >>> - Â  Â // Make sure to revisit this node to clean it up; it will usually<br>
>>> >>> be<br>
>>> >>> dead.<br>
>>> >>> - Â  Â AddToWorkList(N);<br>
>>> >>> - Â  Â return SDValue(N, 0);<br>
>>> >>> + Â  Â return ReplaceExtractVectorEltOfLoadWithNarrowedLoad(N, VT,<br>
>>> >>> EltNo,<br>
>>> >>> LN0);<br>
>>> >>> Â  Â }<br>
>>> >>><br>
>>> >>> Â  Â return SDValue();<br>
>>> >>><br>
>>> >>> Modified: llvm/trunk/test/CodeGen/X86/vec_splat.ll<br>
>>> >>> URL:<br>
>>> >>><br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_splat.ll?rev=209788&r1=209787&r2=209788&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_splat.ll?rev=209788&r1=209787&r2=209788&view=diff</a><br>

>>> >>><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/test/CodeGen/X86/vec_splat.ll (original)<br>
>>> >>> +++ llvm/trunk/test/CodeGen/X86/vec_splat.ll Wed May 28 20:42:45 2014<br>
>>> >>> @@ -1,5 +1,6 @@<br>
>>> >>> Â ; RUN: llc < %s -march=x86 -mcpu=pentium4 -mattr=+sse2 | FileCheck %s<br>
>>> >>> -check-prefix=SSE2<br>
>>> >>> Â ; RUN: llc < %s -march=x86 -mcpu=pentium4 -mattr=+sse3 | FileCheck %s<br>
>>> >>> -check-prefix=SSE3<br>
>>> >>> +; RUN: llc < %s -march=x86-64 -mattr=+avx | FileCheck %s<br>
>>> >>> -check-prefix=AVX<br>
>>> >>><br>
>>> >>> Â define void @test_v4sf(<4 x float>* %P, <4 x float>* %Q, float %X)<br>
>>> >>> nounwind {<br>
>>> >>> Â  Â  Â  Â  %tmp = insertelement <4 x float> zeroinitializer, float %X,<br>
>>> >>> i32 0<br>
>>> >>> ; <<4 x float>> [#uses=1]<br>
>>> >>> @@ -37,6 +38,23 @@ define void @test_v2sd(<2 x double>* %P,<br>
>>> >>> Â define <4 x float> @load_extract_splat(<4 x float>* nocapture<br>
>>> >>> readonly<br>
>>> >>> %ptr, i64 %i, i64 %j) nounwind {<br>
>>> >>> Â  Â %1 = getelementptr inbounds <4 x float>* %ptr, i64 %i<br>
>>> >>> Â  Â %2 = load <4 x float>* %1, align 16<br>
>>> >>> + Â %3 = trunc i64 %j to i32<br>
>>> >>> + Â %4 = extractelement <4 x float> %2, i32 %3<br>
>>> >>> + Â %5 = insertelement <4 x float> undef, float %4, i32 0<br>
>>> >>> + Â %6 = insertelement <4 x float> %5, float %4, i32 1<br>
>>> >>> + Â %7 = insertelement <4 x float> %6, float %4, i32 2<br>
>>> >>> + Â %8 = insertelement <4 x float> %7, float %4, i32 3<br>
>>> >>> + Â ret <4 x float> %8<br>
>>> >>> +<br>
>>> >>> +; AVX-LABEL: load_extract_splat<br>
>>> >>> +; AVX-NOT: rsp<br>
>>> >>> +; AVX: vbroadcastss<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +; Fold extract of a load into the load's address computation. This<br>
>>> >>> avoids<br>
>>> >>> spilling to the stack.<br>
>>> >>> +define <4 x float> @load_extract_splat1(<4 x float>* nocapture<br>
>>> >>> readonly<br>
>>> >>> %ptr, i64 %i, i64 %j) nounwind {<br>
>>> >>> + Â %1 = getelementptr inbounds <4 x float>* %ptr, i64 %i<br>
>>> >>> + Â %2 = load <4 x float>* %1, align 16<br>
>>> >>> Â  Â %3 = extractelement <4 x float> %2, i64 %j<br>
>>> >>> Â  Â %4 = insertelement <4 x float> undef, float %3, i32 0<br>
>>> >>> Â  Â %5 = insertelement <4 x float> %4, float %3, i32 1<br>
>>> >>> @@ -44,7 +62,7 @@ define <4 x float> @load_extract_splat(<<br>
>>> >>> Â  Â %7 = insertelement <4 x float> %6, float %3, i32 3<br>
>>> >>> Â  Â ret <4 x float> %7<br>
>>> >>><br>
>>> >>> -; AVX-LABEL: load_extract_splat<br>
>>> >>> +; AVX-LABEL: load_extract_splat1<br>
>>> >>> Â ; AVX-NOT: movs<br>
>>> >>> Â ; AVX: vbroadcastss<br>
>>> >>> Â }<br>
>>> >>><br>
>>> >>><br>
>>> >>> _______________________________________________<br>
>>> >>> llvm-commits mailing list<br>
>>> >>> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
>>> >>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
>>> >><br>
>>> >><br>
>><br>
>><br>
</div></div></blockquote></div><br></div>