[llvm] [TableGen] Add error checks for number of intrinsic return values (PR #107326)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 4 16:07:14 PDT 2024
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/107326
Fail if we see an intrinsic that returns more than the supported number of return values.
Intrinsics can return only upto a certain nyumber of values, as defined by the `IIT_RetNumbers` list in Intrinsics.td. Currently, if we define an intrinsic that exceeds the limit, llvm-tblgen crashes. Instead, read this limit and fail its exceeded with a proper error message.
>From 6e0a65ef0830ef35a58e13ec7b43ddac8e410df0 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Tue, 3 Sep 2024 05:29:44 -0700
Subject: [PATCH] [TableGen] Add error checks for number of intrinsic return
values
Fail if we see an intrinsic that returns more than the supported
number of return values.
Intrinsics can return only upto a certain nyumber of values, as
defined by the `IIT_RetNumbers` list in Intrinsics.td. Currently,
if we define an intrinsic that exceeds the limit, llvm-tblgen
crashes. Instead, read this limit and fail its exceeded with a
proper error message.
---
llvm/test/TableGen/intrinsic-struct.td | 25 +++++++++++++------
.../TableGen/Basic/CodeGenIntrinsics.cpp | 17 ++++++++++++-
llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 3 +++
3 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/llvm/test/TableGen/intrinsic-struct.td b/llvm/test/TableGen/intrinsic-struct.td
index f23a7a7643af27..767746fa064c73 100644
--- a/llvm/test/TableGen/intrinsic-struct.td
+++ b/llvm/test/TableGen/intrinsic-struct.td
@@ -1,11 +1,22 @@
-// RUN: llvm-tblgen -gen-intrinsic-enums -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS | FileCheck %s
+// RUN: llvm-tblgen -gen-intrinsic-enums -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS | FileCheck %s --check-prefix=CHECK-ENUM
+// RUN: llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS > /dev/null 2>&1
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS -DENABLE_ERROR 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+
// XFAIL: vg_leak
include "llvm/IR/Intrinsics.td"
-// Make sure we can return up to 8 values
-// CHECK: returns_8_results = {{[0-9]+}}, // llvm.returns.8.results
-def int_returns_8_results : Intrinsic<
- [llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty,
- llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty, llvm_anyint_ty],
- [], [], "llvm.returns.8.results">;
+// Make sure we can return up to 9 values.
+// CHECK-ENUM: returns_9_results = {{[0-9]+}}, // llvm.returns.9.results
+def int_returns_9_results : Intrinsic<
+ !listsplat(llvm_anyint_ty, 9),
+ [], [], "llvm.returns.9.results">;
+
+#ifdef ENABLE_ERROR
+// CHECK-ERROR: error: Intrinsics can only return upto 9 values, 'int_returns_10_results' returns 10 values
+// CHECK-ERROR-NEXT: def int_returns_10_results : Intrinsic<
+def int_returns_10_results : Intrinsic<
+ !listsplat(llvm_anyint_ty, 10),
+ [], [], "llvm.returns.10.results">;
+
+#endif
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index a30a7577408f86..68a2fd1d3c3c66 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -29,6 +29,15 @@ CodeGenIntrinsicContext::CodeGenIntrinsicContext(const RecordKeeper &RC) {
for (const Record *Rec : RC.getAllDerivedDefinitions("IntrinsicProperty"))
if (Rec->getValueAsBit("IsDefault"))
DefaultProperties.push_back(Rec);
+
+ // The maximum number of values that an intrinsic can return is the size of
+ // of `IIT_RetNumbers` list - 1 (since we index into this list using the
+ // number of return values as the index).
+ const auto *IIT_RetNumbers =
+ dyn_cast_or_null<ListInit>(RC.getGlobal("IIT_RetNumbers"));
+ if (!IIT_RetNumbers)
+ PrintFatalError("Unable to find 'IIT_RetNumbers' list");
+ MaxNumReturn = IIT_RetNumbers->size() - 1;
}
CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
@@ -106,6 +115,13 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
TargetPrefix + ".'!");
}
+ unsigned NumRet = R->getValueAsListInit("RetTypes")->size();
+ if (NumRet > Ctx.MaxNumReturn)
+ PrintFatalError(DefLoc, "Intrinsics can only return upto " +
+ Twine(Ctx.MaxNumReturn) + " values, '" +
+ DefName + "' returns " + Twine(NumRet) +
+ " values");
+
const Record *TypeInfo = R->getValueAsDef("TypeInfo");
if (!TypeInfo->isSubClassOf("TypeInfoGen"))
PrintFatalError(DefLoc, "TypeInfo field in " + DefName +
@@ -116,7 +132,6 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
// Types field is a concatenation of Return types followed by Param types.
unsigned Idx = 0;
- unsigned NumRet = R->getValueAsListInit("RetTypes")->size();
for (; Idx < NumRet; ++Idx)
IS.RetTys.push_back(TypeList->getElementAsRecord(Idx));
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index 51c23591553802..83282d18789b28 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -30,6 +30,9 @@ class RecordKeeper;
struct CodeGenIntrinsicContext {
explicit CodeGenIntrinsicContext(const RecordKeeper &RC);
std::vector<const Record *> DefaultProperties;
+
+ // Maximum number of values an intrinsic can return.
+ unsigned MaxNumReturn;
};
struct CodeGenIntrinsic {
More information about the llvm-commits
mailing list