@@ -12114,3 +12114,77 @@ SDValue TargetLowering::expandVectorNaryOpBySplitting(SDNode *Node,
1211412114 SDValue SplitOpHi = DAG.getNode (Opcode, DL, HiVT, HiOps);
1211512115 return DAG.getNode (ISD::CONCAT_VECTORS, DL, VT, SplitOpLo, SplitOpHi);
1211612116}
12117+
12118+ SDValue TargetLowering::scalarizeExtractedVectorLoad (EVT ResultVT,
12119+ const SDLoc &DL,
12120+ EVT InVecVT, SDValue EltNo,
12121+ LoadSDNode *OriginalLoad,
12122+ SelectionDAG &DAG) const {
12123+ assert (OriginalLoad->isSimple ());
12124+
12125+ EVT VecEltVT = InVecVT.getVectorElementType ();
12126+
12127+ // If the vector element type is not a multiple of a byte then we are unable
12128+ // to correctly compute an address to load only the extracted element as a
12129+ // scalar.
12130+ if (!VecEltVT.isByteSized ())
12131+ return SDValue ();
12132+
12133+ ISD::LoadExtType ExtTy =
12134+ ResultVT.bitsGT (VecEltVT) ? ISD::EXTLOAD : ISD::NON_EXTLOAD;
12135+ if (!isOperationLegalOrCustom (ISD::LOAD, VecEltVT) ||
12136+ !shouldReduceLoadWidth (OriginalLoad, ExtTy, VecEltVT))
12137+ return SDValue ();
12138+
12139+ Align Alignment = OriginalLoad->getAlign ();
12140+ MachinePointerInfo MPI;
12141+ if (auto *ConstEltNo = dyn_cast<ConstantSDNode>(EltNo)) {
12142+ int Elt = ConstEltNo->getZExtValue ();
12143+ unsigned PtrOff = VecEltVT.getSizeInBits () * Elt / 8 ;
12144+ MPI = OriginalLoad->getPointerInfo ().getWithOffset (PtrOff);
12145+ Alignment = commonAlignment (Alignment, PtrOff);
12146+ } else {
12147+ // Discard the pointer info except the address space because the memory
12148+ // operand can't represent this new access since the offset is variable.
12149+ MPI = MachinePointerInfo (OriginalLoad->getPointerInfo ().getAddrSpace ());
12150+ Alignment = commonAlignment (Alignment, VecEltVT.getSizeInBits () / 8 );
12151+ }
12152+
12153+ unsigned IsFast = 0 ;
12154+ if (!allowsMemoryAccess (*DAG.getContext (), DAG.getDataLayout (), VecEltVT,
12155+ OriginalLoad->getAddressSpace (), Alignment,
12156+ OriginalLoad->getMemOperand ()->getFlags (), &IsFast) ||
12157+ !IsFast)
12158+ return SDValue ();
12159+
12160+ SDValue NewPtr =
12161+ getVectorElementPointer (DAG, OriginalLoad->getBasePtr (), InVecVT, EltNo);
12162+
12163+ // We are replacing a vector load with a scalar load. The new load must have
12164+ // identical memory op ordering to the original.
12165+ SDValue Load;
12166+ if (ResultVT.bitsGT (VecEltVT)) {
12167+ // If the result type of vextract is wider than the load, then issue an
12168+ // extending load instead.
12169+ ISD::LoadExtType ExtType = isLoadExtLegal (ISD::ZEXTLOAD, ResultVT, VecEltVT)
12170+ ? ISD::ZEXTLOAD
12171+ : ISD::EXTLOAD;
12172+ Load = DAG.getExtLoad (ExtType, DL, ResultVT, OriginalLoad->getChain (),
12173+ NewPtr, MPI, VecEltVT, Alignment,
12174+ OriginalLoad->getMemOperand ()->getFlags (),
12175+ OriginalLoad->getAAInfo ());
12176+ DAG.makeEquivalentMemoryOrdering (OriginalLoad, Load);
12177+ } else {
12178+ // The result type is narrower or the same width as the vector element
12179+ Load = DAG.getLoad (VecEltVT, DL, OriginalLoad->getChain (), NewPtr, MPI,
12180+ Alignment, OriginalLoad->getMemOperand ()->getFlags (),
12181+ OriginalLoad->getAAInfo ());
12182+ DAG.makeEquivalentMemoryOrdering (OriginalLoad, Load);
12183+ if (ResultVT.bitsLT (VecEltVT))
12184+ Load = DAG.getNode (ISD::TRUNCATE, DL, ResultVT, Load);
12185+ else
12186+ Load = DAG.getBitcast (ResultVT, Load);
12187+ }
12188+
12189+ return Load;
12190+ }
0 commit comments