[llvm] 94201c3 - [LLVM][Intrinsics] Add validation for vararg intrinsics (#193777)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 09:10:00 PDT 2026


Author: Rahul Joshi
Date: 2026-04-30T09:09:56-07:00
New Revision: 94201c35f371f43b45eadafdaa3698d1688a985e

URL: https://github.com/llvm/llvm-project/commit/94201c35f371f43b45eadafdaa3698d1688a985e
DIFF: https://github.com/llvm/llvm-project/commit/94201c35f371f43b45eadafdaa3698d1688a985e.diff

LOG: [LLVM][Intrinsics] Add validation for vararg intrinsics (#193777)

Add validation for use of `llvm_vararg_ty` in intrinsic type signature.

Added: 
    llvm/test/TableGen/intrinsic-varargs-validation.td

Modified: 
    llvm/include/llvm/IR/Intrinsics.h
    llvm/test/TableGen/intrinsic-varargs.td
    llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 954c704169e53..1efddd09b08fd 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -227,7 +227,7 @@ namespace Intrinsic {
     }
 
     // OneNthEltsVecArguments uses both a divisor N and a reference argument for
-    // the full-width vector to match
+    // the full-width vector to match.
     unsigned getVectorDivisor() const {
       assert(Kind == OneNthEltsVec);
       return OverloadInfo >> 16;
@@ -285,7 +285,7 @@ namespace Intrinsic {
   LLVM_ABI bool matchIntrinsicVarArg(bool isVarArg,
                                      ArrayRef<IITDescriptor> &Infos);
 
-  /// Gets the type arguments of an intrinsic call by matching type contraints
+  /// Gets the overload types of an intrinsic call by matching type contraints
   /// specified by the .td file. The overloaded types are pushed into the
   /// OverloadTys vector.
   ///

diff  --git a/llvm/test/TableGen/intrinsic-varargs-validation.td b/llvm/test/TableGen/intrinsic-varargs-validation.td
new file mode 100644
index 0000000000000..70231747e85e3
--- /dev/null
+++ b/llvm/test/TableGen/intrinsic-varargs-validation.td
@@ -0,0 +1,35 @@
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST0 2>&1 | FileCheck %s --check-prefix=CHECK-TEST0
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST1 2>&1 | FileCheck %s --check-prefix=CHECK-TEST1
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST2 2>&1 | FileCheck %s --check-prefix=CHECK-TEST2
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST3 2>&1 | FileCheck %s --check-prefix=CHECK-TEST3
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST4 2>&1 | FileCheck %s --check-prefix=CHECK-TEST4
+
+// This unit test tests whether invalid use of `llvm_vararg_ty` are flagged.
+
+#define TEST_INTRINSICS_SUPPRESS_DEFS
+include "llvm/IR/Intrinsics.td"
+
+#ifdef TEST0
+// CHECK-TEST0: error: cannot use llvm_vararg_ty as a return type
+def int_test: Intrinsic<[llvm_vararg_ty], []>;
+#endif // TEST0
+
+#ifdef TEST1
+// CHECK-TEST1: error: cannot use llvm_vararg_ty as a return type
+def int_test: Intrinsic<[llvm_i32_ty, llvm_vararg_ty], []>;
+#endif // TEST1
+
+#ifdef TEST2
+// CHECK-TEST2: error: llvm_vararg_ty can only be the last parameter type
+def int_test: Intrinsic<[], [llvm_i32_ty, llvm_vararg_ty, llvm_i1_ty]>;
+#endif // TEST2
+
+#ifdef TEST3
+// CHECK-TEST3: error: llvm_vararg_ty can only be the last parameter type
+def int_test: Intrinsic<[], [llvm_i32_ty, llvm_vararg_ty, llvm_vararg_ty]>;
+#endif // TEST3
+
+#ifdef TEST4
+// CHECK-TEST4: error: llvm_vararg_ty can only be the last parameter type
+def int_test: Intrinsic<[], [llvm_vararg_ty, llvm_i32_ty, llvm_vararg_ty]>;
+#endif // TEST4

diff  --git a/llvm/test/TableGen/intrinsic-varargs.td b/llvm/test/TableGen/intrinsic-varargs.td
index f94e1d0d6750e..498647cc54ed1 100644
--- a/llvm/test/TableGen/intrinsic-varargs.td
+++ b/llvm/test/TableGen/intrinsic-varargs.td
@@ -3,5 +3,6 @@
 
 include "llvm/IR/Intrinsics.td"
 
+// CHECK-LABEL: IIT_LongEncodingTable
 // CHECK: /* 0 */ 0, 26, 0,
 def int_foo : Intrinsic<[], [llvm_vararg_ty]>;

diff  --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 6239082d35bed..af70f216d538a 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -322,11 +322,20 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
 
   // Types field is a concatenation of Return types followed by Param types.
   unsigned Idx = 0;
-  for (; Idx < NumRet; ++Idx)
-    IS.RetTys.push_back(TypeList->getElementAsRecord(Idx));
+  for (; Idx < NumRet; ++Idx) {
+    const Record *RetTy = TypeList->getElementAsRecord(Idx);
+    if (RetTy->getName() == "llvm_vararg_ty")
+      PrintFatalError(DefLoc, "cannot use llvm_vararg_ty as a return type");
+    IS.RetTys.push_back(RetTy);
+  }
 
-  for (unsigned E = TypeList->size(); Idx < E; ++Idx)
-    IS.ParamTys.push_back(TypeList->getElementAsRecord(Idx));
+  for (unsigned E = TypeList->size(); Idx < E; ++Idx) {
+    const Record *ParamTy = TypeList->getElementAsRecord(Idx);
+    if (Idx != E - 1 && ParamTy->getName() == "llvm_vararg_ty")
+      PrintFatalError(DefLoc,
+                      "llvm_vararg_ty can only be the last parameter type");
+    IS.ParamTys.push_back(ParamTy);
+  }
 
   // Parse the intrinsic properties.
   const ListInit *PropList = R->getValueAsListInit("IntrProperties");


        


More information about the llvm-commits mailing list