@@ -4625,6 +4625,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
46254625 break ;
46264626 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR (N); break ;
46274627 case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT (N); break ;
4628+ case ISD::ATOMIC_LOAD:
4629+ Res = WidenVecRes_ATOMIC_LOAD (cast<AtomicSDNode>(N));
4630+ break ;
46284631 case ISD::LOAD: Res = WidenVecRes_LOAD (N); break ;
46294632 case ISD::STEP_VECTOR:
46304633 case ISD::SPLAT_VECTOR:
@@ -6014,6 +6017,85 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
60146017 N->getOperand (1 ), N->getOperand (2 ));
60156018}
60166019
6020+ // / Either return the same load or provide appropriate casts
6021+ // / from the load and return that.
6022+ static SDValue loadElement (SDValue LdOp, EVT FirstVT, EVT WidenVT,
6023+ TypeSize LdWidth, TypeSize FirstVTWidth, SDLoc dl,
6024+ SelectionDAG &DAG) {
6025+ assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
6026+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6027+ if (!FirstVT.isVector ()) {
6028+ unsigned NumElts =
6029+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
6030+ EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), FirstVT, NumElts);
6031+ SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
6032+ return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
6033+ } else if (FirstVT == WidenVT)
6034+ return LdOp;
6035+ else {
6036+ // TODO: We don't currently have any tests that exercise this code path.
6037+ assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () == 0 );
6038+ unsigned NumConcat =
6039+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
6040+ SmallVector<SDValue, 16 > ConcatOps (NumConcat);
6041+ SDValue UndefVal = DAG.getUNDEF (FirstVT);
6042+ ConcatOps[0 ] = LdOp;
6043+ for (unsigned i = 1 ; i != NumConcat; ++i)
6044+ ConcatOps[i] = UndefVal;
6045+ return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
6046+ }
6047+ }
6048+
6049+ static std::optional<EVT> findMemType (SelectionDAG &DAG,
6050+ const TargetLowering &TLI, unsigned Width,
6051+ EVT WidenVT, unsigned Align,
6052+ unsigned WidenEx);
6053+
6054+ SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD (AtomicSDNode *LD) {
6055+ EVT WidenVT =
6056+ TLI.getTypeToTransformTo (*DAG.getContext (), LD->getValueType (0 ));
6057+ EVT LdVT = LD->getMemoryVT ();
6058+ SDLoc dl (LD);
6059+ assert (LdVT.isVector () && WidenVT.isVector () && " Expected vectors" );
6060+ assert (LdVT.isScalableVector () == WidenVT.isScalableVector () &&
6061+ " Must be scalable" );
6062+ assert (LdVT.getVectorElementType () == WidenVT.getVectorElementType () &&
6063+ " Expected equivalent element types" );
6064+
6065+ // Load information
6066+ SDValue Chain = LD->getChain ();
6067+ SDValue BasePtr = LD->getBasePtr ();
6068+ MachineMemOperand::Flags MMOFlags = LD->getMemOperand ()->getFlags ();
6069+ AAMDNodes AAInfo = LD->getAAInfo ();
6070+
6071+ TypeSize LdWidth = LdVT.getSizeInBits ();
6072+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6073+ TypeSize WidthDiff = WidenWidth - LdWidth;
6074+
6075+ // Find the vector type that can load from.
6076+ std::optional<EVT> FirstVT =
6077+ findMemType (DAG, TLI, LdWidth.getKnownMinValue (), WidenVT, /* LdAlign=*/ 0 ,
6078+ WidthDiff.getKnownMinValue ());
6079+
6080+ if (!FirstVT)
6081+ return SDValue ();
6082+
6083+ SmallVector<EVT, 8 > MemVTs;
6084+ TypeSize FirstVTWidth = FirstVT->getSizeInBits ();
6085+
6086+ SDValue LdOp = DAG.getAtomicLoad (ISD::NON_EXTLOAD, dl, *FirstVT, *FirstVT,
6087+ Chain, BasePtr, LD->getMemOperand ());
6088+
6089+ // Load the element with one instruction.
6090+ SDValue Result =
6091+ loadElement (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl, DAG);
6092+
6093+ // Modified the chain - switch anything that used the old chain to use
6094+ // the new one.
6095+ ReplaceValueWith (SDValue (LD, 1 ), LdOp.getValue (1 ));
6096+ return Result;
6097+ }
6098+
60176099SDValue DAGTypeLegalizer::WidenVecRes_LOAD (SDNode *N) {
60186100 LoadSDNode *LD = cast<LoadSDNode>(N);
60196101 ISD::LoadExtType ExtType = LD->getExtensionType ();
@@ -7897,27 +7979,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
78977979
78987980 // Check if we can load the element with one instruction.
78997981 if (MemVTs.empty ()) {
7900- assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
7901- if (!FirstVT->isVector ()) {
7902- unsigned NumElts =
7903- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7904- EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), *FirstVT, NumElts);
7905- SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
7906- return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
7907- }
7908- if (FirstVT == WidenVT)
7909- return LdOp;
7910-
7911- // TODO: We don't currently have any tests that exercise this code path.
7912- assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () == 0 );
7913- unsigned NumConcat =
7914- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7915- SmallVector<SDValue, 16 > ConcatOps (NumConcat);
7916- SDValue UndefVal = DAG.getUNDEF (*FirstVT);
7917- ConcatOps[0 ] = LdOp;
7918- for (unsigned i = 1 ; i != NumConcat; ++i)
7919- ConcatOps[i] = UndefVal;
7920- return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
7982+ return loadElement (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl, DAG);
79217983 }
79227984
79237985 // Load vector by using multiple loads from largest vector to scalar.
0 commit comments