Skip to content

Commit 0738f70

Browse files
authored
[Intrinsics] Add Intrinsic::getFnAttributes() (NFC) (llvm#132029)
Most places that call Intrinsic::getAttributes() are only interested in the function attributes, so add a separate function for that. The motivation for this is that I'd like to add the ability to specify range attributes on intrinsics, which requires knowing the function type. This avoids needing to know the type for most attribute queries.
1 parent d4b586a commit 0738f70

File tree

10 files changed

+43
-31
lines changed

10 files changed

+43
-31
lines changed

llvm/include/llvm/IR/Intrinsics.h

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Function;
2828
class LLVMContext;
2929
class Module;
3030
class AttributeList;
31+
class AttributeSet;
3132

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

91+
/// Return the function attributes for an intrinsic.
92+
AttributeSet getFnAttributes(LLVMContext &C, ID id);
93+
9094
/// Look up the Function declaration of the intrinsic \p id in the Module
9195
/// \p M. If it does not exist, add a declaration and return it. Otherwise,
9296
/// return the existing declaration.

llvm/lib/CodeGen/ExpandVectorPredication.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ static bool maySpeculateLanes(VPIntrinsic &VPI) {
121121
return false;
122122
// Fallback to whether the intrinsic is speculatable.
123123
if (auto IntrID = VPI.getFunctionalIntrinsicID())
124-
return Intrinsic::getAttributes(VPI.getContext(), *IntrID)
125-
.hasFnAttr(Attribute::AttrKind::Speculatable);
124+
return Intrinsic::getFnAttributes(VPI.getContext(), *IntrID)
125+
.hasAttribute(Attribute::AttrKind::Speculatable);
126126
if (auto Opc = VPI.getFunctionalOpcode())
127127
return isSafeToSpeculativelyExecuteWithOpcode(*Opc, &VPI);
128128
return false;

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -880,9 +880,9 @@ MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
880880
MachineInstrBuilder
881881
MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
882882
ArrayRef<Register> ResultRegs) {
883-
auto Attrs = Intrinsic::getAttributes(getContext(), ID);
883+
AttributeSet Attrs = Intrinsic::getFnAttributes(getContext(), ID);
884884
bool HasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
885-
bool isConvergent = Attrs.hasFnAttr(Attribute::Convergent);
885+
bool isConvergent = Attrs.hasAttribute(Attribute::Convergent);
886886
return buildIntrinsic(ID, ResultRegs, HasSideEffects, isConvergent);
887887
}
888888

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

900900
MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
901901
ArrayRef<DstOp> Results) {
902-
auto Attrs = Intrinsic::getAttributes(getContext(), ID);
902+
AttributeSet Attrs = Intrinsic::getFnAttributes(getContext(), ID);
903903
bool HasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
904-
bool isConvergent = Attrs.hasFnAttr(Attribute::Convergent);
904+
bool isConvergent = Attrs.hasAttribute(Attribute::Convergent);
905905
return buildIntrinsic(ID, Results, HasSideEffects, isConvergent);
906906
}
907907

