Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f3d7a77
[𝘀𝗽𝗿] changes to main this commit is based on
pcc Mar 28, 2025
14dae4d
[𝘀𝗽𝗿] initial version
pcc Mar 28, 2025
a687d18
[𝘀𝗽𝗿] changes introduced through rebase
pcc May 13, 2025
37905a8
Rebase
pcc May 13, 2025
70b8768
[𝘀𝗽𝗿] changes introduced through rebase
pcc May 24, 2025
dbbe889
Rebase, add suppport for pseudo
pcc May 24, 2025
3ebc01b
[𝘀𝗽𝗿] changes introduced through rebase
pcc Jul 9, 2025
ffe130a
Rebase
pcc Jul 9, 2025
f376956
[𝘀𝗽𝗿] changes introduced through rebase
pcc Jul 10, 2025
ee32a67
Rebase
pcc Jul 10, 2025
f1b1e47
[𝘀𝗽𝗿] changes introduced through rebase
pcc Jul 30, 2025
3beca25
Address review comments, add tests
pcc Jul 30, 2025
23de70d
[𝘀𝗽𝗿] changes introduced through rebase
pcc Aug 1, 2025
431231c
Rebase, add LangRef
pcc Aug 1, 2025
da91716
[𝘀𝗽𝗿] changes introduced through rebase
pcc Aug 1, 2025
2fc0706
Rebase
pcc Aug 1, 2025
c81704e
[𝘀𝗽𝗿] changes introduced through rebase
pcc Sep 3, 2025
f054523
Rebase
pcc Sep 3, 2025
c28c64d
[𝘀𝗽𝗿] changes introduced through rebase
pcc Sep 5, 2025
65bac0b
Rebase
pcc Sep 5, 2025
f4c61b4
Tweak LangRef
pcc Sep 11, 2025
0c2d97b
Add combine check
pcc Sep 11, 2025
024b2b9
[𝘀𝗽𝗿] changes introduced through rebase
pcc Oct 9, 2025
7f994b0
Rebase
pcc Oct 9, 2025
258e526
[𝘀𝗽𝗿] changes introduced through rebase
pcc Nov 26, 2025
6251dbe
Rebase, address review comments
pcc Nov 26, 2025
70f7e9e
[𝘀𝗽𝗿] changes introduced through rebase
pcc Nov 26, 2025
9ddfc41
Format
pcc Nov 26, 2025
8c6798f
[𝘀𝗽𝗿] landed version
pcc Nov 26, 2025
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
16 changes: 16 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3234,6 +3234,22 @@ A "convergencectrl" operand bundle is only valid on a ``convergent`` operation.
When present, the operand bundle must contain exactly one value of token type.
See the :doc:`ConvergentOperations` document for details.

Deactivation Symbol Operand Bundles
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A ``"deactivation-symbol"`` operand bundle is valid on the following
instructions (AArch64 only):

- Call to a normal function with ``notail`` attribute and a first argument and
return value of type ``ptr``.
- Call to ``llvm.ptrauth.sign`` or ``llvm.ptrauth.auth`` intrinsics.

This operand bundle specifies that if the deactivation symbol is defined
to a valid value for the target, the marked instruction will return the
value of its first argument instead of calling the specified function
or intrinsic. This is achieved with ``PATCHINST`` relocations on the
target instructions (see the AArch64 psABI for details).

.. _moduleasm:

Module-Level Inline Assembly
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ class LLVM_ABI CallLowering {

/// True if this call results in convergent operations.
bool IsConvergent = true;

GlobalValue *DeactivationSymbol = nullptr;
};

