Skip to content

Conversation

darkbuck
Copy link
Contributor

@darkbuck darkbuck commented Sep 24, 2025

Currently, Intrinsic can only have up to 9 return values. In case new intrinsics require more than 9 return values, additional ITT_STRUCTxxx values need to be added to support > 9 return values. Instead, this patch unifies them into a single IIT_STRUCT followed by a BYTE specifying the minimal 2 (encoded as 0) and maximal 257 (encoded as 255) return values.

@llvmbot
Copy link
Member

llvmbot commented Sep 24, 2025

@llvm/pr-subscribers-tablegen

Author: None (darkbuck)

Changes
  • Intrinsic could only have up to 9 return values so far. In case new intrinsics may require more than 9 return values, additional ITT_STRUCTxxx may be added following previous efforts supporting more return values.
  • Instead, this patch addes a new type info IIT_STRUCTn followed by a BYTE specifying the total return values (minus 10) so that we could support up to maximally 265 return values without introducing more encodings in that type info byte.

Full diff: https://github.com/llvm/llvm-project/pull/160434.diff

4 Files Affected:

  • (modified) llvm/include/llvm/IR/Intrinsics.td (+4-1)
  • (modified) llvm/lib/IR/Intrinsics.cpp (+3)
  • (modified) llvm/test/TableGen/intrinsic-struct.td (+25-6)
  • (modified) llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp (+1-1)
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 585371a6a4423..541f1bccdfe1a 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -337,6 +337,7 @@ def IIT_V6 : IIT_Vec<6, 60>;
 def IIT_V10 : IIT_Vec<10, 61>;
 def IIT_V2048 : IIT_Vec<2048, 62>;
 def IIT_V4096 : IIT_Vec<4096, 63>;
