[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