/// Argument handling is mostly uniform between the four places that
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct MachineIRBuilderState {
MDNode *PCSections = nullptr;
/// MMRA Metadata to be set on any instruction we create.
MDNode *MMRA = nullptr;
Value *DS = nullptr;

/// \name Fields describing the insertion point.
/// @{
Expand Down Expand Up @@ -369,6 +370,7 @@ class LLVM_ABI MachineIRBuilder {
State.II = MI.getIterator();
setPCSections(MI.getPCSections());
setMMRAMetadata(MI.getMMRAMetadata());
setDeactivationSymbol(MI.getDeactivationSymbol());
}
/// @}

Expand Down Expand Up @@ -405,6 +407,9 @@ class LLVM_ABI MachineIRBuilder {
/// Set the PC sections metadata to \p MD for all the next build instructions.
void setMMRAMetadata(MDNode *MMRA) { State.MMRA = MMRA; }

Value *getDeactivationSymbol() { return State.DS; }
void setDeactivationSymbol(Value *DS) { State.DS = DS; }

/// Get the current instruction's MMRA metadata.
MDNode *getMMRAMetadata() { return State.MMRA; }

Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/ISDOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,10 @@ enum NodeType {
// Outputs: Output Chain
CLEAR_CACHE,

// Untyped node storing deactivation symbol reference
// (DeactivationSymbolSDNode).
DEACTIVATION_SYMBOL,
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific pre-isel opcode values start here.
BUILTIN_OP_END
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,7 @@ class LLVM_ABI MachineFunction {
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr,
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
MDNode *MMRAs = nullptr);
MDNode *MMRAs = nullptr, Value *DS = nullptr);

/// Allocate a string and populate it with the given external symbol name.
const char *createExternalSymbolName(StringRef Name);
Expand Down
40 changes: 31 additions & 9 deletions llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,29 +160,33 @@ class MachineInstr
///
/// This has to be defined eagerly due to the implementation constraints of
/// `PointerSumType` where it is used.
class ExtraInfo final : TrailingObjects<ExtraInfo, MachineMemOperand *,
MCSymbol *, MDNode *, uint32_t> {
class ExtraInfo final
: TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *, MDNode *,
uint32_t, Value *> {
public:
static ExtraInfo *create(BumpPtrAllocator &Allocator,
ArrayRef<MachineMemOperand *> MMOs,
MCSymbol *PreInstrSymbol = nullptr,
MCSymbol *PostInstrSymbol = nullptr,
MDNode *HeapAllocMarker = nullptr,
MDNode *PCSections = nullptr, uint32_t CFIType = 0,
MDNode *MMRAs = nullptr) {
MDNode *MMRAs = nullptr, Value *DS = nullptr) {
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
bool HasMMRAs = MMRAs != nullptr;
bool HasCFIType = CFIType != 0;
bool HasPCSections = PCSections != nullptr;
bool HasDS = DS != nullptr;
auto *Result = new (Allocator.Allocate(
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t>(
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t,
Value *>(
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType),
HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType, HasDS),
alignof(ExtraInfo)))
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs);
HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs,
HasDS);

// Copy the actual data into the trailing objects.
llvm::copy(MMOs, Result->getTrailingObjects<MachineMemOperand *>());
Expand All @@ -202,6 +206,8 @@ class MachineInstr
Result->getTrailingObjects<uint32_t>()[0] = CFIType;
if (HasMMRAs)
Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = MMRAs;
if (HasDS)
Result->getTrailingObjects<Value *>()[0] = DS;

return Result;
}
Expand Down Expand Up @@ -240,6 +246,10 @@ class MachineInstr
: nullptr;
}

Value *getDeactivationSymbol() const {
return HasDS ? getTrailingObjects<Value *>()[0] : 0;
}

private:
friend TrailingObjects;

Expand All @@ -255,6 +265,7 @@ class MachineInstr
const bool HasPCSections;
const bool HasCFIType;
const bool HasMMRAs;
const bool HasDS;

// Implement the `TrailingObjects` internal API.
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
Expand All @@ -269,16 +280,17 @@ class MachineInstr
size_t numTrailingObjects(OverloadToken<uint32_t>) const {
return HasCFIType;
}
size_t numTrailingObjects(OverloadToken<Value *>) const { return HasDS; }

// Just a boring constructor to allow us to initialize the sizes. Always use
// the `create` routine above.
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType,
bool HasMMRAs)
bool HasMMRAs, bool HasDS)
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
HasPostInstrSymbol(HasPostInstrSymbol),
HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections),
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs) {}
HasCFIType(HasCFIType), HasMMRAs(HasMMRAs), HasDS(HasDS) {}
};

