[llvm] 50be455 - [TableGen] Add check for number of intrinsic return values (#107326)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 5 14:52:33 PDT 2024


Author: Rahul Joshi
Date: 2024-09-05T14:52:30-07:00
New Revision: 50be455ab88b17872cd620698156b4058dc92f58

URL: https://github.com/llvm/llvm-project/commit/50be455ab88b17872cd620698156b4058dc92f58
DIFF: https://github.com/llvm/llvm-project/commit/50be455ab88b17872cd620698156b4058dc92f58.diff

LOG: [TableGen] Add check for number of intrinsic return values (#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 if it's exceeded with a proper error message.

Added: 
    

Modified: 
    llvm/test/TableGen/intrinsic-struct.td
    llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
    llvm/utils/TableGen/Basic/CodeGenIntrinsics.h

Removed: 
    


################################################################################
diff  --git a/llvm/test/TableGen/intrinsic-struct.td b/llvm/test/TableGen/intrinsic-struct.td
index f23a7a7643af27..467fd9057c1833 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..23c64912c780f3 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