Skip to content

Commit a9d4257

Browse files
committed
[SelectionDAG] Widen <2 x T> vector types for atomic load
Vector types of 2 elements must be widened. This change does this for vector types of atomic load in SelectionDAG so that it can translate aligned vectors of >1 size.
1 parent 206603c commit a9d4257

File tree

3 files changed

+361
-23
lines changed

3 files changed

+361
-23
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
10841084
SDValue WidenVecRes_EXTRACT_SUBVECTOR(SDNode* N);
10851085
SDValue WidenVecRes_INSERT_SUBVECTOR(SDNode *N);
10861086
SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N);
1087+
SDValue WidenVecRes_ATOMIC_LOAD(AtomicSDNode *N);
10871088
SDValue WidenVecRes_LOAD(SDNode* N);
10881089
SDValue WidenVecRes_VP_LOAD(VPLoadSDNode *N);
10891090
SDValue WidenVecRes_VP_LOAD_FF(VPLoadFFSDNode *N);

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
62516322
SDValue 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

Comments
 (0)