llvm/lib/CodeGen/MachineVerifier.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ bool MachineVerifier::verifyGIntrinsicSideEffects(const MachineInstr *MI) {
10701070
Opcode == TargetOpcode::G_INTRINSIC_CONVERGENT;
10711071
unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
10721072
if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
1073-
AttributeList Attrs = Intrinsic::getAttributes(
1073+
AttributeSet Attrs = Intrinsic::getFnAttributes(
10741074
MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
10751075
bool DeclHasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
10761076
if (NoSideEffects && DeclHasSideEffects) {
@@ -1094,9 +1094,9 @@ bool MachineVerifier::verifyGIntrinsicConvergence(const MachineInstr *MI) {
10941094
Opcode == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS;
10951095
unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
10961096
if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
1097-
AttributeList Attrs = Intrinsic::getAttributes(
1097+
AttributeSet Attrs = Intrinsic::getFnAttributes(
10981098
MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
1099-
bool DeclIsConvergent = Attrs.hasFnAttr(Attribute::Convergent);
1099+
bool DeclIsConvergent = Attrs.hasAttribute(Attribute::Convergent);
11001100
if (NotConvergent && DeclIsConvergent) {
11011101
report(Twine(TII->getName(Opcode), " used with a convergent intrinsic"),
11021102
MI);

llvm/lib/IR/Intrinsics.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,14 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
753753
#include "llvm/IR/IntrinsicImpl.inc"
754754
#undef GET_INTRINSIC_ATTRIBUTES
755755

756+
AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {
757+
if (id == 0)
758+
return AttributeSet();
759+
uint16_t PackedID = IntrinsicsToAttributesMap[id - 1];
760+
uint8_t FnAttrID = PackedID >> 8;
761+
return getIntrinsicFnAttributeSet(C, FnAttrID);
762+
}
763+
756764
Function *Intrinsic::getOrInsertDeclaration(Module *M, ID id,
757765
ArrayRef<Type *> Tys) {
758766
// There can never be multiple globals with the same name of different types,

llvm/lib/Target/AMDGPU/SIISelLowering.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1222,8 +1222,8 @@ bool SITargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
12221222

12231223
if (const AMDGPU::RsrcIntrinsic *RsrcIntr =
12241224
AMDGPU::lookupRsrcIntrinsic(IntrID)) {
1225-
AttributeList Attr =
1226-
Intrinsic::getAttributes(CI.getContext(), (Intrinsic::ID)IntrID);
1225+
AttributeSet Attr =
1226+
Intrinsic::getFnAttributes(CI.getContext(), (Intrinsic::ID)IntrID);
12271227
MemoryEffects ME = Attr.getMemoryEffects();
12281228
if (ME.doesNotAccessMemory())
12291229
return false;

llvm/lib/Transforms/Vectorize/VPlan.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -1263,13 +1263,13 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags {
12631263
: VPRecipeWithIRFlags(VPDef::VPWidenIntrinsicSC, CallArguments, DL),
12641264
VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
12651265
LLVMContext &Ctx = Ty->getContext();
1266-
AttributeList Attrs = Intrinsic::getAttributes(Ctx, VectorIntrinsicID);
1266+
AttributeSet Attrs = Intrinsic::getFnAttributes(Ctx, VectorIntrinsicID);
12671267
MemoryEffects ME = Attrs.getMemoryEffects();
12681268
MayReadFromMemory = ME.onlyWritesMemory();
12691269
MayWriteToMemory = ME.onlyReadsMemory();
12701270
MayHaveSideEffects = MayWriteToMemory ||
1271-
!Attrs.hasFnAttr(Attribute::NoUnwind) ||
1272-
!Attrs.hasFnAttr(Attribute::WillReturn);
1271+
!Attrs.hasAttribute(Attribute::NoUnwind) ||
1272+
!Attrs.hasAttribute(Attribute::WillReturn);
12731273
}
12741274

12751275
~VPWidenIntrinsicRecipe() override = default;

llvm/lib/Transforms/Vectorize/VectorCombine.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -995,8 +995,8 @@ bool VectorCombine::scalarizeVPIntrinsic(Instruction &I) {
995995
// scalarizing it.
996996
bool SafeToSpeculate;
997997
if (ScalarIntrID)
998-
SafeToSpeculate = Intrinsic::getAttributes(I.getContext(), *ScalarIntrID)
999-
.hasFnAttr(Attribute::AttrKind::Speculatable);
998+
SafeToSpeculate = Intrinsic::getFnAttributes(I.getContext(), *ScalarIntrID)
999+
.hasAttribute(Attribute::AttrKind::Speculatable);
10001000
else
10011001
SafeToSpeculate = isSafeToSpeculativelyExecuteWithOpcode(
10021002
*FunctionalOpcode, &VPI, nullptr, &AC, &DT);

llvm/test/TableGen/intrinsic-attrs.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ def int_deref_ptr_ret : Intrinsic<[llvm_ptr_ty], [], [Dereferenceable<RetIndex,
2222
// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
2323
// CHECK-NEXT: });
2424

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

29+
// CHECK: getAttributes(LLVMContext &C, ID id)
3030
// CHECK: case 1:
3131
// CHECK-NEXT: return AttributeList::get(C, {
3232
// CHECK-NEXT: {AttributeList::FunctionIndex, getIntrinsicFnAttributeSet(C, FnAttrID)}

llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp

+13-13
Original file line numberDiff line numberDiff line change
@@ -555,8 +555,6 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
555555
default: llvm_unreachable("Invalid attribute set number");)";
556556

557557
for (const CodeGenIntrinsic &Int : Ints) {
558-
if (!hasFnAttributes(Int))
559-
continue;
560558
unsigned ID = UniqFnAttributes.size();
561559
if (!UniqFnAttributes.try_emplace(&Int, ID).second)
562560
continue;
@@ -606,8 +604,7 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
606604
}
607605
} // getIntrinsicFnAttributeSet
608606
609-
AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
610-
)";
607+
static constexpr uint16_t IntrinsicsToAttributesMap[] = {)";
611608

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

619+
// Emit an array of AttributeList. Most intrinsics will have at least one
620+
// entry, for the function itself (index ~1), which is usually nounwind.
621+
for (const CodeGenIntrinsic &Int : Ints) {
622+
uint16_t FnAttrIndex = UniqFnAttributes[&Int];
623+
OS << formatv("\n {} << 8 | {}, // {}", FnAttrIndex,
624+
UniqAttributes[&Int], Int.Name);
625+
}
626+
622627
// Assign a 16-bit packed ID for each intrinsic. The lower 8-bits will be its
623628
// "argument attribute ID" (index in UniqAttributes) and upper 8 bits will be
624629
// its "function attribute ID" (index in UniqFnAttributes).
@@ -627,17 +632,12 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
627632
if (UniqFnAttributes.size() > 256)
628633
PrintFatalError("Too many unique function attributes for table!");
629634

630-
// Emit an array of AttributeList. Most intrinsics will have at least one
631-
// entry, for the function itself (index ~1), which is usually nounwind.
632-
OS << " static constexpr uint16_t IntrinsicsToAttributesMap[] = {";
633-
for (const CodeGenIntrinsic &Int : Ints) {
634-
uint16_t FnAttrIndex = hasFnAttributes(Int) ? UniqFnAttributes[&Int] : 0;
635-
OS << formatv("\n {} << 8 | {}, // {}", FnAttrIndex,
636-
UniqAttributes[&Int], Int.Name);
637-
}
635+
OS << R"(
636+
};
637+
638+
AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {)";
638639

639640
OS << formatv(R"(
640-
};
641641
if (id == 0)
642642
return AttributeList();
643643

0 commit comments

Comments
 (0)