@@ -4622,6 +4622,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
4622
4622
break ;
4623
4623
case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR (N); break ;
4624
4624
case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT (N); break ;
4625
+ case ISD::ATOMIC_LOAD:
4626
+ Res = WidenVecRes_ATOMIC_LOAD (cast<AtomicSDNode>(N));
4627
+ break ;
4625
4628
case ISD::LOAD: Res = WidenVecRes_LOAD (N); break ;
4626
4629
case ISD::STEP_VECTOR:
4627
4630
case ISD::SPLAT_VECTOR:
@@ -6003,6 +6006,74 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
6003
6006
N->getOperand (1 ), N->getOperand (2 ));
6004
6007
}
6005
6008
6009
+ // / Either return the same load or provide appropriate casts
6010
+ // / from the load and return that.
6011
+ static SDValue coerceLoadedValue (SDValue LdOp, EVT FirstVT, EVT WidenVT,
6012
+ TypeSize LdWidth, TypeSize FirstVTWidth,
6013
+ SDLoc dl, SelectionDAG &DAG) {
6014
+ assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
6015
+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6016
+ if (!FirstVT.isVector ()) {
6017
+ unsigned NumElts =
6018
+ WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
6019
+ EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), FirstVT, NumElts);
6020
+ SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
6021
+ return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
6022
+ }
6023
+ assert (FirstVT == WidenVT);
6024
+ return LdOp;
6025
+ }
6026
+
6027
+ static std::optional<EVT> findMemType (SelectionDAG &DAG,
6028
+ const TargetLowering &TLI, unsigned Width,
6029
+ EVT WidenVT, unsigned Align,
6030
+ unsigned WidenEx);
6031
+
6032
+ SDValue DAGTypeLegalizer::WidenVecRes_ATOMIC_LOAD (AtomicSDNode *LD) {
6033
+ EVT WidenVT =
6034
+ TLI.getTypeToTransformTo (*DAG.getContext (), LD->getValueType (0 ));
6035
+ EVT LdVT = LD->getMemoryVT ();
6036
+ SDLoc dl (LD);
6037
+ assert (LdVT.isVector () && WidenVT.isVector () && " Expected vectors" );
6038
+ assert (LdVT.isScalableVector () == WidenVT.isScalableVector () &&
6039
+ " Must be scalable" );
6040
+ assert (LdVT.getVectorElementType () == WidenVT.getVectorElementType () &&
6041
+ " Expected equivalent element types" );
6042
+
6043
+ // Load information
6044
+ SDValue Chain = LD->getChain ();
6045
+ SDValue BasePtr = LD->getBasePtr ();
6046
+ MachineMemOperand::Flags MMOFlags = LD->getMemOperand ()->getFlags ();
6047
+ AAMDNodes AAInfo = LD->getAAInfo ();
6048
+
6049
+ TypeSize LdWidth = LdVT.getSizeInBits ();
6050
+ TypeSize WidenWidth = WidenVT.getSizeInBits ();
6051
+ TypeSize WidthDiff = WidenWidth - LdWidth;
6052
+
6053
+ // Find the vector type that can load from.
6054
+ std::optional<EVT> FirstVT =
6055
+ findMemType (DAG, TLI, LdWidth.getKnownMinValue (), WidenVT, /* LdAlign=*/ 0 ,
6056
+ WidthDiff.getKnownMinValue ());
6057
+
6058
+ if (!FirstVT)
6059
+ return SDValue ();
6060
+
6061
+ SmallVector<EVT, 8 > MemVTs;
6062
+ TypeSize FirstVTWidth = FirstVT->getSizeInBits ();
6063
+
6064
+ SDValue LdOp = DAG.getAtomicLoad (ISD::NON_EXTLOAD, dl, *FirstVT, *FirstVT,
6065
+ Chain, BasePtr, LD->getMemOperand ());
6066
+
6067
+ // Load the element with one instruction.
6068
+ SDValue Result = coerceLoadedValue (LdOp, *FirstVT, WidenVT, LdWidth,
6069
+ FirstVTWidth, dl, DAG);
6070
+
6071
+ // Modified the chain - switch anything that used the old chain to use
6072
+ // the new one.
6073
+ ReplaceValueWith (SDValue (LD, 1 ), LdOp.getValue (1 ));
6074
+ return Result;
6075
+ }
6076
+
6006
6077
SDValue DAGTypeLegalizer::WidenVecRes_LOAD (SDNode *N) {
6007
6078
LoadSDNode *LD = cast<LoadSDNode>(N);
6008
6079
ISD::LoadExtType ExtType = LD->getExtensionType ();
@@ -7894,29 +7965,9 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
7894
7965
LdChain.push_back (LdOp.getValue (1 ));
7895
7966
7896
7967
// Check if we can load the element with one instruction.
7897
- if (MemVTs.empty ()) {
7898
- assert (TypeSize::isKnownLE (LdWidth, FirstVTWidth));
7899
- if (!FirstVT->isVector ()) {
7900
- unsigned NumElts =
7901
- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7902
- EVT NewVecVT = EVT::getVectorVT (*DAG.getContext (), *FirstVT, NumElts);
7903
- SDValue VecOp = DAG.getNode (ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
7904
- return DAG.getNode (ISD::BITCAST, dl, WidenVT, VecOp);
7905
- }
7906
- if (FirstVT == WidenVT)
7907
- return LdOp;
7908
-
7909
- // TODO: We don't currently have any tests that exercise this code path.
7910
- assert (WidenWidth.getFixedValue () % FirstVTWidth.getFixedValue () == 0 );
7911
- unsigned NumConcat =
7912
- WidenWidth.getFixedValue () / FirstVTWidth.getFixedValue ();
7913
- SmallVector<SDValue, 16 > ConcatOps (NumConcat);
7914
- SDValue UndefVal = DAG.getUNDEF (*FirstVT);
7915
- ConcatOps[0 ] = LdOp;
7916
- for (unsigned i = 1 ; i != NumConcat; ++i)
7917
- ConcatOps[i] = UndefVal;
7918
- return DAG.getNode (ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
7919
- }
7968
+ if (MemVTs.empty ())
7969
+ return coerceLoadedValue (LdOp, *FirstVT, WidenVT, LdWidth, FirstVTWidth, dl,
7970
+ DAG);
7920
7971
7921
7972
// Load vector by using multiple loads from largest vector to scalar.
7922
7973
SmallVector<SDValue, 16 > LdOps;
0 commit comments