[llvm] 511757d - [SPIR-V] Fix crash when a function pointer global is a use of a cloned function (#216638)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 03:25:26 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-08-18T12:25:21+02:00
New Revision: 511757d18596bc3220dd195fe8fe79d298fbce65

URL: https://github.com/llvm/llvm-project/commit/511757d18596bc3220dd195fe8fe79d298fbce65
DIFF: https://github.com/llvm/llvm-project/commit/511757d18596bc3220dd195fe8fe79d298fbce65.diff

LOG: [SPIR-V] Fix crash when a function pointer global is a use of a cloned function (#216638)

GlobalValue operands must be updated via replaceUsesOfWith, not
Constant::handleOperandChange, which doesn't support them

Fixes LCOMPILER-2616

Added: 
    

Modified: 
    llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
    llvm/test/CodeGen/SPIRV/passes/SPIRVPrepareFunctions.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
index 6d54b6c6fa19d..d784de3de3610 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
@@ -630,20 +630,17 @@ SPIRVPrepareFunctionsImpl::removeAggregateTypesFromSignature(Function *F) {
   CloneFunctionInto(NewF, F, VMap, CloneFunctionChangeType::LocalChangesOnly,
                     Returns);
   NewF->takeName(F);
+  NewF->setComdat(F->getComdat());
 
   addFunctionTypeMutation(
       NewF->getParent()->getOrInsertNamedMetadata("spv.cloned_funcs"),
       std::move(ChangedTypes), NewF->getName());
 
-  for (auto *U : make_early_inc_range(F->users())) {
-    if (CallInst *CI;
-        (CI = dyn_cast<CallInst>(U)) && CI->getCalledFunction() == F)
+  for (User *U : F->users()) {
+    if (auto *CI = dyn_cast<CallInst>(U); CI && CI->getCalledFunction() == F)
       CI->mutateFunctionType(NewF->getFunctionType());
-    if (auto *C = dyn_cast<Constant>(U))
-      C->handleOperandChange(F, NewF);
-    else
-      U->replaceUsesOfWith(F, NewF);
   }
+  F->replaceAllUsesWith(NewF);
 
   // register the mutation
   if (RetType != F->getReturnType())

diff  --git a/llvm/test/CodeGen/SPIRV/passes/SPIRVPrepareFunctions.ll b/llvm/test/CodeGen/SPIRV/passes/SPIRVPrepareFunctions.ll
index 91ba08d682015..6700de4f7ebd4 100644
--- a/llvm/test/CodeGen/SPIRV/passes/SPIRVPrepareFunctions.ll
+++ b/llvm/test/CodeGen/SPIRV/passes/SPIRVPrepareFunctions.ll
@@ -1,5 +1,8 @@
 ; RUN: opt -S -passes=spirv-prepare-functions -mtriple=spirv64-unknown-unknown < %s | FileCheck %s
 
+ at fp = global ptr addrspace(4) @callback
+; CHECK: @fp = global ptr addrspace(4) @callback
+
 ; @llvm.bswap.* is replaced with a call to a SPIR-V helper function whose
 ; body implements the byte-swap with shifts/masks/ors.
 define i32 @bswap_i32(i32 %x) {
@@ -33,6 +36,16 @@ define void @memset_attrs(ptr %p, i8 %v, i32 %n) {
   ret void
 }
 
+; @fp keeps pointing at @callback across the clone/rename via RAUW.
+; CHECK-LABEL: define void @caller(
+; CHECK: %ptr = load ptr addrspace(4), ptr @fp
+; CHECK: call addrspace(4) i32 %ptr(i32 0), !spv.mutated_callsite ![[#MUTATED_CS:]]
+define void @caller() {
+  %ptr = load ptr addrspace(4), ptr @fp
+  %r = call addrspace(4) { float, float } %ptr(i32 0)
+  ret void
+}
+
 ; The bswap helper is materialized with the standard shift/mask/or unrolling.
 ; CHECK-LABEL: define i32 @spirv.llvm_bswap_i32(i32 %0)
 ; CHECK-DAG:   shl i32 %0, 24
@@ -71,3 +84,14 @@ declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1)
 declare i32 @llvm.bswap.i32(i32)
 declare i32 @llvm.fshl.i32(i32, i32, i32)
 declare i32 @llvm.fshr.i32(i32, i32, i32)
+
+; CHECK-LABEL: define i32 @callback(
+define { float, float } @callback({ float, float } %x) addrspace(4) {
+  ret { float, float } %x
+}
+
+; CHECK-DAG: ![[#MUTATED_CS]] = !{!"spv.mutated_callsite.caller.0"}
+; CHECK-DAG: !spv.cloned_funcs = !{![[#CLONED:]]}
+; CHECK-DAG: ![[#CLONED]] = !{!"callback", ![[#RET:]], ![[#ARG:]]}
+; CHECK-DAG: ![[#RET]] = !{i32 -1, { float, float } zeroinitializer}
+; CHECK-DAG: ![[#ARG]] = !{i32 0, { float, float } zeroinitializer}


        


More information about the llvm-commits mailing list