[llvm] [SPIRV] Add support for pointers to functions with aggregate args/returns as global variables / constant initialisers (PR #169595)

Juan Manuel Martinez CaamaƱo via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 26 02:53:58 PST 2025


================
@@ -543,11 +558,76 @@ SPIRVPrepareFunctions::removeAggregateTypesFromSignature(Function *F) {
   return NewF;
 }
 
+// Mutates indirect callsites iff if aggregate argument/return types are present
+// with the types replaced by i32 types. The change in types is noted in
+// 'spv.mutated_callsites' metadata for later restoration.
+bool SPIRVPrepareFunctions::removeAggregateTypesFromCalls(Function *F) {
+  if (F->isDeclaration() || F->isIntrinsic())
+    return false;
+
+  SmallVector<std::pair<CallBase *, FunctionType *>> Calls;
+  for (auto &&BB : *F) {
+    for (auto &&I : BB) {
+      if (auto *CB = dyn_cast<CallBase>(&I)) {
+        if (!CB->getCalledOperand() || CB->getCalledFunction())
+          continue;
+        if (CB->getType()->isAggregateType() ||
+            any_of(CB->args(),
+                  [](auto &&Arg) { return Arg->getType()->isAggregateType(); }))
+          Calls.emplace_back(CB, nullptr);
+      }
+    }
+  }
+
+  if (Calls.empty())
+    return false;
+
+  IRBuilder<> B(F->getContext());
+
+  for (auto &&[CB, NewFnTy] : Calls) {
+    SmallVector<std::pair<int, Type *>> ChangedTypes;
+    SmallVector<Type *> NewArgTypes;
+
+    if (CB->getType()->isAggregateType())
+      ChangedTypes.emplace_back(-1, CB->getType());
+
+    Type *RetTy = ChangedTypes.empty() ? CB->getType() : B.getInt32Ty();
+    for (auto &&Arg : CB->args()) {
+      if (Arg->getType()->isAggregateType()) {
+        NewArgTypes.push_back(B.getInt32Ty());
+        ChangedTypes.emplace_back(Arg.getOperandNo(), Arg->getType());
+      } else {
+        NewArgTypes.push_back(Arg->getType());
+      }
+    }
+    NewFnTy = FunctionType::get(RetTy, NewArgTypes,
+                                CB->getFunctionType()->isVarArg());
+
+    if (!CB->hasName())
+      CB->setName("spv.mutated_callsite");
----------------
jmmartinez wrote:

If I follow everything we attach a `spv.mutated_callsites` to the module that associates every mutated callsite by instruction name to the original callee type.

We could have 2 callsites with the same name on 2 separate functions. Which would raise conflicts if the original callee types do not match.

https://github.com/llvm/llvm-project/pull/169595


More information about the llvm-commits mailing list