[llvm] [LLVM] Change Intrinsic::ID to encode target and intrinsic index (PR #113576)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 24 12:58:32 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Rahul Joshi (jurahul)
<details>
<summary>Changes</summary>
Change `Intrinsic::ID` enum values to encode an 8-bit target index in upper 16-bits and a 16-bit intrinsic index (within the target) in lower 16-bits.
This change is in preparation for being able to disable intrinsics for targets that are not enabled.
---
Patch is 64.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113576.diff
30 Files Affected:
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h (+2-2)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h (+2-2)
- (modified) llvm/include/llvm/IR/Intrinsics.h (+9)
- (added) llvm/include/llvm/Support/IntrinsicID.h (+59)
- (modified) llvm/lib/CodeGen/MachineOperand.cpp (+1-1)
- (modified) llvm/lib/CodeGen/MachineVerifier.cpp (+2-2)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp (+1-1)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+1-1)
- (modified) llvm/lib/IR/Core.cpp (+2-1)
- (modified) llvm/lib/IR/Intrinsics.cpp (+95-22)
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+1-1)
- (modified) llvm/lib/Target/X86/X86IntrinsicsInfo.h (+1-2)
- (modified) llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td (+7-7)
- (modified) llvm/test/TableGen/GlobalISelEmitter-SDNodeXForm-timm.td (+2-2)
- (modified) llvm/test/TableGen/GlobalISelEmitter-immarg-literal-pattern.td (+2-2)
- (modified) llvm/test/TableGen/GlobalISelEmitter-input-discard.td (+1-1)
- (modified) llvm/test/TableGen/GlobalISelEmitter.td (+4-4)
- (modified) llvm/test/TableGen/GlobalISelEmitterOverloadedPtr.td (+1-1)
- (modified) llvm/test/TableGen/immarg-predicated.td (+1-1)
- (modified) llvm/test/TableGen/immarg.td (+1-1)
- (modified) llvm/test/TableGen/intrinsic-overload-conflict.td (+1-1)
- (modified) llvm/test/TableGen/intrinsic-struct.td (+1-1)
- (modified) llvm/test/TableGen/predicate-patfags.td (+2-2)
- (modified) llvm/unittests/IR/VPIntrinsicTest.cpp (+8-7)
- (modified) llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp (+113-46)
- (modified) llvm/utils/TableGen/Basic/CodeGenIntrinsics.h (+19-14)
- (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp (+1-1)
- (modified) llvm/utils/TableGen/Common/CodeGenDAGPatterns.h (+3-11)
- (modified) llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp (+2-2)
- (modified) llvm/utils/TableGen/IntrinsicEmitter.cpp (+103-81)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 7b42722ca8d4f1..383ce96813d84d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -275,7 +275,7 @@ enum {
/// Check the operand is a specific intrinsic ID
/// - InsnID(ULEB128) - Instruction ID
/// - OpIdx(ULEB128) - Operand index
- /// - IID(2) - Expected Intrinsic ID
+ /// - IID(4) - Expected Intrinsic ID
GIM_CheckIntrinsicID,
/// Check the operand is a specific predicate
@@ -411,7 +411,7 @@ enum {
/// Adds an intrinsic ID to the specified instruction.
/// - InsnID(ULEB128) - Instruction ID to modify
- /// - IID(2) - Intrinsic ID
+ /// - IID(4) - Intrinsic ID
GIR_AddIntrinsicID,
/// Marks the implicit def of a register as dead.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 9f8eb030a96c64..775998fe53a7be 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -889,7 +889,7 @@ bool GIMatchTableExecutor::executeMatchTable(
case GIM_CheckIntrinsicID: {
uint64_t InsnID = readULEB();
uint64_t OpIdx = readULEB();
- uint16_t Value = readU16();
+ uint32_t Value = readU32();
DEBUG_WITH_TYPE(TgtExecutor::getName(),
dbgs() << CurrentIdx << ": GIM_CheckIntrinsicID(MIs["
<< InsnID << "]->getOperand(" << OpIdx
@@ -1185,7 +1185,7 @@ bool GIMatchTableExecutor::executeMatchTable(
}
case GIR_AddIntrinsicID: {
uint64_t InsnID = readULEB();
- uint16_t Value = readU16();
+ uint32_t Value = readU32();
assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
OutMIs[InsnID].addIntrinsicID((Intrinsic::ID)Value);
DEBUG_WITH_TYPE(TgtExecutor::getName(),
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index e893295e3272b9..e04711c45de803 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -47,8 +47,17 @@ namespace Intrinsic {
#define GET_INTRINSIC_ENUM_VALUES
#include "llvm/IR/IntrinsicEnums.inc"
#undef GET_INTRINSIC_ENUM_VALUES
+ end_id = ~0U,
};
+ // Returns if `id` is a valid intrinsic ID. Validity means that it value is
+ // one of the values defined for the Intrinsic::ID enum.
+ bool IsIntrinsicIDValid(ID id);
+
+ // Get the next valid ID. This is used in test cases that iterate over valid
+ // intrinsic ID enums.
+ ID GetNextValidIntrinsicID(ID id);
+
/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
/// Note, this version is for intrinsics with no overloads. Use the other
/// version of getName if overloads are required.
diff --git a/llvm/include/llvm/Support/IntrinsicID.h b/llvm/include/llvm/Support/IntrinsicID.h
new file mode 100644
index 00000000000000..60b13d85ec9070
--- /dev/null
+++ b/llvm/include/llvm/Support/IntrinsicID.h
@@ -0,0 +1,59 @@
+//===- llvm/Support/IntrinsicID.h - Intrinsic ID encoding -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions to support intrinsic ID encoding. The
+// Intrinsic::ID enum value is constructed using a target prefix index in bits
+// 23-16 (8-bit) and an intrinsic index (index within the list of intrinsics for
+// tha target) in lower 16 bits. To support Intrinsic::ID 0 being not used, the
+// intrinsic index is encoded as Index + 1 for all targets.
+//
+// This file defines functions that encapsulate this encoding.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INTRINSIC_ID_H
+#define LLVM_SUPPORT_INTRINSIC_ID_H
+
+#include "llvm/Support/FormatVariadic.h"
+#include <limits>
+#include <optional>
+#include <utility>
+
+namespace llvm::Intrinsic {
+typedef unsigned ID;
+
+inline ID EncodeIntrinsicID(unsigned TargetIndex, unsigned IntrinsicIndex) {
+ assert(IntrinsicIndex < std::numeric_limits<uint16_t>::max());
+ assert(TargetIndex <= std::numeric_limits<uint8_t>::max());
+ return (TargetIndex << 16) | (IntrinsicIndex + 1);
+}
+
+inline std::pair<unsigned, unsigned> DecodeIntrinsicID(ID id) {
+ unsigned IntrinsicIndex = id & 0xFFFF;
+ unsigned TargetIndex = id >> 16;
+ assert(IntrinsicIndex != 0);
+ return {TargetIndex, IntrinsicIndex - 1};
+}
+
+inline std::optional<std::pair<unsigned, unsigned>>
+DecodeIntrinsicIDNoFail(ID id) {
+ unsigned IntrinsicIndex = id & 0xFFFF;
+ unsigned TargetIndex = id >> 16;
+ if (IntrinsicIndex == 0)
+ return std::nullopt;
+ return std::make_pair(TargetIndex, IntrinsicIndex - 1);
+}
+
+inline void PrintIntrinsicIDEncoding(raw_ostream &OS, unsigned TargetIndex,
+ unsigned IntrinsicIndex) {
+ OS << formatv(" = ({} << 16) + {} + 1", TargetIndex, IntrinsicIndex);
+}
+
+} // end namespace llvm::Intrinsic
+
+#endif // LLVM_SUPPORT_INTRINSIC_ID_H
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index c0e004555de959..8261ac9401d6ae 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -992,7 +992,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
}
case MachineOperand::MO_IntrinsicID: {
Intrinsic::ID ID = getIntrinsicID();
- if (ID < Intrinsic::num_intrinsics)
+ if (Intrinsic::IsIntrinsicIDValid(ID))
OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
else if (IntrinsicInfo)
OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index e2c09fe25d55cd..77440e5e7275f7 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1055,7 +1055,7 @@ bool MachineVerifier::verifyGIntrinsicSideEffects(const MachineInstr *MI) {
bool NoSideEffects = Opcode == TargetOpcode::G_INTRINSIC ||
Opcode == TargetOpcode::G_INTRINSIC_CONVERGENT;
unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
- if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
+ if (IntrID != 0 && Intrinsic::IsIntrinsicIDValid(IntrID)) {
AttributeList Attrs = Intrinsic::getAttributes(
MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
bool DeclHasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
@@ -1079,7 +1079,7 @@ bool MachineVerifier::verifyGIntrinsicConvergence(const MachineInstr *MI) {
bool NotConvergent = Opcode == TargetOpcode::G_INTRINSIC ||
Opcode == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS;
unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
- if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
+ if (IntrID != 0 && Intrinsic::IsIntrinsicIDValid(IntrID)) {
AttributeList Attrs = Intrinsic::getAttributes(
MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
bool DeclIsConvergent = Attrs.hasFnAttr(Attribute::Convergent);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 703efb70089742..d9e3324c6a4981 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -160,7 +160,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::INTRINSIC_W_CHAIN: {
unsigned OpNo = getOpcode() == ISD::INTRINSIC_WO_CHAIN ? 0 : 1;
unsigned IID = getOperand(OpNo)->getAsZExtVal();
- if (IID < Intrinsic::num_intrinsics)
+ if (Intrinsic::IsIntrinsicIDValid(IID))
return Intrinsic::getBaseName((Intrinsic::ID)IID).str();
if (!G)
return "Unknown intrinsic";
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 981ab18b59c1c1..391f6facdc901e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -4431,7 +4431,7 @@ void SelectionDAGISel::CannotYetSelect(SDNode *N) {
} else {
bool HasInputChain = N->getOperand(0).getValueType() == MVT::Other;
unsigned iid = N->getConstantOperandVal(HasInputChain);
- if (iid < Intrinsic::num_intrinsics)
+ if (Intrinsic::IsIntrinsicIDValid(iid))
Msg << "intrinsic %" << Intrinsic::getBaseName((Intrinsic::ID)iid);
else if (const TargetIntrinsicInfo *TII = TM.getIntrinsicInfo())
Msg << "target intrinsic %" << TII->getName(iid);
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index 1cf998c6850068..32f31e9900880d 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2458,7 +2458,8 @@ unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {
}
static Intrinsic::ID llvm_map_to_intrinsic_id(unsigned ID) {
- assert(ID < llvm::Intrinsic::num_intrinsics && "Intrinsic ID out of range");
+ assert(llvm::Intrinsic::IsIntrinsicIDValid(ID) &&
+ "Intrinsic ID out of range");
return llvm::Intrinsic::ID(ID);
}
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 1b92daf15b463e..729d553c15a579 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -33,8 +33,54 @@
#include "llvm/IR/IntrinsicsXCore.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
+#include "llvm/Support/IntrinsicID.h"
using namespace llvm;
+using namespace Intrinsic;
+
+/// Table of per-target intrinsic name tables.
+#define GET_INTRINSIC_TARGET_DATA
+#include "llvm/IR/IntrinsicImpl.inc"
+#undef GET_INTRINSIC_TARGET_DATA
+size_t constexpr NumTargets = sizeof(TargetInfos) / sizeof(TargetInfos[0]);
+
+// Returns true if the given intrinsic ID is valid, that is, its value is one
+// of the enum values defined for this intrinsic (including not_intrinsic).
+bool Intrinsic::IsIntrinsicIDValid(ID ID) {
+ if (ID == Intrinsic::not_intrinsic)
+ return true;
+ auto Decoded = DecodeIntrinsicIDNoFail(ID);
+ if (!Decoded)
+ return false;
+ unsigned TargetIdx = Decoded->first;
+ unsigned IntrinsicIdx = Decoded->second;
+ return TargetIdx < NumTargets && IntrinsicIdx < TargetInfos[TargetIdx].Count;
+}
+
+// Returns linear index of ID if its valid, else returns 0.
+inline unsigned getLinearIndex(Intrinsic::ID ID) {
+ auto Decoded = DecodeIntrinsicIDNoFail(ID);
+ if (!Decoded)
+ return 0;
+ unsigned TargetIdx = Decoded->first;
+ unsigned IntrinsicIdx = Decoded->second;
+ return TargetInfos[TargetIdx].FirstLinearIndex + IntrinsicIdx;
+}
+
+ID Intrinsic::GetNextValidIntrinsicID(Intrinsic::ID ID) {
+ if (ID == Intrinsic::not_intrinsic)
+ return EncodeIntrinsicID(0, 0);
+ if (ID == Intrinsic::last_valid_intrinsic_id)
+ return Intrinsic::end_id;
+ if (ID == Intrinsic::end_id)
+ llvm_unreachable("Cannot find the next valid intrisnic");
+ auto [TargetIndex, IntrinsicIndex] = DecodeIntrinsicID(ID);
+ if (IntrinsicIndex + 1 < TargetInfos[TargetIndex].Count)
+ return EncodeIntrinsicID(TargetIndex, IntrinsicIndex + 1);
+ if (TargetIndex + 1 < NumTargets)
+ return EncodeIntrinsicID(TargetIndex + 1, 0);
+ llvm_unreachable("Cannot find the next valid intrisnic");
+}
/// Table of string intrinsic names indexed by enum value.
static constexpr const char *const IntrinsicNameTable[] = {
@@ -45,12 +91,12 @@ static constexpr const char *const IntrinsicNameTable[] = {
};
StringRef Intrinsic::getBaseName(ID id) {
- assert(id < num_intrinsics && "Invalid intrinsic ID!");
- return IntrinsicNameTable[id];
+ assert(IsIntrinsicIDValid(id) && "Invalid intrinsic ID!");
+ return ArrayRef(IntrinsicNameTable)[getLinearIndex(id)];
}
StringRef Intrinsic::getName(ID id) {
- assert(id < num_intrinsics && "Invalid intrinsic ID!");
+ assert(IsIntrinsicIDValid(id) && "Invalid intrinsic ID!");
assert(!Intrinsic::isOverloaded(id) &&
"This version of getName does not support overloading");
return getBaseName(id);
@@ -157,8 +203,7 @@ static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType) {
static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef<Type *> Tys,
Module *M, FunctionType *FT,
bool EarlyModuleCheck) {
-
- assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
+ assert(IsIntrinsicIDValid(Id) && "Invalid intrinsic ID!");
assert((Tys.empty() || Intrinsic::isOverloaded(Id)) &&
"This version of getName is for overloaded intrinsics only");
(void)EarlyModuleCheck;
@@ -450,11 +495,15 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
#undef GET_INTRINSIC_GENERATOR_GLOBAL
void Intrinsic::getIntrinsicInfoTableEntries(
- ID id, SmallVectorImpl<IITDescriptor> &T) {
+ ID IntrinsicID, SmallVectorImpl<IITDescriptor> &T) {
static_assert(sizeof(IIT_Table[0]) == 2,
"Expect 16-bit entries in IIT_Table");
+ assert(IsIntrinsicIDValid(IntrinsicID));
+ unsigned Idx = getLinearIndex(IntrinsicID);
+ if (Idx == 0)
+ return;
// Check to see if the intrinsic's type was expressible by the table.
- uint16_t TableVal = IIT_Table[id - 1];
+ uint16_t TableVal = IIT_Table[Idx - 1];
// Decode the TableVal into an array of IITValues.
SmallVector<unsigned char> IITValues;
@@ -609,19 +658,20 @@ FunctionType *Intrinsic::getType(LLVMContext &Context, ID id,
return FunctionType::get(ResultTy, ArgTys, false);
}
-bool Intrinsic::isOverloaded(ID id) {
+// Check if an intrinsic is overloaded or not using its linear index.
+static bool isOverloadedUsingLinearIndex(unsigned Idx) {
#define GET_INTRINSIC_OVERLOAD_TABLE
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_OVERLOAD_TABLE
}
-/// Table of per-target intrinsic name tables.
-#define GET_INTRINSIC_TARGET_DATA
-#include "llvm/IR/IntrinsicImpl.inc"
-#undef GET_INTRINSIC_TARGET_DATA
+bool Intrinsic::isOverloaded(ID id) {
+ assert(IsIntrinsicIDValid(id));
+ return isOverloadedUsingLinearIndex(getLinearIndex(id));
+}
bool Intrinsic::isTargetIntrinsic(Intrinsic::ID IID) {
- return IID > TargetInfos[0].Count;
+ return IID != Intrinsic::not_intrinsic && DecodeIntrinsicID(IID).first != 0;
}
int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
@@ -683,7 +733,29 @@ findTargetSubtable(StringRef Name) {
// We've either found the target or just fall back to the generic set, which
// is always first.
const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
- return {ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count), TI.Name};
+ unsigned LinearIndex = TI.FirstLinearIndex;
+ return {ArrayRef(IntrinsicNameTable + LinearIndex, TI.Count), TI.Name};
+}
+
+static Intrinsic::ID getIntrinsicIDFromIndex(unsigned Idx) {
+ if (Idx == 0)
+ return Intrinsic::not_intrinsic;
+
+ auto It =
+ partition_point(TargetInfos, [Idx](const IntrinsicTargetInfo &Info) {
+ return Info.FirstLinearIndex + Info.Count < Idx;
+ });
+ // Idx, if present, will be in the entry at It or It + 1.
+ if (It == std::end(TargetInfos))
+ return Intrinsic::not_intrinsic;
+ unsigned TargetIndex = std::distance(std::begin(TargetInfos), It);
+ if (It->FirstLinearIndex <= Idx && Idx < It->FirstLinearIndex + It->Count)
+ return EncodeIntrinsicID(TargetIndex, Idx - It->FirstLinearIndex);
+ ++It;
+ ++TargetIndex;
+ if (It->FirstLinearIndex <= Idx && Idx < It->FirstLinearIndex + It->Count)
+ return EncodeIntrinsicID(TargetIndex, Idx - It->FirstLinearIndex);
+ return Intrinsic::not_intrinsic;
}
/// This does the actual lookup of an intrinsic ID which matches the given
@@ -693,19 +765,19 @@ Intrinsic::ID Intrinsic::lookupIntrinsicID(StringRef Name) {
int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name, Target);
if (Idx == -1)
return Intrinsic::not_intrinsic;
-
- // Intrinsic IDs correspond to the location in IntrinsicNameTable, but we have
- // an index into a sub-table.
+ const auto MatchSize = strlen(NameTable[Idx]);
+ // Adjust the index from sub-table index to index into the global table.
int Adjust = NameTable.data() - IntrinsicNameTable;
- Intrinsic::ID ID = static_cast<Intrinsic::ID>(Idx + Adjust);
+ Idx += Adjust;
// If the intrinsic is not overloaded, require an exact match. If it is
// overloaded, require either exact or prefix match.
- const auto MatchSize = strlen(NameTable[Idx]);
assert(Name.size() >= MatchSize && "Expected either exact or prefix match");
bool IsExactMatch = Name.size() == MatchSize;
- return IsExactMatch || Intrinsic::isOverloaded(ID) ? ID
- : Intrinsic::not_intrinsic;
+ Intrinsic::ID r = IsExactMatch || isOverloadedUsingLinearIndex(Idx)
+ ? getIntrinsicIDFromIndex(Idx)
+ : Intrinsic::not_intrinsic;
+ return r;
}
/// This defines the "Intrinsic::getAttributes(ID id)" method.
@@ -1043,8 +1115,9 @@ bool Intrinsic::matchIntrinsicVarArg(
bool Intrinsic::getIntrinsicSignature(Intrinsic::ID ID, FunctionType *FT,
SmallVectorImpl<Type *> &ArgTys) {
- if (!ID)
+ if (ID == Intrinsic::not_intrinsic)
return false;
+ assert(IsIntrinsicIDValid(ID));
SmallVector<Intrinsic::IITDescriptor, 8> Table;
getIntrinsicInfoTableEntries(ID, Table);
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 5a848ada9dd8ee..30aadcce028c23 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -7542,7 +7542,7 @@ static unsigned getIntrinsicID(const SDNode *N) {
return Intrinsic::not_intrinsic;
case ISD::INTRINSIC_WO_CHAIN: {
unsigned IID = N->getConstantOperandVal(0);
- if (IID < Intrinsic::num_intrinsics)
+ if (Intrinsic::IsIntrinsicIDValid(IID))
return IID;
return Intrinsic::not_intrinsic;
}
diff --git a/llvm/lib/Target/X86/X86IntrinsicsInfo.h b/llvm/lib/Target/X86/X86IntrinsicsInfo.h
index 86fd04046d16a0..f5477ec2f81315 100644
--- a/llvm/lib/Target/X86/X86IntrinsicsInfo.h
+++ b/llvm/lib/Target/X86/X86IntrinsicsInfo.h
@@ -79,8 +79,7 @@ enum IntrinsicType : uint16_t {
};
struct IntrinsicData {
-
- uint16_t Id;
+ unsigned Id;
IntrinsicType Type;
uint16_t Opc0;
uint16_t Opc1;
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td
index 365d0c9fbff494..8d96f703f97892 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-intrinsics.td
@@ -36,7 +36,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 3*/ GIMT_Encode4([[L72:[0-9]+]]), // Rule ID 0 //
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
-// CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, GIMT_Encode2(Intrinsic::1in_1out),
+// CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, GIMT_Encode4(Intrinsic::1in_1out),
// CHECK-NEXT: // MIs[0] a
// CHECK-NEXT: // No operand predicates
// CHECK-NEXT: // MIs[0] Operand 2
@@ -45,10 +45,10 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK-NEXT: // Combiner Rule #0: IntrinTest0
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_INTRINSIC),
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),
-// CHECK-NEXT: GIR_AddIntrinsicID, /*MI*/0, GIMT_Encode2(Intrinsic::0in_1out),
+// CHECK-NEXT: GIR_AddIntrinsicID, /*MI*/0, GIMT_Encode4(Intrinsic::0in_1out),
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/113576
More information about the llvm-commits
mailing list