Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,12 @@ class SelectionDAG {
LLVM_ABI SDValue getElementCount(const SDLoc &DL, EVT VT, ElementCount EC,
bool ConstantFold = true);

/// Return a vector with the first 'Len' lanes set to true and remaining lanes
/// set to false. The mask's ValueType is the same as when comparing vectors
/// of type VT.
LLVM_ABI SDValue getMaskFromElementCount(const SDLoc &DL, EVT VT,
ElementCount Len);

/// Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
return getNode(ISD::GLOBAL_OFFSET_TABLE, SDLoc(), VT);
Expand Down
90 changes: 71 additions & 19 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6201,8 +6201,33 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Parts);
}

report_fatal_error("Don't know how to widen the result of "
"EXTRACT_SUBVECTOR for scalable vectors");
// Fallback to extracting through memory.

Align Alignment = DAG.getReducedAlign(InVT, /*UseABI=*/false);
SDValue StackPtr = DAG.CreateStackTemporary(InVT.getStoreSize(), Alignment);
auto &MF = DAG.getMachineFunction();
auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);

MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
PtrInfo, MachineMemOperand::MOStore,
LocationSize::beforeOrAfterPointer(), Alignment);
MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
PtrInfo, MachineMemOperand::MOLoad,
LocationSize::beforeOrAfterPointer(), Alignment);

// Write out the input vector.
SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, StoreMMO);

// Build a mask to match the length of the non-widened result.
SDValue Mask =
DAG.getMaskFromElementCount(dl, WidenVT, VT.getVectorElementCount());

// Read back the sub-vector setting the remaining lanes to poison.
StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, InVT, VT, Idx);
return DAG.getMaskedLoad(
WidenVT, dl, Ch, StackPtr, DAG.getUNDEF(StackPtr.getValueType()), Mask,
DAG.getPOISON(WidenVT), VT, LoadMMO, ISD::UNINDEXED, ISD::NON_EXTLOAD);
}

// We could try widening the input to the right length but for now, extract
Expand Down Expand Up @@ -6306,11 +6331,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
if (VT.isVector()) {
// If all else fails replace the load with a wide masked load.
SDLoc DL(N);
EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());

SDValue Len = DAG.getElementCount(DL, IdxVT, VT.getVectorElementCount());
SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, WideMaskVT,
DAG.getConstant(0, DL, IdxVT), Len);
SDValue Mask =
DAG.getMaskFromElementCount(DL, WideVT, VT.getVectorElementCount());

SDValue NewLoad = DAG.getMaskedLoad(
WideVT, DL, LD->getChain(), LD->getBasePtr(), LD->getOffset(), Mask,
Expand Down Expand Up @@ -7447,9 +7469,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(SDNode *N) {
SDValue InVec = N->getOperand(0);

EVT OrigVT = SubVec.getValueType();
if (getTypeAction(SubVec.getValueType()) == TargetLowering::TypeWidenVector)
SubVec = GetWidenedVector(SubVec);
Comment on lines -7450 to -7451
Copy link
Collaborator Author

@paulwalker-arm paulwalker-arm Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not necessary but I don't see any way the if statement can be false because at this point the result (and thus first operand) must be legal.


SubVec = GetWidenedVector(SubVec);
EVT SubVT = SubVec.getValueType();

// Whether or not all the elements of the widened SubVec will be inserted into
Expand All @@ -7471,17 +7491,52 @@ SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(SDNode *N) {
}
}

if (!IndicesValid)
report_fatal_error(
"Don't know how to widen the operands for INSERT_SUBVECTOR");

SDLoc DL(N);

// We need to make sure that the indices are still valid, otherwise we might
// widen what was previously well-defined to something undefined.
if (IndicesValid && InVec.isUndef() && N->getConstantOperandVal(2) == 0)
if (InVec.isUndef() && N->getConstantOperandVal(2) == 0)
return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, InVec, SubVec,
N->getOperand(2));

if (!IndicesValid || OrigVT.isScalableVector())
report_fatal_error(
"Don't know how to widen the operands for INSERT_SUBVECTOR");
if (OrigVT.isScalableVector()) {
// Fallback to inserting through memory.

Align Alignment = DAG.getReducedAlign(VT, /*UseABI=*/false);
SDValue StackPtr = DAG.CreateStackTemporary(VT.getStoreSize(), Alignment);
auto &MF = DAG.getMachineFunction();
auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);

MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
PtrInfo, MachineMemOperand::MOStore,
LocationSize::beforeOrAfterPointer(), Alignment);
MachineMemOperand *LoadMMO = DAG.getMachineFunction().getMachineMemOperand(
PtrInfo, MachineMemOperand::MOLoad,
LocationSize::beforeOrAfterPointer(), Alignment);

// Write out the vector being inserting into.
SDValue Ch =
DAG.getStore(DAG.getEntryNode(), DL, InVec, StackPtr, StoreMMO);

// Build a mask to match the length of the sub-vector.
SDValue Mask =
DAG.getMaskFromElementCount(DL, SubVT, OrigVT.getVectorElementCount());

// Overwrite the sub-vector at the required offset.
StackPtr =
TLI.getVectorSubVecPointer(DAG, StackPtr, VT, OrigVT, N->getOperand(2));
Ch = DAG.getMaskedStore(Ch, DL, SubVec, StackPtr,
DAG.getUNDEF(StackPtr.getValueType()), Mask, VT,
StoreMMO, ISD::UNINDEXED, ISD::NON_EXTLOAD);

// Read back the result.
return DAG.getLoad(VT, DL, Ch, StackPtr, LoadMMO);
}

// If the operands can't be widened legally, just replace the INSERT_SUBVECTOR
// with a series of INSERT_VECTOR_ELT
Expand Down Expand Up @@ -7560,12 +7615,9 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
if (StVT.isVector()) {
// If all else fails replace the store with a wide masked store.
SDLoc DL(N);
EVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout());

SDValue WideStVal = GetWidenedVector(StVal);
SDValue Len = DAG.getElementCount(DL, IdxVT, StVT.getVectorElementCount());
SDValue Mask = DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, WideMaskVT,
DAG.getConstant(0, DL, IdxVT), Len);
SDValue Mask =
DAG.getMaskFromElementCount(DL, WideVT, StVT.getVectorElementCount());

return DAG.getMaskedStore(ST->getChain(), DL, WideStVal, ST->getBasePtr(),
ST->getOffset(), Mask, ST->getMemoryVT(),
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2112,6 +2112,14 @@ SDValue SelectionDAG::getElementCount(const SDLoc &DL, EVT VT, ElementCount EC,
return getConstant(EC.getKnownMinValue(), DL, VT);
}

SDValue SelectionDAG::getMaskFromElementCount(const SDLoc &DL, EVT DataVT,
ElementCount EC) {
EVT IdxVT = TLI->getVectorIdxTy(getDataLayout());
EVT MaskVT = TLI->getSetCCResultType(getDataLayout(), *getContext(), DataVT);
return getNode(ISD::GET_ACTIVE_LANE_MASK, DL, MaskVT,
getConstant(0, DL, IdxVT), getElementCount(DL, IdxVT, EC));
}

SDValue SelectionDAG::getStepVector(const SDLoc &DL, EVT ResVT) {
APInt One(ResVT.getScalarSizeInBits(), 1);
return getStepVector(DL, ResVT, One);
Expand Down
Loading