[llvm] [LLVM][Intrinsics] Change overly defensive code in `DecodeIITType` (PR #190260)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 2 13:49:46 PDT 2026
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/190260
>From 7b122db3e2c6d47033112068c36dd0a686518895 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Thu, 2 Apr 2026 13:35:16 -0700
Subject: [PATCH] [LLVM][Intrinsics] Change overly defensive code in
`DecodeIITType`
`DecodeIITType` seems to do a range check each time the next entry
from the IIT encoding table is read. This is overly defensive and
can negatively impact compile time. Assuming a well formed IIT
encoding table, we don't need these checks and in debug builds
if we do run off the end, the ArrayRef indexing (in `Infos`) will
trigger an assert failure.
Additionaly, change some use if 0s (in loop conditions and defaut
constructed terminator in the IIT long encoding table) to explicitly
use IIT_Done to clarify the code better.
---
llvm/lib/IR/Intrinsics.cpp | 40 ++++++++-----------
.../utils/TableGen/Basic/IntrinsicEmitter.cpp | 8 +++-
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 0e01529bda711..920543b71b6bf 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -354,42 +354,39 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
return;
case IIT_ANY: {
- unsigned OverloadInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadInfo = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::Overloaded, OverloadInfo));
return;
}
case IIT_EXTEND_ARG: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::Extend, OverloadIndex));
return;
}
case IIT_TRUNC_ARG: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::Trunc, OverloadIndex));
return;
}
case IIT_ONE_NTH_ELTS_VEC_ARG: {
- unsigned short OverloadIndex =
- (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- unsigned short N = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned short OverloadIndex = Infos[NextElt++];
+ unsigned short N = Infos[NextElt++];
OutputTable.push_back(IITDescriptor::get(IITDescriptor::OneNthEltsVec,
/*Hi=*/N, /*Lo=*/OverloadIndex));
return;
}
case IIT_SAME_VEC_WIDTH_ARG: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::SameVecWidth, OverloadIndex));
return;
}
case IIT_VEC_OF_ANYPTRS_TO_ELT: {
- unsigned short OverloadIndex =
- (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
- unsigned short RefOverloadIndex =
- (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned short OverloadIndex = Infos[NextElt++];
+ unsigned short RefOverloadIndex = Infos[NextElt++];
OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt,
/*Hi=*/RefOverloadIndex,
/*Lo=*/OverloadIndex));
@@ -409,19 +406,19 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
return;
}
case IIT_SUBDIVIDE2_ARG: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::Subdivide2, OverloadIndex));
return;
}
case IIT_SUBDIVIDE4_ARG: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::Subdivide4, OverloadIndex));
return;
}
case IIT_VEC_ELEMENT: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::VecElement, OverloadIndex));
return;
@@ -431,7 +428,7 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
return;
}
case IIT_VEC_OF_BITCASTS_TO_INT: {
- unsigned OverloadIndex = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ unsigned OverloadIndex = Infos[NextElt++];
OutputTable.push_back(
IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, OverloadIndex));
return;
@@ -484,7 +481,7 @@ void Intrinsic::getIntrinsicInfoTableEntries(
// Okay, decode the table into the output vector of IITDescriptors.
DecodeIITType(NextElt, IITEntries, IIT_Done, T);
- while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0)
+ while (NextElt != IITEntries.size() && IITEntries[NextElt] != IIT_Done)
DecodeIITType(NextElt, IITEntries, IIT_Done, T);
}
@@ -493,8 +490,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
LLVMContext &Context) {
using namespace Intrinsic;
- IITDescriptor D = Infos.front();
- Infos = Infos.slice(1);
+ IITDescriptor D = Infos.consume_front();
switch (D.Kind) {
case IITDescriptor::Void:
@@ -862,8 +858,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
return false;
};
- IITDescriptor D = Infos.front();
- Infos = Infos.slice(1);
+ IITDescriptor D = Infos.consume_front();
switch (D.Kind) {
case IITDescriptor::Void:
@@ -997,7 +992,7 @@ matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::SameVecWidth: {
if (D.getOverloadIndex() >= OverloadTys.size()) {
// Defer check and subsequent check for the vector element type.
- Infos = Infos.slice(1);
+ (void)Infos.drop_front();
return IsDeferredCheck || DeferCheck(Ty);
}
auto *ReferenceType =
@@ -1114,8 +1109,7 @@ bool Intrinsic::matchIntrinsicVarArg(
return true;
// Check and verify the descriptor.
- IITDescriptor D = Infos.front();
- Infos = Infos.slice(1);
+ IITDescriptor D = Infos.consume_front();
if (D.Kind == IITDescriptor::VarArg)
return !isVarArg;
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index bda911b50d813..85524981a2a57 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -224,6 +224,8 @@ void IntrinsicEmitter::EmitIITInfo(raw_ostream &OS) {
RecsByNumber[Number] = Rec->getName();
}
if (IIT_Base.size() > 0) {
+ if (RecsByNumber[0] != "IIT_Done")
+ PrintFatalError("IIT_Done expected to have value 0");
for (unsigned I = 0, E = RecsByNumber.size(); I < E; ++I)
if (!RecsByNumber[I].empty())
OS << " " << RecsByNumber[I] << " = " << I << ",\n";
@@ -351,7 +353,11 @@ void IntrinsicEmitter::EmitGenerator(const CodeGenIntrinsicTable &Ints,
// If we can compute a 16/32-bit fixed encoding for this intrinsic, do so and
// capture it in this vector, otherwise store a ~0U.
std::vector<FixedEncodingTy> FixedEncodings;
- SequenceToOffsetTable<TypeSigTy> LongEncodingTable;
+
+ // Each IIT encoding sequence in the long encoding table is terminated by
+ // IIT_Done(=0) token.
+ constexpr unsigned char IIT_Done = 0;
+ SequenceToOffsetTable<TypeSigTy> LongEncodingTable(IIT_Done);
FixedEncodings.reserve(Ints.size());
More information about the llvm-commits
mailing list