/// Enumeration of the kinds of inline extra info available. It is important
Expand Down Expand Up @@ -867,6 +879,14 @@ class MachineInstr
return nullptr;
}

Value *getDeactivationSymbol() const {
if (!Info)
return nullptr;
if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
return EI->getDeactivationSymbol();
return nullptr;
}

/// Helper to extract a CFI type hash if one has been added.
uint32_t getCFIType() const {
if (!Info)
Expand Down Expand Up @@ -1969,6 +1989,8 @@ class MachineInstr
/// Set the CFI type for the instruction.
LLVM_ABI void setCFIType(MachineFunction &MF, uint32_t Type);

LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS);

/// Return the MIFlags which represent both MachineInstrs. This
/// should be used when merging two MachineInstrs into one. This routine does
/// not modify the MIFlags of this MachineInstr.
Expand Down Expand Up @@ -2088,7 +2110,7 @@ class MachineInstr
void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
MDNode *HeapAllocMarker, MDNode *PCSections,
uint32_t CFIType, MDNode *MMRAs);
uint32_t CFIType, MDNode *MMRAs, Value *DS);
};

/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the
Expand Down
27 changes: 22 additions & 5 deletions llvm/include/llvm/CodeGen/MachineInstrBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,44 @@ enum {
} // end namespace RegState

/// Set of metadata that should be preserved when using BuildMI(). This provides
/// a more convenient way of preserving DebugLoc, PCSections and MMRA.
/// a more convenient way of preserving certain data from the original
/// instruction.
class MIMetadata {
public:
MIMetadata() = default;
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr)
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA) {}
MIMetadata(DebugLoc DL, MDNode *PCSections = nullptr, MDNode *MMRA = nullptr,
Value *DeactivationSymbol = nullptr)
: DL(std::move(DL)), PCSections(PCSections), MMRA(MMRA),
DeactivationSymbol(DeactivationSymbol) {}
MIMetadata(const DILocation *DI, MDNode *PCSections = nullptr,
MDNode *MMRA = nullptr)
: DL(DI), PCSections(PCSections), MMRA(MMRA) {}
explicit MIMetadata(const Instruction &From)
: DL(From.getDebugLoc()),
PCSections(From.getMetadata(LLVMContext::MD_pcsections)) {}
PCSections(From.getMetadata(LLVMContext::MD_pcsections)),
DeactivationSymbol(getDeactivationSymbol(&From)) {}
explicit MIMetadata(const MachineInstr &From)
: DL(From.getDebugLoc()), PCSections(From.getPCSections()) {}
: DL(From.getDebugLoc()), PCSections(From.getPCSections()),
DeactivationSymbol(From.getDeactivationSymbol()) {}

const DebugLoc &getDL() const { return DL; }
MDNode *getPCSections() const { return PCSections; }
MDNode *getMMRAMetadata() const { return MMRA; }
Value *getDeactivationSymbol() const { return DeactivationSymbol; }

private:
DebugLoc DL;
MDNode *PCSections = nullptr;
MDNode *MMRA = nullptr;
Value *DeactivationSymbol = nullptr;

static inline Value *getDeactivationSymbol(const Instruction *I) {
if (auto *CB = dyn_cast<CallBase>(I))
if (auto Bundle =
CB->getOperandBundle(llvm::LLVMContext::OB_deactivation_symbol))
return Bundle->Inputs[0].get();
return nullptr;
}
};

