@@ -4590,6 +4590,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
4590
4590
break ;
4591
4591
case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR (N); break ;
4592
4592
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 ;
4593
4596
case ISD::LOAD: Res = WidenVecRes_LOAD (N); break ;
4594
4597
case ISD::STEP_VECTOR:
4595
4598
case ISD::SPLAT_VECTOR:
@@ -5979,6 +5982,85 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
5979
5982
N->getOperand (1 ), N->getOperand (2 ));
5980
5983
}
5981
5984
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 = loadElement (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth,
6056
+ 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
+
5982
6064
SDValue DAGTypeLegalizer::WidenVecRes_LOAD (SDNode *N) {
5983
6065
LoadSDNode *LD = cast<LoadSDNode>(N);
5984
6066
ISD::LoadExtType ExtType = LD->getExtensionType ();
@@ -7862,27 +7944,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
7862
7944
7863
7945
// Check if we can load the element with one instruction.
7864
7946
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);
7886
7948
}
7887
7949
7888
7950
// Load vector by using multiple loads from largest vector to scalar.
0 commit comments