Skip to content

Commit 39f039e

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. commit-id:2894ccd1
1 parent 7b4708f commit 39f039e

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
@@ -1068,6 +1068,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
10681068
SDValue WidenVecRes_EXTRACT_SUBVECTOR(SDNode* N);
10691069
SDValue WidenVecRes_INSERT_SUBVECTOR(SDNode *N);
10701070
SDValue WidenVecRes_INSERT_VECTOR_ELT(SDNode* N);
1071+
SDValue WidenVecRes_ATOMIC_LOAD(AtomicSDNode *N);
10711072
SDValue WidenVecRes_LOAD(SDNode* N);
10721073
SDValue WidenVecRes_VP_LOAD(VPLoadSDNode *N);
10731074
SDValue WidenVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *N);

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4622,6 +4622,9 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
46224622
break;
46234623
case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
46244624
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;
46254628
case ISD::LOAD: Res = WidenVecRes_LOAD(N); break;
46264629
case ISD::STEP_VECTOR:
46274630
case ISD::SPLAT_VECTOR:
@@ -6003,6 +6006,74 @@ SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
60036006
N->getOperand(1), N->getOperand(2));
60046007
}
60056008

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+
60066077
SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
60076078
LoadSDNode *LD = cast<LoadSDNode>(N);
60086079
ISD::LoadExtType ExtType = LD->getExtensionType();
@@ -7894,29 +7965,9 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
78947965
LdChain.push_back(LdOp.getValue(1));
78957966

78967967
// 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);
79207971

79217972
// Load vector by using multiple loads from largest vector to scalar.
79227973
SmallVector<SDValue, 16> LdOps;

0 commit comments

Comments
 (0)