class MachineInstrBuilder {
Expand Down Expand Up @@ -348,6 +363,8 @@ class MachineInstrBuilder {
MI->setPCSections(*MF, MIMD.getPCSections());
if (MIMD.getMMRAMetadata())
MI->setMMRAMetadata(*MF, MIMD.getMMRAMetadata());
if (MIMD.getDeactivationSymbol())
MI->setDeactivationSymbol(*MF, MIMD.getDeactivationSymbol());
return *this;
}

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,7 @@ class SelectionDAG {
int64_t offset = 0, unsigned TargetFlags = 0) {
return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags);
}
LLVM_ABI SDValue getDeactivationSymbol(const GlobalValue *GV);
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false);
SDValue getTargetFrameIndex(int FI, EVT VT) {
return getFrameIndex(FI, VT, true);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/SelectionDAGISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class SelectionDAGISel {
OPC_RecordChild7,
OPC_RecordMemRef,
OPC_CaptureGlueInput,
OPC_CaptureDeactivationSymbol,
OPC_MoveChild,
OPC_MoveChild0,
OPC_MoveChild1,
Expand Down
16 changes: 16 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAGNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,22 @@ class GlobalAddressSDNode : public SDNode {
}
};

class DeactivationSymbolSDNode : public SDNode {
friend class SelectionDAG;

const GlobalValue *TheGlobal;

DeactivationSymbolSDNode(const GlobalValue *GV, SDVTList VTs)
: SDNode(ISD::DEACTIVATION_SYMBOL, 0, DebugLoc(), VTs), TheGlobal(GV) {}

public:
const GlobalValue *getGlobal() const { return TheGlobal; }

static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::DEACTIVATION_SYMBOL;
}
};

class FrameIndexSDNode : public SDNode {
friend class SelectionDAG;

Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -4765,6 +4765,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
SmallVector<SDValue, 4> InVals;
const ConstantInt *CFIType = nullptr;
SDValue ConvergenceControlToken;
GlobalValue *DeactivationSymbol = nullptr;

std::optional<PtrAuthInfo> PAI;

Expand Down Expand Up @@ -4918,6 +4919,11 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
return *this;
}

CallLoweringInfo &setDeactivationSymbol(GlobalValue *Sym) {
DeactivationSymbol = Sym;
return *this;
}

ArgListTy &getArgs() {
return Args;
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/IR/LLVMContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ class LLVMContext {
OB_kcfi = 8, // "kcfi"
OB_convergencectrl = 9, // "convergencectrl"
OB_align = 10, // "align"
OB_LastBundleID = OB_align // Marker for last bundle ID
OB_deactivation_symbol = 11, // "deactivation-symbol"
OB_LastBundleID = OB_deactivation_symbol
};

/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/Target.td
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ class Instruction : InstructionEncoding {
// If so, make sure to override
// TargetInstrInfo::getInsertSubregLikeInputs.
bit variadicOpsAreDefs = false; // Are variadic operands definitions?
bit supportsDeactivationSymbol = false;

// Does the instruction have side effects that are not captured by any
// operands of the instruction or other flags?
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
assert(Info.CFIType->getType()->isIntegerTy(32) && "Invalid CFI type");
}

if (auto Bundle = CB.getOperandBundle(LLVMContext::OB_deactivation_symbol)) {
Info.DeactivationSymbol = cast<GlobalValue>(Bundle->Inputs[0]);
}

Info.CB = &CB;
Info.KnownCallees = CB.getMetadata(LLVMContext::MD_callees);
Info.CallConv = CallConv;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2917,6 +2917,9 @@ bool IRTranslator::translateIntrinsic(
}
}

if (auto Bundle = CB.getOperandBundle(LLVMContext::OB_deactivation_symbol))
MIB->setDeactivationSymbol(*MF, Bundle->Inputs[0].get());

return true;
}

Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ void MachineIRBuilder::setMF(MachineFunction &MF) {
//------------------------------------------------------------------------------

MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
return BuildMI(getMF(), {getDL(), getPCSections(), getMMRAMetadata()},
getTII().get(Opcode));
return BuildMI(
getMF(),
{getDL(), getPCSections(), getMMRAMetadata(), getDeactivationSymbol()},
getTII().get(Opcode));
}

MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRParser/MILexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("heap-alloc-marker", MIToken::kw_heap_alloc_marker)
.Case("pcsections", MIToken::kw_pcsections)
.Case("cfi-type", MIToken::kw_cfi_type)
.Case("deactivation-symbol", MIToken::kw_deactivation_symbol)
.Case("bbsections", MIToken::kw_bbsections)
.Case("bb_id", MIToken::kw_bb_id)
.Case("unknown-size", MIToken::kw_unknown_size)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRParser/MILexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ struct MIToken {
kw_heap_alloc_marker,
kw_pcsections,
kw_cfi_type,
kw_deactivation_symbol,
kw_bbsections,
kw_bb_id,
kw_unknown_size,
Expand Down
Loading
Loading