@@ -4590,6 +4590,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
45904590 break ;
45914591 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR (N); break ;
45924592 case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT (N); break ;
4593+ case ISD::ATOMIC_LOAD:
4594+ Res = WidenVecRes_ATOMIC_LOAD (cast<AtomicSDNode>(N));
4595+ break ;
45934596 case ISD::LOAD: Res = WidenVecRes_LOAD (N); break ;
45944597 case ISD::STEP_VECTOR:
45954598 case ISD::SPLAT_VECTOR:
@@ -5979,6 +5982,85 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
59795982 N->getOperand (1 ), N->getOperand (2 ));
59805983}
59815984
5985+ // / Either return the same load or provide appropriate casts
5986+ // / from the load and return that.
5987+ static SDValue loadElement (SDValue LdOp, EVT FirstVT, EVT WidenVT,
5988+ TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl,
5989+ SelectionDAG &DAG) {
5990+ assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
5991+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
5992+ if (!FirstVT.isVector ()) {
5993+ unsigned NumElts =
5994+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
5995+ EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), FirstVT, NumElts);
5996+ SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
5997+ return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
5998+ } else if (FirstVT == WidenVT)
5999+ return LdOp;
6000+ else {
6001+ // TODO: We don't currently have any tests that exercise this code path.
6002+ assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () == 0 );
6003+ unsigned NumConcat =
6004+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
6005+ SmallVector<SDValue, 16 > ConcatOps (NumConcat);
6006+ SDValue UndefVal = DAG.getUNDEF (FirstVT);
6007+ ConcatOps[0 ] = LdOp;
6008+ for (unsigned i = 1 ; i != NumConcat; ++i)
6009+ ConcatOps[i] = UndefVal;
6010+ return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
6011+ }
6012+ }
6013+
6014+ static std::optional<EVT> findMemType (SelectionDAG &DAG,
6015+ const TargetLowering &TLI, unsigned Width,
6016+ EVT WidenVT, unsigned Align,
6017+ unsigned WidenEx);
6018+
6019+ SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD (AtomicSDNode *LD) {
6020+ EVT WidenVT =
6021+ TLI.getTypeToTransformTo (*DAG.getContext (), LD->getValueType (0 ));
6022+ EVT LdVT = LD->getMemoryVT ();
6023+ SDLoc dl (LD);
6024+ assert (LdVT.isVector () && WidenVT.isVector () && " Expected vectors" );
6025+ assert (LdVT.isScalableVector () == WidenVT.isScalableVector () &&
6026+ " Must be scalable" );
6027+ assert (LdVT.getVectorElementType () == WidenVT.getVectorElementType () &&
6028+ " Expected equivalent element types" );
6029+
6030+ // Load information
6031+ SDValue Chain = LD->getChain ();
6032+ SDValue BasePtr = LD->getBasePtr ();
6033+ MachineMemOperand::Flags MMOFlags = LD->getMemOperand ()->getFlags ();
6034+ AAMDNodes AAInfo = LD->getAAInfo ();
6035+
6036+ TypeSize LdWidth = LdVT.getSizeInBits ();
6037+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6038+ TypeSize WidthDiff = WidenWidth - LdWidth;
6039+
6040+ // Find the vector type that can load from.
6041+ std::optional<EVT> FirstVT =
6042+ findMemType (DAG, TLI, LdWidth.getKnownMinValue (), WidenVT, /* LdAlign=*/ 0 ,
6043+ WidthDiff.getKnownMinValue ());
6044+
6045+ if (!FirstVT)
6046+ return SDValue ();
6047+
6048+ SmallVector<EVT, 8 > MemVTs;
6049+ TypeSize FirstVTWidth = FirstVT->getSizeInBits ();
6050+
6051+ SDValue LdOp = DAG.getAtomicLoad (ISD::NON_EXTLOAD, dl, *FirstVT, *FirstVT,
6052+ Chain, BasePtr, LD->getMemOperand ());
6053+
6054+ // Load the element with one instruction.
6055+ SDValue Result =
6056+ loadElement (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl, DAG);
6057+
6058+ // Modified the chain - switch anything that used the old chain to use
6059+ // the new one.
6060+ ReplaceValueWith (SDValue (LD, 1 ), LdOp.getValue (1 ));
6061+ return Result;
6062+ }
6063+
59826064SDValue DAGTypeLegalizer::WidenVecRes_LOAD (SDNode *N) {
59836065 LoadSDNode *LD = cast<LoadSDNode>(N);
59846066 ISD::LoadExtType ExtType = LD->getExtensionType ();
@@ -7862,27 +7944,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
78627944
78637945 // Check if we can load the element with one instruction.
78647946 if (MemVTs.empty ()) {
7865- assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
7866- if (!FirstVT->isVector ()) {
7867- unsigned NumElts =
7868- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7869- EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), *FirstVT, NumElts);
7870- SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
7871- return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
7872- }
7873- if (FirstVT == WidenVT)
7874- return LdOp;
7875-
7876- // TODO: We don't currently have any tests that exercise this code path.
7877- assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () == 0 );
7878- unsigned NumConcat =
7879- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7880- SmallVector<SDValue, 16 > ConcatOps (NumConcat);
7881- SDValue UndefVal = DAG.getUNDEF (*FirstVT);
7882- ConcatOps[0 ] = LdOp;
7883- for (unsigned i = 1 ; i != NumConcat; ++i)
7884- ConcatOps[i] = UndefVal;
7885- return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
7947+ return loadElement (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl, DAG);
78867948 }
78877949
78887950 // Load vector by using multiple loads from largest vector to scalar.
0 commit comments