+def IIT_STRUCTn : IIT_Base<64>;
 }
 
 defvar IIT_all_FixedTypes = !filter(iit, IIT_all,
@@ -663,7 +664,9 @@ class TypeInfoGen<
     !if(!isa<LLVMMatchType>(ty), ACTys[MappingRIdxs[ty.Number]], ty));
 
   list<int> TypeSig = !listflatten(!listconcat(
-    [IIT_RetNumbers[!size(RetTypes)]],
+    [!cond(
+      !lt(!size(RetTypes), !size(IIT_RetNumbers)): IIT_RetNumbers[!size(RetTypes)],
+      true: [IIT_STRUCTn.Number, !sub(!size(RetTypes), !size(IIT_RetNumbers))])],
     !foreach(i, !range(AllTypes),
       !foreach(a, AllTypes[i].Sig,
         ResolveArgCode<
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 4d2e8fadff4f7..7298141f8b695 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -390,6 +390,9 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
   case IIT_EMPTYSTRUCT:
     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
     return;
+  case IIT_STRUCTn:
+    StructElts += Infos[NextElt++] + 1;
+    [[fallthrough]];
   case IIT_STRUCT9:
     ++StructElts;
     [[fallthrough]];
diff --git a/llvm/test/TableGen/intrinsic-struct.td b/llvm/test/TableGen/intrinsic-struct.td
index 467fd9057c183..c5ee2c3087ca2 100644
--- a/llvm/test/TableGen/intrinsic-struct.td
+++ b/llvm/test/TableGen/intrinsic-struct.td
@@ -1,22 +1,41 @@
 // 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: llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS | FileCheck %s --check-prefix=CHECK-IMPL
 // 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 9 values.
-// CHECK-ENUM: returns_9_results = {{[0-9]+}}, // llvm.returns.9.results
+// Make sure we can return up to 265 values. Intrinsics are in alphabetical order.
+// CHECK-ENUM: returns_10_results = {{[0-9]+}}, // llvm.returns.10.results
+// CHECK-ENUM: returns_265_results, // llvm.returns.265.results
+// CHECK-ENUM: returns_9_results, // llvm.returns.9.results
+
+// Make sure the encoding table is correctly generated. Intrinsics are in reverse alphabetical order.
+// CHECK-IMPL: IIT_LongEncodingTable
+// CHECK-IMPL-NEXT: 49,
+// CHECK-IMPL-SAME: 15, 1, 15, 9, 15, 17, 15, 25, 15, 33, 15, 41, 15, 49, 15, 57, 15, 65, 0
+// CHECK-IMPL-NEXT: 64, 255
+// CHECK-IMPL-SAME: 15, 1, 15, 9, 15, 17, 15, 25, 15, 33, 15, 41, 15, 49, 15, 57, 15, 65, 15, 73, 15, 81,
+// CHECK-IMPL-NEXT: 64, 0
+// CHECK-IMPL-SAME: 15, 1, 15, 9, 15, 17, 15, 25, 15, 33, 15, 41, 15, 49, 15, 57, 15, 65, 15, 73, 0
 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">;
 
+def int_returns_265_results : Intrinsic<
+                              !listsplat(llvm_anyint_ty, 265),
+                              [], [], "llvm.returns.265.results">;
+
+#ifdef ENABLE_ERROR
+// CHECK-ERROR: error: intrinsics can only return upto 265 values, 'int_returns_266_results' returns 266 values
+// CHECK-ERROR-NEXT: def int_returns_266_results : Intrinsic<
+def int_returns_266_results : Intrinsic<
+                              !listsplat(llvm_anyint_ty, 266),
+                              [], [], "llvm.returns.10.results">;
+
 #endif
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index bc42efa3b2e9c..0a64a5cbfb154 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -37,7 +37,7 @@ CodeGenIntrinsicContext::CodeGenIntrinsicContext(const RecordKeeper &RC) {
       dyn_cast_or_null<ListInit>(RC.getGlobal("IIT_RetNumbers"));
   if (!IIT_RetNumbers)
     PrintFatalError("unable to find 'IIT_RetNumbers' list");
-  MaxNumReturn = IIT_RetNumbers->size() - 1;
+  MaxNumReturn = IIT_RetNumbers->size() - 1 + /*IIT_STRUCTn*/ 256;
 }
 
 CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {

@llvmbot
Copy link
Member

llvmbot commented Sep 24, 2025

@llvm/pr-subscribers-llvm-ir

Author: None (darkbuck)

Changes
  • Intrinsic could only have up to 9 return values so far. In case new intrinsics may require more than 9 return values, additional ITT_STRUCTxxx may be added following previous efforts supporting more return values.
  • Instead, this patch addes a new type info IIT_STRUCTn followed by a BYTE specifying the total return values (minus 10) so that we could support up to maximally 265 return values without introducing more encodings in that type info byte.

Full diff: https://github.com/llvm/llvm-project/pull/160434.diff

4 Files Affected:

  • (modified) llvm/include/llvm/IR/Intrinsics.td (+4-1)
  • (modified) llvm/lib/IR/Intrinsics.cpp (+3)
  • (modified) llvm/test/TableGen/intrinsic-struct.td (+25-6)
  • (modified) llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp (+1-1)
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 585371a6a4423..541f1bccdfe1a 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -337,6 +337,7 @@ def IIT_V6 : IIT_Vec<6, 60>;
 def IIT_V10 : IIT_Vec<10, 61>;
 def IIT_V2048 : IIT_Vec<2048, 62>;
 def IIT_V4096 : IIT_Vec<4096, 63>;
+def IIT_STRUCTn : IIT_Base<64>;
 }
 
 defvar IIT_all_FixedTypes = !filter(iit, IIT_all,
@@ -663,7 +664,9 @@ class TypeInfoGen<
     !if(!isa<LLVMMatchType>(ty), ACTys[MappingRIdxs[ty.Number]], ty));
 
   list<int> TypeSig = !listflatten(!listconcat(
-    [IIT_RetNumbers[!size(RetTypes)]],
+    [!cond(
+      !lt(!size(RetTypes), !size(IIT_RetNumbers)): IIT_RetNumbers[!size(RetTypes)],
+      true: [IIT_STRUCTn.Number, !sub(!size(RetTypes), !size(IIT_RetNumbers))])],
     !foreach(i, !range(AllTypes),
       !foreach(a, AllTypes[i].Sig,
         ResolveArgCode<
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 4d2e8fadff4f7..7298141f8b695 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -390,6 +390,9 @@ DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
   case IIT_EMPTYSTRUCT:
     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
     return;
+  case IIT_STRUCTn:
+    StructElts += Infos[NextElt++] + 1;
+    [[fallthrough]];
   case IIT_STRUCT9:
     ++StructElts;
     [[fallthrough]];
diff --git a/llvm/test/TableGen/intrinsic-struct.td b/llvm/test/TableGen/intrinsic-struct.td
index 467fd9057c183..c5ee2c3087ca2 100644
--- a/llvm/test/TableGen/intrinsic-struct.td
+++ b/llvm/test/TableGen/intrinsic-struct.td
@@ -1,22 +1,41 @@
 // 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: llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS | FileCheck %s --check-prefix=CHECK-IMPL
 // 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 9 values.
-// CHECK-ENUM: returns_9_results = {{[0-9]+}}, // llvm.returns.9.results
+// Make sure we can return up to 265 values. Intrinsics are in alphabetical order.
+// CHECK-ENUM: returns_10_results = {{[0-9]+}}, // llvm.returns.10.results
+// CHECK-ENUM: returns_265_results, // llvm.returns.265.results
+// CHECK-ENUM: returns_9_results, // llvm.returns.9.results
+
+// Make sure the encoding table is correctly generated. Intrinsics are in reverse alphabetical order.
+// CHECK-IMPL: IIT_LongEncodingTable
+// CHECK-IMPL-NEXT: 49,
+// CHECK-IMPL-SAME: 15, 1, 15, 9, 15, 17, 15, 25, 15, 33, 15, 41, 15, 49, 15, 57, 15, 65, 0
+// CHECK-IMPL-NEXT: 64, 255
+// CHECK-IMPL-SAME: 15, 1, 15, 9, 15, 17, 15, 25, 15, 33, 15, 41, 15, 49, 15, 57, 15, 65, 15, 73, 15, 81,
+// CHECK-IMPL-NEXT: 64, 0
+// CHECK-IMPL-SAME: 15, 1, 15, 9, 15, 17, 15, 25, 15, 33, 15, 41, 15, 49, 15, 57, 15, 65, 15, 73, 0
 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">;
 
+def int_returns_265_results : Intrinsic<
+                              !listsplat(llvm_anyint_ty, 265),
+                              [], [], "llvm.returns.265.results">;
+
+#ifdef ENABLE_ERROR
+// CHECK-ERROR: error: intrinsics can only return upto 265 values, 'int_returns_266_results' returns 266 values
+// CHECK-ERROR-NEXT: def int_returns_266_results : Intrinsic<
+def int_returns_266_results : Intrinsic<
+                              !listsplat(llvm_anyint_ty, 266),
+                              [], [], "llvm.returns.10.results">;
+
 #endif
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index bc42efa3b2e9c..0a64a5cbfb154 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -37,7 +37,7 @@ CodeGenIntrinsicContext::CodeGenIntrinsicContext(const RecordKeeper &RC) {
       dyn_cast_or_null<ListInit>(RC.getGlobal("IIT_RetNumbers"));
   if (!IIT_RetNumbers)
     PrintFatalError("unable to find 'IIT_RetNumbers' list");
-  MaxNumReturn = IIT_RetNumbers->size() - 1;
+  MaxNumReturn = IIT_RetNumbers->size() - 1 + /*IIT_STRUCTn*/ 256;
 }
 
 CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {

@darkbuck darkbuck force-pushed the hliao/main/intrin-ret-num branch from e87db1d to 1829b70 Compare September 24, 2025 03:21
@wecing wecing removed their request for review September 24, 2025 11:59
@darkbuck darkbuck requested a review from nikic September 24, 2025 13:56
@darkbuck darkbuck force-pushed the hliao/main/intrin-ret-num branch from 1829b70 to 14b913b Compare September 25, 2025 11:45
@darkbuck
Copy link
Contributor Author

@chapuni, @nikic, and @jurahul PING for review or suggestion

@jurahul
Copy link
Contributor

jurahul commented Sep 25, 2025

Thanks for the PR. It's best to give reviewers at least week before a reminder. That being said, I do plan to look at this in the next few days and will give feedback then.

@darkbuck darkbuck force-pushed the hliao/main/intrin-ret-num branch from f012257 to 0941bc6 Compare September 26, 2025 04:02
@darkbuck darkbuck changed the title [Intrinsic] Add IIT_STRUCTn to support more than 9 return values [Intrinsic] Unify IIT_STRUCT{2-9} into ITT_STRUCT to support upto 257 return value Sep 26, 2025
@jurahul jurahul self-requested a review September 26, 2025 13:53
@darkbuck darkbuck force-pushed the hliao/main/intrin-ret-num branch from 0941bc6 to 79c11ee Compare September 26, 2025 15:29
@jurahul
Copy link
Contributor

jurahul commented Sep 26, 2025

Suggested PR description:

Currently, Intrinsic can only have up to 9 return values. In case new intrinsics require more than 9 return values, additional
ITT_STRUCTxxx values need to be added to support > 9 return values. Instead, this patch unifies them into a single IIT_STRUCT followed by a BYTE specifying the minimal 2 (encoded as 0) and maximal 257 (encoded as 255) return values.

@darkbuck darkbuck force-pushed the hliao/main/intrin-ret-num branch from 79c11ee to 596ecd4 Compare September 26, 2025 16:55
… return values

- Currently, Intrinsic can only have up to 9 return values. In case new
  intrinsics require more than 9 return values, additional ITT_STRUCTxxx
  values need to be added to support > 9 return values.  Instead, this
  patch unifies them into a single IIT_STRUCT followed by a BYTE
  specifying the minimal 2 (encoded as 0) and maximal 257 (encoded as
  255) return values.
@darkbuck darkbuck force-pushed the hliao/main/intrin-ret-num branch from 596ecd4 to cbfa8a1 Compare September 26, 2025 17:00
Copy link
Contributor

@jurahul jurahul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for iterating through the feedback.

@darkbuck
Copy link
Contributor Author

committed in 9d7628d

@darkbuck darkbuck closed this Sep 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants