Skip to content

[CodeGen] Remove handling for lifetime.start/end on non-alloca #149838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2025
Merged
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
5 changes: 2 additions & 3 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1425,10 +1425,9 @@ class SelectionDAG {

/// Creates a LifetimeSDNode that starts (`IsStart==true`) or ends
/// (`IsStart==false`) the lifetime of the portion of `FrameIndex` between
/// offsets `Offset` and `Offset + Size`.
/// offsets `0` and `Size`.
LLVM_ABI SDValue getLifetimeNode(bool IsStart, const SDLoc &dl, SDValue Chain,
int FrameIndex, int64_t Size,
int64_t Offset = -1);
int FrameIndex, int64_t Size);

/// Creates a PseudoProbeSDNode with function GUID `Guid` and
/// the index of the block `Index` it is probing, as well as the attributes
Expand Down
16 changes: 4 additions & 12 deletions llvm/include/llvm/CodeGen/SelectionDAGNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2004,25 +2004,17 @@ class FrameIndexSDNode : public SDNode {
class LifetimeSDNode : public SDNode {
friend class SelectionDAG;
int64_t Size;
int64_t Offset; // -1 if offset is unknown.

LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
SDVTList VTs, int64_t Size, int64_t Offset)
: SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {}
SDVTList VTs, int64_t Size)
: SDNode(Opcode, Order, dl, VTs), Size(Size) {}

public:
int64_t getFrameIndex() const {
return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
}

bool hasOffset() const { return Offset >= 0; }
int64_t getOffset() const {
assert(hasOffset() && "offset is unknown");
return Offset;
}
int64_t getSize() const {
assert(hasOffset() && "offset is unknown");
return Size;
}
int64_t getSize() const { return Size; }

// Methods to support isa and dyn_cast
static bool classof(const SDNode *N) {
Expand Down
20 changes: 4 additions & 16 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2189,23 +2189,11 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
unsigned Op = ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
: TargetOpcode::LIFETIME_END;

// Get the underlying objects for the location passed on the lifetime
// marker.
SmallVector<const Value *, 4> Allocas;
getUnderlyingObjects(CI.getArgOperand(1), Allocas);

// Iterate over each underlying object, creating lifetime markers for each
// static alloca. Quit if we find a non-static alloca.
for (const Value *V : Allocas) {
const AllocaInst *AI = dyn_cast<AllocaInst>(V);
if (!AI)
continue;

if (!AI->isStaticAlloca())
return true;
const AllocaInst *AI = cast<AllocaInst>(CI.getArgOperand(1));
if (!AI->isStaticAlloca())
return true;

MIRBuilder.buildInstr(Op).addFrameIndex(getOrCreateFrameIndex(*AI));
}
MIRBuilder.buildInstr(Op).addFrameIndex(getOrCreateFrameIndex(*AI));
return true;
}
case Intrinsic::fake_use: {
Expand Down
11 changes: 3 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22727,11 +22727,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {

SDValue DAGCombiner::visitLIFETIME_END(SDNode *N) {
const auto *LifetimeEnd = cast<LifetimeSDNode>(N);
if (!LifetimeEnd->hasOffset())
return SDValue();

const BaseIndexOffset LifetimeEndBase(N->getOperand(1), SDValue(),
LifetimeEnd->getOffset(), false);
const BaseIndexOffset LifetimeEndBase(N->getOperand(1), SDValue(), 0, false);

// We walk up the chains to find stores.
SmallVector<SDValue, 8> Chains = {N->getOperand(0)};
Expand Down Expand Up @@ -29418,9 +29414,8 @@ bool DAGCombiner::mayAlias(SDNode *Op0, SDNode *Op1) const {
return {false /*isVolatile*/,
/*isAtomic*/ false,
LN->getOperand(1),
(LN->hasOffset()) ? LN->getOffset() : 0,
(LN->hasOffset()) ? LocationSize::precise(LN->getSize())
: LocationSize::beforeOrAfterPointer(),
0,
LocationSize::precise(LN->getSize()),
(MachineMemOperand *)nullptr};
// Default.
return {false /*isvolatile*/,
Expand Down
12 changes: 4 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,10 +786,7 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
break;
case ISD::LIFETIME_START:
case ISD::LIFETIME_END:
if (cast<LifetimeSDNode>(N)->hasOffset()) {
ID.AddInteger(cast<LifetimeSDNode>(N)->getSize());
ID.AddInteger(cast<LifetimeSDNode>(N)->getOffset());
}
ID.AddInteger(cast<LifetimeSDNode>(N)->getSize());
break;
case ISD::PSEUDO_PROBE:
ID.AddInteger(cast<PseudoProbeSDNode>(N)->getGuid());
Expand Down Expand Up @@ -9364,7 +9361,7 @@ SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl,

SDValue SelectionDAG::getLifetimeNode(bool IsStart, const SDLoc &dl,
SDValue Chain, int FrameIndex,
int64_t Size, int64_t Offset) {
int64_t Size) {
const unsigned Opcode = IsStart ? ISD::LIFETIME_START : ISD::LIFETIME_END;
const auto VTs = getVTList(MVT::Other);
SDValue Ops[2] = {
Expand All @@ -9377,13 +9374,12 @@ SDValue SelectionDAG::getLifetimeNode(bool IsStart, const SDLoc &dl,
AddNodeIDNode(ID, Opcode, VTs, Ops);
ID.AddInteger(FrameIndex);
ID.AddInteger(Size);
ID.AddInteger(Offset);
void *IP = nullptr;
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP))
return SDValue(E, 0);

LifetimeSDNode *N = newSDNode<LifetimeSDNode>(
Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, Size, Offset);
LifetimeSDNode *N = newSDNode<LifetimeSDNode>(Opcode, dl.getIROrder(),
dl.getDebugLoc(), VTs, Size);
createOperands(N, Ops);
CSEMap.InsertNode(N, IP);
InsertNode(N);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,7 @@ BaseIndexOffset BaseIndexOffset::match(const SDNode *N,
if (const auto *LS0 = dyn_cast<LSBaseSDNode>(N))
return matchLSNode(LS0, DAG);
if (const auto *LN = dyn_cast<LifetimeSDNode>(N)) {
if (LN->hasOffset())
return BaseIndexOffset(LN->getOperand(1), SDValue(), LN->getOffset(),
false);
return BaseIndexOffset(LN->getOperand(1), SDValue(), false);
return BaseIndexOffset(LN->getOperand(1), SDValue(), 0, false);
}
return BaseIndexOffset();
}
Expand Down
33 changes: 9 additions & 24 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7596,32 +7596,17 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,

const int64_t ObjectSize =
cast<ConstantInt>(I.getArgOperand(0))->getSExtValue();
Value *const ObjectPtr = I.getArgOperand(1);
SmallVector<const Value *, 4> Allocas;
getUnderlyingObjects(ObjectPtr, Allocas);
const AllocaInst *LifetimeObject = cast<AllocaInst>(I.getArgOperand(1));

for (const Value *Alloca : Allocas) {
const AllocaInst *LifetimeObject = dyn_cast_or_null<AllocaInst>(Alloca);

// Could not find an Alloca.
if (!LifetimeObject)
continue;

// First check that the Alloca is static, otherwise it won't have a
// valid frame index.
auto SI = FuncInfo.StaticAllocaMap.find(LifetimeObject);
if (SI == FuncInfo.StaticAllocaMap.end())
return;
// First check that the Alloca is static, otherwise it won't have a
// valid frame index.
auto SI = FuncInfo.StaticAllocaMap.find(LifetimeObject);
if (SI == FuncInfo.StaticAllocaMap.end())
return;

const int FrameIndex = SI->second;
int64_t Offset;
if (GetPointerBaseWithConstantOffset(
ObjectPtr, Offset, DAG.getDataLayout()) != LifetimeObject)
Offset = -1; // Cannot determine offset from alloca to lifetime object.
Res = DAG.getLifetimeNode(IsStart, sdl, getRoot(), FrameIndex, ObjectSize,
Offset);
DAG.setRoot(Res);
}
const int FrameIndex = SI->second;
Res = DAG.getLifetimeNode(IsStart, sdl, getRoot(), FrameIndex, ObjectSize);
DAG.setRoot(Res);
return;
}
case Intrinsic::pseudoprobe: {
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -947,8 +947,7 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
<< ASC->getDestAddressSpace()
<< ']';
} else if (const LifetimeSDNode *LN = dyn_cast<LifetimeSDNode>(this)) {
if (LN->hasOffset())
OS << "<" << LN->getOffset() << " to " << LN->getOffset() + LN->getSize() << ">";
OS << "<0 to " << LN->getSize() << ">";
} else if (const auto *AA = dyn_cast<AssertAlignSDNode>(this)) {
OS << '<' << AA->getAlign().value() << '>';
}
Expand Down
Loading