[llvm] [Offload] Generate `OffloadTypedGetInfo.inc` (PR #168615)

Andrei Elovikov via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 18 22:12:05 PST 2025


https://github.com/aelovikov-intel updated https://github.com/llvm/llvm-project/pull/168615

>From a17c1bb559f2971c9b7c5ac512d9a3c7d13fa510 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at intel.com>
Date: Tue, 18 Nov 2025 12:56:53 -0800
Subject: [PATCH 1/4] [Offload] Generate `OffloadTypedGetInfo.inc`

Various offload APIs `olGet*Info` are essentially untyped because they
"return" value via `void *PropValue` output parameter. However, for C++
consumers (e.g., SYCL in #166927) it would be beneficial if we could recover
that type information. Before this PR it was only encoded in the
comments near corresponding information info descriptors, e.g.,

```c++
///////////////////////////////////////////////////////////////////////////////
/// @brief Supported event info.
typedef enum ol_event_info_t {
  /// [ol_queue_handle_t] The handle of the queue associated with the device.
  OL_EVENT_INFO_QUEUE = 0,
  /// [bool] True if and only if the event is complete.
  OL_EVENT_INFO_IS_COMPLETE = 1,
  /// @cond
  OL_EVENT_INFO_LAST = 2,
  OL_EVENT_INFO_FORCE_UINT32 = 0x7fffffff
  /// @endcond

} ol_event_info_t;
```

and not accessible programmatically.
---
 offload/liboffload/API/CMakeLists.txt         |  1 +
 .../tools/offload-tblgen/get_info_wrappers.td | 57 +++++++++++++
 offload/tools/offload-tblgen/CMakeLists.txt   |  1 +
 offload/tools/offload-tblgen/Generators.hpp   |  2 +
 .../offload-tblgen/TypedGetInfoWrappers.cpp   | 84 +++++++++++++++++++
 .../tools/offload-tblgen/offload-tblgen.cpp   |  8 +-
 6 files changed, 152 insertions(+), 1 deletion(-)
 create mode 100644 offload/test/tools/offload-tblgen/get_info_wrappers.td
 create mode 100644 offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp

diff --git a/offload/liboffload/API/CMakeLists.txt b/offload/liboffload/API/CMakeLists.txt
index e4baa4772a1ef..daa8f382197df 100644
--- a/offload/liboffload/API/CMakeLists.txt
+++ b/offload/liboffload/API/CMakeLists.txt
@@ -19,6 +19,7 @@ offload_tablegen(OffloadEntryPoints.inc -gen-entry-points)
 offload_tablegen(OffloadFuncs.inc -gen-func-names)
 offload_tablegen(OffloadImplFuncDecls.inc -gen-impl-func-decls)
 offload_tablegen(OffloadPrint.hpp -gen-print-header)
+offload_tablegen(OffloadTypedGetInfo.inc -gen-get-info-wrappers)
 
 add_public_tablegen_target(OffloadGenerate)
 
diff --git a/offload/test/tools/offload-tblgen/get_info_wrappers.td b/offload/test/tools/offload-tblgen/get_info_wrappers.td
new file mode 100644
index 0000000000000..4483022c94fbc
--- /dev/null
+++ b/offload/test/tools/offload-tblgen/get_info_wrappers.td
@@ -0,0 +1,57 @@
+// RUN: %offload-tblgen -gen-get-info-wrappers -I %S/../../../liboffload/API %s | %fcheck-generic
+
+include "APIDefs.td"
+
+def ol_foo_handle_t : Handle {
+}
+
+def ol_foo_info_t : Enum {
+  let is_typed = 1;
+  let etors = [
+    TaggedEtor<"INT", "int", "">,
+    TaggedEtor<"STRING", "char[]", "">,
+    TaggedEtor<"ARRAY", "int[]", "">,
+  ];
+}
+
+def olGetFooInfo : Function {
+  let params = [
+    Param<"ol_foo_handle_t", "Foo", "", PARAM_IN>,
+    Param<"ol_foo_info_t", "PropName", "", PARAM_IN>,
+    Param<"size_t", "PropSize", "", PARAM_IN>,
+    TypeTaggedParam<"void*", "PropValue", "array of bytes holding the info.", PARAM_OUT,
+      TypeInfo<"PropName", "PropSize">>
+  ];
+  let returns = [
+    Return<"OL_FOO_INVALID">
+  ];
+}
+
+// CHECK-LABEL: template <ol_foo_info_t Desc> inline auto get_info(ol_foo_handle_t Foo);
+// CHECK-NEXT:  template<> inline auto get_info<OL_FOO_INFO_INT>(ol_foo_handle_t Foo) {
+// CHECK-NEXT:    int Result;
+// CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_INT, 1, &Result))
+// CHECK-NEXT:      return std::variant<int, ol_result_t>{Err};
+// CHECK-NEXT:    else
+// CHECK-NEXT:      return std::variant<int, ol_result_t>{Result};
+// CHECK-NEXT:  }
+// CHECK-NEXT:  template<> inline auto get_info<OL_FOO_INFO_STRING>(ol_foo_handle_t Foo) {
+// CHECK-NEXT:    std::string Result;
+// CHECK-NEXT:    size_t ResultSize = 0;  if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_STRING, &ResultSize))
+// CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
+// CHECK-NEXT:    Result.resize(ResultSize);
+// CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_STRING, ResultSize, Result.data()))
+// CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
+// CHECK-NEXT:    else
+// CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Result};
+// CHECK-NEXT:  }
+// CHECK-NEXT:  template<> inline auto get_info<OL_FOO_INFO_ARRAY>(ol_foo_handle_t Foo) {
+// CHECK-NEXT:    std::vector<int> Result;
+// CHECK-NEXT:    size_t ResultSize = 0;  if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_ARRAY, &ResultSize))
+// CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
+// CHECK-NEXT:    Result.resize(ResultSize);
+// CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_ARRAY, ResultSize, Result.data()))
+// CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
+// CHECK-NEXT:    else
+// CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Result};
+// CHECK-NEXT:  }
diff --git a/offload/tools/offload-tblgen/CMakeLists.txt b/offload/tools/offload-tblgen/CMakeLists.txt
index a5ae1c3757fbf..bc3c4fa5b6ef7 100644
--- a/offload/tools/offload-tblgen/CMakeLists.txt
+++ b/offload/tools/offload-tblgen/CMakeLists.txt
@@ -20,6 +20,7 @@ add_tablegen(offload-tblgen OFFLOAD
   offload-tblgen.cpp
   PrintGen.cpp
   RecordTypes.hpp
+  TypedGetInfoWrappers.cpp
   )
 
 # Make sure that C++ headers are available, if libcxx is built at the same
diff --git a/offload/tools/offload-tblgen/Generators.hpp b/offload/tools/offload-tblgen/Generators.hpp
index fda63f8b198e5..84e14ea0c16e9 100644
--- a/offload/tools/offload-tblgen/Generators.hpp
+++ b/offload/tools/offload-tblgen/Generators.hpp
@@ -25,3 +25,5 @@ void EmitOffloadExports(const llvm::RecordKeeper &Records,
 void EmitOffloadErrcodes(const llvm::RecordKeeper &Records,
                          llvm::raw_ostream &OS);
 void EmitOffloadInfo(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitTypedGetInfoWrappers(const llvm::RecordKeeper &Records,
+                              llvm::raw_ostream &OS);
diff --git a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
new file mode 100644
index 0000000000000..5c1ef15ce3aff
--- /dev/null
+++ b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a Tablegen backend that produces typed C++ inline wrappers for
+// various `olGet*Info interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+#include "GenCommon.hpp"
+#include "RecordTypes.hpp"
+
+using namespace llvm;
+using namespace offload::tblgen;
+
+void EmitTypedGetInfoWrappers(const llvm::RecordKeeper &Records,
+                              llvm::raw_ostream &OS) {
+  OS << GenericHeader;
+  for (auto *R : Records.getAllDerivedDefinitions("Function")) {
+    auto Name = R->getName();
+    if (!Name.starts_with("olGet") || !Name.ends_with("Info"))
+      continue;
+    auto F = FunctionRec{R};
+    auto Params = F.getParams();
+    assert(Params.size() == 4);
+    auto Object = Params[0];
+    auto InfoDesc = Params[1];
+
+    OS << formatv("template <{} Desc> inline auto get_info({} {});\n",
+                  InfoDesc.getType(), Object.getType(), Object.getName());
+
+    EnumRec E{Records.getDef(InfoDesc.getType())};
+    for (auto &V : E.getValues()) {
+      auto Desc = E.getEnumValNamePrefix() + "_" + V.getName();
+      auto TaggedType = V.getTaggedType();
+      auto ResultType = [TaggedType]() -> std::string {
+        if (!TaggedType.ends_with("[]"))
+          return TaggedType.str();
+        if (TaggedType == "char[]")
+          return "std::string";
+
+        return ("std::vector<" + TaggedType.drop_back(2) + ">").str();
+      }();
+      auto ReturnType =
+          "std::variant<" + ResultType + ", " + PrefixLower + "_result_t>";
+      OS << formatv("template<> inline auto get_info<{}>({} {}) {{\n", Desc,
+                    Object.getType(), Object.getName());
+      if (TaggedType.ends_with("[]")) {
+        OS << TAB_1 << formatv("{0} Result;\n", ResultType);
+        OS << TAB_1 << "size_t ResultSize = 0;";
+        OS << TAB_1
+           << formatv("if (auto Err = {}Size({}, {}, &ResultSize))\n",
+                      F.getName(), Object.getName(), Desc);
+        OS << TAB_2 << formatv("return {}{{Err};\n", ReturnType);
+        OS << TAB_1 << "Result.resize(ResultSize);\n"; // TODO: Or "-1"?
+        OS << TAB_1
+           << formatv("if (auto Err = {}({}, {}, ResultSize, Result.data()))\n",
+                      F.getName(), Object.getName(), Desc);
+        OS << TAB_2 << formatv("return {0}{{Err};\n", ReturnType);
+        OS << TAB_1 << "else\n";
+        OS << TAB_2 << formatv("return {0}{{Result};\n", ReturnType);
+      } else {
+        OS << TAB_1 << formatv("{0} Result;\n", TaggedType);
+        OS << TAB_1
+           << formatv("if (auto Err = {}({}, {}, 1, &Result))\n", F.getName(),
+                      Object.getName(), Desc);
+        OS << TAB_2 << formatv("return {0}{{Err};\n", ReturnType);
+        OS << TAB_1 << "else\n";
+        OS << TAB_2 << formatv("return {0}{{Result};\n", ReturnType);
+      }
+      OS << "}\n";
+    }
+    OS << "\n";
+  }
+}
diff --git a/offload/tools/offload-tblgen/offload-tblgen.cpp b/offload/tools/offload-tblgen/offload-tblgen.cpp
index 18aaf9e00f08a..3a0f56acdc460 100644
--- a/offload/tools/offload-tblgen/offload-tblgen.cpp
+++ b/offload/tools/offload-tblgen/offload-tblgen.cpp
@@ -34,6 +34,7 @@ enum ActionType {
   GenExports,
   GenErrcodes,
   GenInfo,
+  GenTypedGetInfoWrappers,
 };
 
 namespace {
@@ -60,7 +61,10 @@ cl::opt<ActionType> Action(
                    "Generate export file for the Offload library"),
         clEnumValN(GenErrcodes, "gen-errcodes",
                    "Generate Offload Error Code enum"),
-        clEnumValN(GenInfo, "gen-info", "Generate Offload Info enum")));
+        clEnumValN(GenInfo, "gen-info", "Generate Offload Info enum"),
+        clEnumValN(GenTypedGetInfoWrappers, "gen-get-info-wrappers",
+                   "Generate typed C++ wrappers around various olGet*Info "
+                   "interfaces")));
 }
 
 static bool OffloadTableGenMain(raw_ostream &OS, const RecordKeeper &Records) {
@@ -98,6 +102,8 @@ static bool OffloadTableGenMain(raw_ostream &OS, const RecordKeeper &Records) {
   case GenInfo:
     EmitOffloadInfo(Records, OS);
     break;
+  case GenTypedGetInfoWrappers:
+    EmitTypedGetInfoWrappers(Records, OS);
   }
 
   return false;

>From 7f805f0e65966727d05d666f92e791ed0e287716 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at intel.com>
Date: Tue, 18 Nov 2025 15:04:14 -0800
Subject: [PATCH 2/4] Adjust `ResultSize` properly

---
 .../tools/offload-tblgen/get_info_wrappers.td     |  3 +++
 .../tools/offload-tblgen/TypedGetInfoWrappers.cpp | 15 ++++++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/offload/test/tools/offload-tblgen/get_info_wrappers.td b/offload/test/tools/offload-tblgen/get_info_wrappers.td
index 4483022c94fbc..9f66b3093cacd 100644
--- a/offload/test/tools/offload-tblgen/get_info_wrappers.td
+++ b/offload/test/tools/offload-tblgen/get_info_wrappers.td
@@ -39,6 +39,7 @@ def olGetFooInfo : Function {
 // CHECK-NEXT:    std::string Result;
 // CHECK-NEXT:    size_t ResultSize = 0;  if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_STRING, &ResultSize))
 // CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
+// CHECK-NEXT:    ResultSize -= 1;
 // CHECK-NEXT:    Result.resize(ResultSize);
 // CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_STRING, ResultSize, Result.data()))
 // CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
@@ -49,6 +50,8 @@ def olGetFooInfo : Function {
 // CHECK-NEXT:    std::vector<int> Result;
 // CHECK-NEXT:    size_t ResultSize = 0;  if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_ARRAY, &ResultSize))
 // CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
+// CHECK-NEXT:    assert(ResultSize % sizeof(int) == 0);
+// CHECK-NEXT:    ResultSize /= sizeof(int);
 // CHECK-NEXT:    Result.resize(ResultSize);
 // CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_ARRAY, ResultSize, Result.data()))
 // CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
diff --git a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
index 5c1ef15ce3aff..19e64ee251316 100644
--- a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
+++ b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
@@ -42,13 +42,14 @@ void EmitTypedGetInfoWrappers(const llvm::RecordKeeper &Records,
     for (auto &V : E.getValues()) {
       auto Desc = E.getEnumValNamePrefix() + "_" + V.getName();
       auto TaggedType = V.getTaggedType();
-      auto ResultType = [TaggedType]() -> std::string {
+      auto ElementType = TaggedType.rtrim("[]");
+      auto ResultType = [&]() -> std::string {
         if (!TaggedType.ends_with("[]"))
           return TaggedType.str();
         if (TaggedType == "char[]")
           return "std::string";
 
-        return ("std::vector<" + TaggedType.drop_back(2) + ">").str();
+        return ("std::vector<" + ElementType + ">").str();
       }();
       auto ReturnType =
           "std::variant<" + ResultType + ", " + PrefixLower + "_result_t>";
@@ -61,7 +62,15 @@ void EmitTypedGetInfoWrappers(const llvm::RecordKeeper &Records,
            << formatv("if (auto Err = {}Size({}, {}, &ResultSize))\n",
                       F.getName(), Object.getName(), Desc);
         OS << TAB_2 << formatv("return {}{{Err};\n", ReturnType);
-        OS << TAB_1 << "Result.resize(ResultSize);\n"; // TODO: Or "-1"?
+        if (TaggedType == "char[]") {
+          // Null terminator isn't counted in std::string::size.
+          OS << TAB_1 << "ResultSize -= 1;\n";
+        } else {
+          OS << TAB_1
+             << formatv("assert(ResultSize % sizeof({}) == 0);\n", ElementType);
+          OS << TAB_1 << formatv("ResultSize /= sizeof({});\n", ElementType);
+        }
+        OS << TAB_1 << "Result.resize(ResultSize);\n";
         OS << TAB_1
            << formatv("if (auto Err = {}({}, {}, ResultSize, Result.data()))\n",
                       F.getName(), Object.getName(), Desc);

>From 08d46f35be1bc64ebf401b362493e3dbf0dbb5bb Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at intel.com>
Date: Tue, 18 Nov 2025 15:05:25 -0800
Subject: [PATCH 3/4] Add missing new line

---
 offload/test/tools/offload-tblgen/get_info_wrappers.td | 6 ++++--
 offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp  | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/offload/test/tools/offload-tblgen/get_info_wrappers.td b/offload/test/tools/offload-tblgen/get_info_wrappers.td
index 9f66b3093cacd..c0412f6a27474 100644
--- a/offload/test/tools/offload-tblgen/get_info_wrappers.td
+++ b/offload/test/tools/offload-tblgen/get_info_wrappers.td
@@ -37,7 +37,8 @@ def olGetFooInfo : Function {
 // CHECK-NEXT:  }
 // CHECK-NEXT:  template<> inline auto get_info<OL_FOO_INFO_STRING>(ol_foo_handle_t Foo) {
 // CHECK-NEXT:    std::string Result;
-// CHECK-NEXT:    size_t ResultSize = 0;  if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_STRING, &ResultSize))
+// CHECK-NEXT:    size_t ResultSize = 0;
+// CHECK-NEXT:    if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_STRING, &ResultSize))
 // CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
 // CHECK-NEXT:    ResultSize -= 1;
 // CHECK-NEXT:    Result.resize(ResultSize);
@@ -48,7 +49,8 @@ def olGetFooInfo : Function {
 // CHECK-NEXT:  }
 // CHECK-NEXT:  template<> inline auto get_info<OL_FOO_INFO_ARRAY>(ol_foo_handle_t Foo) {
 // CHECK-NEXT:    std::vector<int> Result;
-// CHECK-NEXT:    size_t ResultSize = 0;  if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_ARRAY, &ResultSize))
+// CHECK-NEXT:    size_t ResultSize = 0;
+// CHECK-NEXT:    if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_ARRAY, &ResultSize))
 // CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
 // CHECK-NEXT:    assert(ResultSize % sizeof(int) == 0);
 // CHECK-NEXT:    ResultSize /= sizeof(int);
diff --git a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
index 19e64ee251316..92dd484cec6c9 100644
--- a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
+++ b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
@@ -57,7 +57,7 @@ void EmitTypedGetInfoWrappers(const llvm::RecordKeeper &Records,
                     Object.getType(), Object.getName());
       if (TaggedType.ends_with("[]")) {
         OS << TAB_1 << formatv("{0} Result;\n", ResultType);
-        OS << TAB_1 << "size_t ResultSize = 0;";
+        OS << TAB_1 << "size_t ResultSize = 0;\n";
         OS << TAB_1
            << formatv("if (auto Err = {}Size({}, {}, &ResultSize))\n",
                       F.getName(), Object.getName(), Desc);

>From 46f3c805b023a95d3a491240f8f82d771ae06c8d Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at intel.com>
Date: Tue, 18 Nov 2025 22:06:14 -0800
Subject: [PATCH 4/4] olGet*Info expects size in bytes

---
 offload/test/tools/offload-tblgen/get_info_wrappers.td | 6 ++----
 offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp  | 7 +++----
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/offload/test/tools/offload-tblgen/get_info_wrappers.td b/offload/test/tools/offload-tblgen/get_info_wrappers.td
index c0412f6a27474..a35ece354f296 100644
--- a/offload/test/tools/offload-tblgen/get_info_wrappers.td
+++ b/offload/test/tools/offload-tblgen/get_info_wrappers.td
@@ -40,8 +40,7 @@ def olGetFooInfo : Function {
 // CHECK-NEXT:    size_t ResultSize = 0;
 // CHECK-NEXT:    if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_STRING, &ResultSize))
 // CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
-// CHECK-NEXT:    ResultSize -= 1;
-// CHECK-NEXT:    Result.resize(ResultSize);
+// CHECK-NEXT:    Result.resize(ResultSize - 1);
 // CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_STRING, ResultSize, Result.data()))
 // CHECK-NEXT:      return std::variant<std::string, ol_result_t>{Err};
 // CHECK-NEXT:    else
@@ -53,8 +52,7 @@ def olGetFooInfo : Function {
 // CHECK-NEXT:    if (auto Err = olGetFooInfoSize(Foo, OL_FOO_INFO_ARRAY, &ResultSize))
 // CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
 // CHECK-NEXT:    assert(ResultSize % sizeof(int) == 0);
-// CHECK-NEXT:    ResultSize /= sizeof(int);
-// CHECK-NEXT:    Result.resize(ResultSize);
+// CHECK-NEXT:    Result.resize(ResultSize / sizeof(int));
 // CHECK-NEXT:    if (auto Err = olGetFooInfo(Foo, OL_FOO_INFO_ARRAY, ResultSize, Result.data()))
 // CHECK-NEXT:      return std::variant<std::vector<int>, ol_result_t>{Err};
 // CHECK-NEXT:    else
diff --git a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
index 92dd484cec6c9..0949899779180 100644
--- a/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
+++ b/offload/tools/offload-tblgen/TypedGetInfoWrappers.cpp
@@ -63,14 +63,13 @@ void EmitTypedGetInfoWrappers(const llvm::RecordKeeper &Records,
                       F.getName(), Object.getName(), Desc);
         OS << TAB_2 << formatv("return {}{{Err};\n", ReturnType);
         if (TaggedType == "char[]") {
-          // Null terminator isn't counted in std::string::size.
-          OS << TAB_1 << "ResultSize -= 1;\n";
+          // Null terminator isn't counted in `std::string::size()`.
+          OS << TAB_1 << "Result.resize(ResultSize - 1);\n";
         } else {
           OS << TAB_1
              << formatv("assert(ResultSize % sizeof({}) == 0);\n", ElementType);
-          OS << TAB_1 << formatv("ResultSize /= sizeof({});\n", ElementType);
+          OS << TAB_1 << formatv("Result.resize(ResultSize / sizeof({}));\n", ElementType);
         }
-        OS << TAB_1 << "Result.resize(ResultSize);\n";
         OS << TAB_1
            << formatv("if (auto Err = {}({}, {}, ResultSize, Result.data()))\n",
                       F.getName(), Object.getName(), Desc);



More information about the llvm-commits mailing list