@@ -4859,6 +4859,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
48594859 break ;
48604860 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR (N); break ;
48614861 case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT (N); break ;
4862+ case ISD::ATOMIC_LOAD:
4863+ Res = WidenVecRes_ATOMIC_LOAD (cast<AtomicSDNode>(N));
4864+ break ;
48624865 case ISD::LOAD: Res = WidenVecRes_LOAD (N); break ;
48634866 case ISD::STEP_VECTOR:
48644867 case ISD::SPLAT_VECTOR:
@@ -6248,6 +6251,74 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
62486251 N->getOperand (1 ), N->getOperand (2 ));
62496252}
62506253
6254+ // / Either return the same load or provide appropriate casts
6255+ // / from the load and return that.
6256+ static SDValue coerceLoadedValue (SDValue LdOp, EVT FirstVT, EVT WidenVT,
6257+ TypeSize LdWidth, TypeSize FirstVTWidth,
6258+ SDLoc dl, SelectionDAG &DAG) {
6259+ assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
6260+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6261+ if (!FirstVT.isVector ()) {
6262+ unsigned NumElts =
6263+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
6264+ EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), FirstVT, NumElts);
6265+ SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
6266+ return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
6267+ }
6268+ assert (FirstVT == WidenVT);
6269+ return LdOp;
6270+ }
6271+
6272+ static std::optional<EVT> findMemType (SelectionDAG &DAG,
6273+ const TargetLowering &TLI, unsigned Width,
6274+ EVT WidenVT, unsigned Align,
6275+ unsigned WidenEx);
6276+
6277+ SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD (AtomicSDNode *LD) {
6278+ EVT WidenVT =
6279+ TLI.getTypeToTransformTo (*DAG.getContext (), LD->getValueType (0 ));
6280+ EVT LdVT = LD->getMemoryVT ();
6281+ SDLoc dl (LD);
6282+ assert (LdVT.isVector () && WidenVT.isVector () && " Expected vectors" );
6283+ assert (LdVT.isScalableVector () == WidenVT.isScalableVector () &&
6284+ " Must be scalable" );
6285+ assert (LdVT.getVectorElementType () == WidenVT.getVectorElementType () &&
6286+ " Expected equivalent element types" );
6287+
6288+ // Load information
6289+ SDValue Chain = LD->getChain ();
6290+ SDValue BasePtr = LD->getBasePtr ();
6291+ MachineMemOperand::Flags MMOFlags = LD->getMemOperand ()->getFlags ();
6292+ AAMDNodes AAInfo = LD->getAAInfo ();
6293+
6294+ TypeSize LdWidth = LdVT.getSizeInBits ();
6295+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6296+ TypeSize WidthDiff = WidenWidth - LdWidth;
6297+
6298+ // Find the vector type that can load from.
6299+ std::optional<EVT> FirstVT =
6300+ findMemType (DAG, TLI, LdWidth.getKnownMinValue (), WidenVT, /* LdAlign=*/ 0 ,
6301+ WidthDiff.getKnownMinValue ());
6302+
6303+ if (!FirstVT)
6304+ return SDValue ();
6305+
6306+ SmallVector<EVT, 8 > MemVTs;
6307+ TypeSize FirstVTWidth = FirstVT->getSizeInBits ();
6308+
6309+ SDValue LdOp = DAG.getAtomicLoad (ISD::NON_EXTLOAD, dl, *FirstVT, *FirstVT,
6310+ Chain, BasePtr, LD->getMemOperand ());
6311+
6312+ // Load the element with one instruction.
6313+ SDValue Result = coerceLoadedValue (LdOp, *FirstVT, WidenVT, LdWidth,
6314+ FirstVTWidth, dl, DAG);
6315+
6316+ // Modified the chain - switch anything that used the old chain to use
6317+ // the new one.
6318+ ReplaceValueWith (SDValue (LD, 1 ), LdOp.getValue (1 ));
6319+ return Result;
6320+ }
6321+
62516322SDValue DAGTypeLegalizer::WidenVecRes_LOAD (SDNode *N) {
62526323 LoadSDNode *LD = cast<LoadSDNode>(N);
62536324 ISD::LoadExtType ExtType = LD->getExtensionType ();
@@ -8212,29 +8283,9 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
82128283 LdChain.push_back (LdOp.getValue (1 ));
82138284
82148285 // Check if we can load the element with one instruction.
8215- if (MemVTs.empty ()) {
8216- assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
8217- if (!FirstVT->isVector ()) {
8218- unsigned NumElts =
8219- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
8220- EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), *FirstVT, NumElts);
8221- SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
8222- return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
8223- }
8224- if (FirstVT == WidenVT)
8225- return LdOp;
8226-
8227- // TODO: We don't currently have any tests that exercise this code path.
8228- assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () == 0 );
8229- unsigned NumConcat =
8230- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
8231- SmallVector<SDValue, 16 > ConcatOps (NumConcat);
8232- SDValue UndefVal = DAG.getUNDEF (*FirstVT);
8233- ConcatOps[0 ] = LdOp;
8234- for (unsigned i = 1 ; i != NumConcat; ++i)
8235- ConcatOps[i] = UndefVal;
8236- return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
8237- }
8286+ if (MemVTs.empty ())
8287+ return coerceLoadedValue (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl,
8288+ DAG);
82388289
82398290 // Load vector by using multiple loads from largest vector to scalar.
82408291 SmallVector<SDValue, 16 > LdOps;
0 commit comments