@@ -4699,6 +4699,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
4699
4699
break ;
4700
4700
case ISD::EXTRACT_SUBVECTOR: Res =WidenVecRes_EXTRACT_SUBVECTOR (N);break ;
4701
4701
case ISD::INSERT_VECTOR_ELT: Res =WidenVecRes_INSERT_VECTOR_ELT (N);break ;
4702
+ case ISD::ATOMIC_LOAD:
4703
+ Res =WidenVecRes_ATOMIC_LOAD (cast<AtomicSDNode>(N));
4704
+ break ;
4702
4705
case ISD::LOAD: Res =WidenVecRes_LOAD (N);break ;
4703
4706
case ISD::STEP_VECTOR:
4704
4707
case ISD::SPLAT_VECTOR:
@@ -6080,6 +6083,74 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
6080
6083
N->getOperand (1 ), N->getOperand (2 ));
6081
6084
}
6082
6085
6086
+ // / Either return the same load or provide appropriate casts
6087
+ // / from the load and return that.
6088
+ static SDValuecoerceLoadedValue (SDValue LdOp, EVT FirstVT, EVT WidenVT,
6089
+ TypeSize LdWidth, TypeSize FirstVTWidth,
6090
+ SDLoc dl, SelectionDAG &DAG) {
6091
+ assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
6092
+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6093
+ if (!FirstVT.isVector ()) {
6094
+ unsigned NumElts =
6095
+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
6096
+ EVT NewVecVT =EVT::getVectorVT (*DAG.getContext (), FirstVT, NumElts);
6097
+ SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
6098
+ return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
6099
+ }
6100
+ assert (FirstVT == WidenVT);
6101
+ return LdOp;
6102
+ }
6103
+
6104
+ static std::optional<EVT>findMemType (SelectionDAG &DAG,
6105
+ const TargetLowering &TLI,unsigned Width,
6106
+ EVT WidenVT,unsigned Align,
6107
+ unsigned WidenEx);
6108
+
6109
+ SDValueDAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD (AtomicSDNode *LD) {
6110
+ EVT WidenVT =
6111
+ TLI.getTypeToTransformTo (*DAG.getContext (), LD->getValueType (0 ));
6112
+ EVT LdVT = LD->getMemoryVT ();
6113
+ SDLocdl (LD);
6114
+ assert (LdVT.isVector () && WidenVT.isVector () &&" Expected vectors" );
6115
+ assert (LdVT.isScalableVector () == WidenVT.isScalableVector () &&
6116
+ " Must be scalable" );
6117
+ assert (LdVT.getVectorElementType () == WidenVT.getVectorElementType () &&
6118
+ " Expected equivalent element types" );
6119
+
6120
+ // Load information
6121
+ SDValue Chain = LD->getChain ();
6122
+ SDValue BasePtr = LD->getBasePtr ();
6123
+ MachineMemOperand::Flags MMOFlags = LD->getMemOperand ()->getFlags ();
6124
+ AAMDNodes AAInfo = LD->getAAInfo ();
6125
+
6126
+ TypeSize LdWidth = LdVT.getSizeInBits ();
6127
+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6128
+ TypeSize WidthDiff = WidenWidth - LdWidth;
6129
+
6130
+ // Find the vector type that can load from.
6131
+ std::optional<EVT> FirstVT =
6132
+ findMemType (DAG, TLI, LdWidth.getKnownMinValue (), WidenVT,/* LdAlign=*/ 0 ,
6133
+ WidthDiff.getKnownMinValue ());
6134
+
6135
+ if (!FirstVT)
6136
+ return SDValue ();
6137
+
6138
+ SmallVector<EVT,8 > MemVTs;
6139
+ TypeSize FirstVTWidth = FirstVT->getSizeInBits ();
6140
+
6141
+ SDValue LdOp = DAG.getAtomicLoad (ISD::NON_EXTLOAD, dl, *FirstVT, *FirstVT,
6142
+ Chain, BasePtr, LD->getMemOperand ());
6143
+
6144
+ // Load the element with one instruction.
6145
+ SDValue Result =coerceLoadedValue (LdOp, *FirstVT, WidenVT, LdWidth,
6146
+ FirstVTWidth, dl, DAG);
6147
+
6148
+ // Modified the chain - switch anything that used the old chain to use
6149
+ // the new one.
6150
+ ReplaceValueWith (SDValue (LD,1 ), LdOp.getValue (1 ));
6151
+ return Result;
6152
+ }
6153
+
6083
6154
SDValueDAGTypeLegalizer::WidenVecRes_LOAD (SDNode *N) {
6084
6155
LoadSDNode *LD = cast<LoadSDNode>(N);
6085
6156
ISD::LoadExtType ExtType = LD->getExtensionType ();
@@ -7988,29 +8059,9 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
7988
8059
LdChain.push_back (LdOp.getValue (1 ));
7989
8060
7990
8061
// Check if we can load the element with one instruction.
7991
- if (MemVTs.empty ()) {
7992
- assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
7993
- if (!FirstVT->isVector ()) {
7994
- unsigned NumElts =
7995
- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7996
- EVT NewVecVT =EVT::getVectorVT (*DAG.getContext (), *FirstVT, NumElts);
7997
- SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
7998
- return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
7999
- }
8000
- if (FirstVT == WidenVT)
8001
- return LdOp;
8002
-
8003
- // TODO: We don't currently have any tests that exercise this code path.
8004
- assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () ==0 );
8005
- unsigned NumConcat =
8006
- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
8007
- SmallVector<SDValue,16 >ConcatOps (NumConcat);
8008
- SDValue UndefVal = DAG.getUNDEF (*FirstVT);
8009
- ConcatOps[0 ] = LdOp;
8010
- for (unsigned i =1 ; i != NumConcat; ++i)
8011
- ConcatOps[i] = UndefVal;
8012
- return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
8013
- }
8062
+ if (MemVTs.empty ())
8063
+ return coerceLoadedValue (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl,
8064
+ DAG);
8014
8065
8015
8066
// Load vector by using multiple loads from largest vector to scalar.
8016
8067
SmallVector<SDValue,16 > LdOps;