[llvm] [SPIR-V] Dereference non-null OpGroupAsyncCopy event operands typed as pointer-to-Event (PR #214222)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 5 05:52:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-spir-v

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

Discussed in https://github.com/llvm/llvm-project/pull/212754

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


2 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp (+17) 
- (added) llvm/test/CodeGen/SPIRV/transcoding/OpGroupAsyncCopy-nonnull-event.ll (+28) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 7d5c2bac4250e..08b982e59dcbd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -3132,6 +3132,10 @@ static bool generateAsyncCopy(const SPIRV::IncomingCall *Call,
       MachineRegisterInfo *MRI = MIRBuilder.getMRI();
       Register ConstReg = EventReg;
       MachineInstr *Def = getDefInstrMaybeConstant(ConstReg, MRI);
+      SPIRVTypeInst EventPointeeType =
+          EventType && EventType->getOpcode() == SPIRV::OpTypePointer
+              ? GR->getPointeeType(EventType)
+              : nullptr;
       if (Def->getOpcode() == TargetOpcode::G_CONSTANT &&
           Def->getOperand(1).getCImm()->isZero()) {
         // Only substitute a null Event for the "ptr null" idiom, not for a
@@ -3145,6 +3149,19 @@ static bool generateAsyncCopy(const SPIRV::IncomingCall *Call,
             .addDef(NullEventReg)
             .addUse(EventTyReg);
         EventReg = NullEventReg;
+      } else if (EventPointeeType &&
+                 EventPointeeType->getOpcode() == SPIRV::OpTypeEvent) {
+        // Dereference: a real event can end up typed as pointer-to-Event
+        // after round-tripping through a stack slot under the legacy
+        // opaque-ptr ocl_event ABI.
+        Register EventTyReg = GR->getSPIRVTypeID(EventPointeeType);
+        Register LoadedReg =
+            createVirtualRegister(EventPointeeType, GR, MIRBuilder);
+        MIRBuilder.buildInstr(SPIRV::OpLoad)
+            .addDef(LoadedReg)
+            .addUse(EventTyReg)
+            .addUse(EventReg);
+        EventReg = LoadedReg;
       }
     }
     bool Res = MIRBuilder.buildInstr(Opcode)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpGroupAsyncCopy-nonnull-event.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpGroupAsyncCopy-nonnull-event.ll
new file mode 100644
index 0000000000000..0c7cea15c0cc5
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpGroupAsyncCopy-nonnull-event.ll
@@ -0,0 +1,28 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; Check a real (non-null) event_t reloaded from a stack slot is dereferenced
+; to OpTypeEvent before being used as an OpGroupAsyncCopy Event operand.
+
+; CHECK-SPIRV-DAG: %[[#EventTy:]] = OpTypeEvent
+; CHECK-SPIRV-DAG: %[[#EventPtrTy:]] = OpTypePointer Function %[[#EventTy]]
+; CHECK-SPIRV: %[[#EventVar:]] = OpBitcast %[[#EventPtrTy]]
+; CHECK-SPIRV: %[[#FirstEvent:]] = OpGroupAsyncCopy %[[#EventTy]]
+; CHECK-SPIRV: OpStore %[[#EventVar]] %[[#FirstEvent]]
+; CHECK-SPIRV: %[[#ReloadedPtr:]] = OpLoad %[[#EventPtrTy]]
+; CHECK-SPIRV: %[[#ReloadedEvent:]] = OpLoad %[[#EventTy]] %[[#ReloadedPtr]]
+; CHECK-SPIRV: OpGroupAsyncCopy %[[#EventTy]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#ReloadedEvent]]
+
+%opencl.event_t = type opaque
+
+define spir_kernel void @foo(ptr addrspace(1) %src, ptr addrspace(3) %dst) {
+entry:
+  %event = alloca ptr, align 4
+  %call1 = call spir_func ptr @_Z21async_work_group_copyPU3AS1Dv2_cPKU3AS3S_j9ocl_event(ptr addrspace(1) %src, ptr addrspace(3) %dst, i32 4, ptr null)
+  store ptr %call1, ptr %event, align 4
+  %reloaded = load ptr, ptr %event, align 4
+  %call2 = call spir_func ptr @_Z21async_work_group_copyPU3AS1Dv2_cPKU3AS3S_j9ocl_event(ptr addrspace(1) %src, ptr addrspace(3) %dst, i32 4, ptr %reloaded)
+  ret void
+}
+
+declare spir_func ptr @_Z21async_work_group_copyPU3AS1Dv2_cPKU3AS3S_j9ocl_event(ptr addrspace(1), ptr addrspace(3), i32, ptr)

``````````

</details>


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


More information about the llvm-commits mailing list