Skip to content

[Intrinsics] Add Intrinsic::getFnAttributes() (NFC) #132029

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
Mar 20, 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
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/Intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Function;
class LLVMContext;
class Module;
class AttributeList;
class AttributeSet;

/// This namespace contains an enum with a value for every intrinsic/builtin
/// function known by LLVM. The enum values are returned by
Expand Down Expand Up @@ -87,6 +88,9 @@ namespace Intrinsic {
/// Return the attributes for an intrinsic.
AttributeList getAttributes(LLVMContext &C, ID id);

/// Return the function attributes for an intrinsic.
AttributeSet getFnAttributes(LLVMContext &C, ID id);

/// Look up the Function declaration of the intrinsic \p id in the Module
/// \p M. If it does not exist, add a declaration and return it. Otherwise,
/// return the existing declaration.
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/ExpandVectorPredication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ static bool maySpeculateLanes(VPIntrinsic &VPI) {
return false;
// Fallback to whether the intrinsic is speculatable.
if (auto IntrID = VPI.getFunctionalIntrinsicID())
return Intrinsic::getAttributes(VPI.getContext(), *IntrID)
.hasFnAttr(Attribute::AttrKind::Speculatable);
return Intrinsic::getFnAttributes(VPI.getContext(), *IntrID)
.hasAttribute(Attribute::AttrKind::Speculatable);
if (auto Opc = VPI.getFunctionalOpcode())
return isSafeToSpeculativelyExecuteWithOpcode(*Opc, &VPI);
return false;
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,9 +880,9 @@ MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
MachineInstrBuilder
MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
ArrayRef<Register> ResultRegs) {
auto Attrs = Intrinsic::getAttributes(getContext(), ID);
AttributeSet Attrs = Intrinsic::getFnAttributes(getContext(), ID);
bool HasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
bool isConvergent = Attrs.hasFnAttr(Attribute::Convergent);
bool isConvergent = Attrs.hasAttribute(Attribute::Convergent);
return buildIntrinsic(ID, ResultRegs, HasSideEffects, isConvergent);
}

Expand All @@ -899,9 +899,9 @@ MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,

MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
ArrayRef<DstOp> Results) {
auto Attrs = Intrinsic::getAttributes(getContext(), ID);
AttributeSet Attrs = Intrinsic::getFnAttributes(getContext(), ID);
bool HasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
bool isConvergent = Attrs.hasFnAttr(Attribute::Convergent);
bool isConvergent = Attrs.hasAttribute(Attribute::Convergent);
return buildIntrinsic(ID, Results, HasSideEffects, isConvergent);
}

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ bool MachineVerifier::verifyGIntrinsicSideEffects(const MachineInstr *MI) {
Opcode == TargetOpcode::G_INTRINSIC_CONVERGENT;
unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
AttributeList Attrs = Intrinsic::getAttributes(
AttributeSet Attrs = Intrinsic::getFnAttributes(
MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
bool DeclHasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
if (NoSideEffects && DeclHasSideEffects) {
Expand All @@ -1094,9 +1094,9 @@ bool MachineVerifier::verifyGIntrinsicConvergence(const MachineInstr *MI) {
Opcode == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS;
unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
AttributeList Attrs = Intrinsic::getAttributes(
AttributeSet Attrs = Intrinsic::getFnAttributes(
MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
bool DeclIsConvergent = Attrs.hasFnAttr(Attribute::Convergent);
bool DeclIsConvergent = Attrs.hasAttribute(Attribute::Convergent);
if (NotConvergent && DeclIsConvergent) {
report(Twine(TII->getName(Opcode), " used with a convergent intrinsic"),
MI);
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/IR/Intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,14 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_ATTRIBUTES

AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {
if (id == 0)
return AttributeSet();
uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
uint8_t FnAttrID = PackedID >> 8;
return getIntrinsicFnAttributeSet(C, FnAttrID);
}

Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
ArrayRef<Type *> Tys) {
// There can never be multiple globals with the same name of different types,
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/AMDGPU/SIISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,8 +1222,8 @@ bool SITargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,

if (const AMDGPU::RsrcIntrinsic *RsrcIntr =
AMDGPU::lookupRsrcIntrinsic(IntrID)) {
AttributeList Attr =
Intrinsic::getAttributes(CI.getContext(), (Intrinsic::ID)IntrID);
AttributeSet Attr =
Intrinsic::getFnAttributes(CI.getContext(), (Intrinsic::ID)IntrID);
MemoryEffects ME = Attr.getMemoryEffects();
if (ME.doesNotAccessMemory())
return false;
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -1263,13 +1263,13 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
: VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, DL),
VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
LLVMContext &Ctx = Ty->getContext();
AttributeList Attrs = Intrinsic::getAttributes(Ctx, VectorIntrinsicID);
AttributeSet Attrs = Intrinsic::getFnAttributes(Ctx, VectorIntrinsicID);
MemoryEffects ME = Attrs.getMemoryEffects();
MayReadFromMemory = ME.onlyWritesMemory();
MayWriteToMemory = ME.onlyReadsMemory();
MayHaveSideEffects = MayWriteToMemory ||
!Attrs.hasFnAttr(Attribute::NoUnwind) ||
!Attrs.hasFnAttr(Attribute::WillReturn);
!Attrs.hasAttribute(Attribute::NoUnwind) ||
!Attrs.hasAttribute(Attribute::WillReturn);
}

~VPWidenIntrinsicRecipe() override = default;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Vectorize/VectorCombine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,8 +995,8 @@ bool VectorCombine::scalarizeVPIntrinsic(Instruction &I) {
// scalarizing it.
bool SafeToSpeculate;
if (ScalarIntrID)
SafeToSpeculate = Intrinsic::getAttributes(I.getContext(), *ScalarIntrID)
.hasFnAttr(Attribute::AttrKind::Speculatable);
SafeToSpeculate = Intrinsic::getFnAttributes(I.getContext(), *ScalarIntrID)
.hasAttribute(Attribute::AttrKind::Speculatable);
else
SafeToSpeculate = isSafeToSpeculativelyExecuteWithOpcode(
*FunctionalOpcode, &VPI, nullptr, &AC, &DT);
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/TableGen/intrinsic-attrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ def int_deref_ptr_ret : Intrinsic<[llvm_ptr_ty], [], [Dereferenceable<RetIndex,
// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
// CHECK-NEXT: });


// CHECK: getAttributes(LLVMContext &C, ID id)
// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
// CHECK: 0 << 8 | 0, // llvm.deref.ptr.ret
// CHECK: 1 << 8 | 1, // llvm.random.gen

// CHECK: getAttributes(LLVMContext &C, ID id)
// CHECK: case 1:
// CHECK-NEXT: return AttributeList::get(C, {
// CHECK-NEXT: {AttributeList::FunctionIndex, getIntrinsicFnAttributeSet(C, FnAttrID)}
Expand Down
26 changes: 13 additions & 13 deletions llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,6 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
default: llvm_unreachable("Invalid attribute set number");)";

for (const CodeGenIntrinsic &Int : Ints) {
if (!hasFnAttributes(Int))
continue;
unsigned ID = UniqFnAttributes.size();
if (!UniqFnAttributes.try_emplace(&Int, ID).second)
continue;
Expand Down Expand Up @@ -606,8 +604,7 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
}
} // getIntrinsicFnAttributeSet

AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
)";
static constexpr uint16_t IntrinsicsToAttributesMap[] = {)";

// Compute the maximum number of attribute arguments and the map. For function
// attributes, we only consider whether the intrinsics has any function
Expand All @@ -619,6 +616,14 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
UniqAttributes.try_emplace(&Int, ID);
}

// Emit an array of AttributeList. Most intrinsics will have at least one
// entry, for the function itself (index ~1), which is usually nounwind.
for (const CodeGenIntrinsic &Int : Ints) {
uint16_t FnAttrIndex = UniqFnAttributes[&Int];
OS << formatv("\n {} << 8 | {}, // {}", FnAttrIndex,
UniqAttributes[&Int], Int.Name);
}

// Assign a 16-bit packed ID for each intrinsic. The lower 8-bits will be its
// "argument attribute ID" (index in UniqAttributes) and upper 8 bits will be
// its "function attribute ID" (index in UniqFnAttributes).
Expand All @@ -627,17 +632,12 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
if (UniqFnAttributes.size() > 256)
PrintFatalError("Too many unique function attributes for table!");

// Emit an array of AttributeList. Most intrinsics will have at least one
// entry, for the function itself (index ~1), which is usually nounwind.
OS << " static constexpr uint16_t IntrinsicsToAttributesMap[] = {";
for (const CodeGenIntrinsic &Int : Ints) {
uint16_t FnAttrIndex = hasFnAttributes(Int) ? UniqFnAttributes[&Int] : 0;
OS << formatv("\n {} << 8 | {}, // {}", FnAttrIndex,
UniqAttributes[&Int], Int.Name);
}
OS << R"(
};

AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {)";

OS << formatv(R"(
};
if (id == 0)
return AttributeList();

Expand Down