[llvm] [SPIR-V] Fix i8 pointer type for NULL events in OpEnqueueKernel (PR #201125)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 2 07:05:21 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>



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


2 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp (+26-12) 
- (modified) llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll (+4-5) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 9bc29dd0103a6..7c32914e609eb 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2975,27 +2975,41 @@ static bool buildEnqueueKernel(const SPIRV::IncomingCall *Call,
   // 2. Process all arguments which requered preparation.
   // 2.1 Events - use Call arguments, or use dummy nulls in case of absence of
   // events
+
+  // Per SPIR-V spec, OpEnqueueKernel's Wait Events / Ret Event operands
+  // must be pointers to OpTypeDeviceEvent. Build the LLVM TargetExtType
+  // for spirv.DeviceEvent so getOrCreateSPIRVPointerType can register
+  // both the SPIR-V type and the LLVM-side mapping; deriving the pointer
+  // from an opaque LLVM PointerType would lose the pointee and deduce
+  // to <Generic i8*>.
+  auto BuildDeviceEventNullPtr = [&]() {
+    LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
+    Type *DeviceEventTy = TargetExtType::get(Ctx, "spirv.DeviceEvent");
+    SPIRVTypeInst DeviceEventPtrTy = GR->getOrCreateSPIRVPointerType(
+        DeviceEventTy, MIRBuilder, SPIRV::StorageClass::Generic);
+    return GR->getOrCreateConstNullPtr(MIRBuilder, DeviceEventPtrTy);
+  };
+
   Register NumEventsReg;
   Register WaitEventsReg;
   Register RetEventReg;
   if (HasEvents) {
+    auto IsNullEvent = [&](Register R) {
+      MachineInstr *Def = getDefInstrMaybeConstant(R, MRI);
+      return Def->getOpcode() == TargetOpcode::G_CONSTANT &&
+             Def->getOperand(1).getCImm()->isZero();
+    };
+
     NumEventsReg = Call->Arguments[NumEventsIdx];
     WaitEventsReg = Call->Arguments[WaitEventsIdx];
     RetEventReg = Call->Arguments[RetEventIdx];
+    if (IsNullEvent(WaitEventsReg))
+      WaitEventsReg = BuildDeviceEventNullPtr();
+    if (IsNullEvent(RetEventReg))
+      RetEventReg = BuildDeviceEventNullPtr();
   } else {
     NumEventsReg = buildConstantIntReg32(0, MIRBuilder, GR);
-    // Per SPIR-V spec, OpEnqueueKernel's Wait Events / Ret Event operands
-    // must be pointers to OpTypeDeviceEvent. Build the LLVM TargetExtType
-    // for spirv.DeviceEvent so getOrCreateSPIRVPointerType can register
-    // both the SPIR-V type and the LLVM-side mapping; deriving the pointer
-    // from an opaque LLVM PointerType would lose the pointee and deduce
-    // to <Generic i8*>.
-    LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
-    Type *DeviceEventTy = TargetExtType::get(Ctx, "spirv.DeviceEvent");
-    SPIRVTypeInst DeviceEventPtrTy = GR->getOrCreateSPIRVPointerType(
-        DeviceEventTy, MIRBuilder, SPIRV::StorageClass::Generic);
-    Register NullPtr =
-        GR->getOrCreateConstNullPtr(MIRBuilder, DeviceEventPtrTy);
+    Register NullPtr = BuildDeviceEventNullPtr();
     WaitEventsReg = NullPtr;
     RetEventReg = NullPtr;
   }
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll b/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll
index 2d7e73d71094e..ce51b91b775ff 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/enqueue_kernel.ll
@@ -24,7 +24,6 @@
 ; CHECK-DAG: %[[#TypeNDRangeStruct:]] = OpTypeStruct %[[#typeInt32]] %[[#Array3x64]] %[[#Array3x64]] %[[#Array3x64]]
 
 ; CHECK-DAG: %[[#pointerInt8:]] = OpTypePointer Generic %[[#typeInt8]]
-; CHECK-DAG: %[[#nullPtrInt8:]] = OpConstantNull %[[#pointerInt8]]
 ; CHECK-DAG: %[[#nullArray3x64:]] = OpConstantNull %[[#Array3x64]]
 
 ; CHECK-DAG: %[[#typeEvent:]] = OpTypeDeviceEvent
@@ -60,9 +59,8 @@
 ;;
 ;;     const size_t gs[] = {1,2,4};
 ;;
-; TODO: Fix int8 type came from clang in case of NULL events passed in opencl's enqueue_kernel.
 ;;     // enqueue empty kernel
-; CHECK: %[[#]] = OpEnqueueKernel %[[#typeInt32]] %[[#default_queue:]] %[[#Num1i32]] %[[#NDRange3]] %[[#Num0i32]] %[[#nullPtrInt8]] %[[#nullPtrInt8]] %[[#InvokeKernel1]] %[[#]] %[[#Num16i32]] %[[#Num8i32]]
+; CHECK: %[[#]] = OpEnqueueKernel %[[#typeInt32]] %[[#default_queue:]] %[[#Num1i32]] %[[#NDRange3]] %[[#Num0i32]] %[[#nullPtrEvent]] %[[#nullPtrEvent]] %[[#InvokeKernel1]] %[[#]] %[[#Num16i32]] %[[#Num8i32]]
 ;;     enqueue_kernel(default_queue,
 ;;             CLK_ENQUEUE_FLAGS_WAIT_KERNEL,
 ;;             ndrange_3D(gs),
@@ -86,7 +84,8 @@
 ;;             });
 ;;
 ;;     // events, var arg
-; CHECK: %[[#]] = OpEnqueueKernel %[[#typeInt32]] %[[#default_queue]] %[[#Num0i32]] %[[#]] %[[#Num2i32]] %[[#event_wait_list2:]] %[[#event2]] %[[#InvokeKernel4]] %[[#]] %[[#Num16i32]] %[[#Num8i32]] %[[#]]
+; CHECK: %[[#event_wait_list2:]] = OpPtrCastToGeneric %[[#]] %[[#]]
+; CHECK: %[[#]] = OpEnqueueKernel %[[#typeInt32]] %[[#default_queue]] %[[#Num0i32]] %[[#]] %[[#Num2i32]] %[[#event_wait_list2]] %[[#event2]] %[[#InvokeKernel4]] %[[#]] %[[#Num16i32]] %[[#Num8i32]] %[[#]]
 ;;     char c;
 ;;     enqueue_kernel(default_queue, flags, ndrange, 2, event_wait_list2, &clk_event,
 ;;             ^(local void *p) {
@@ -103,7 +102,7 @@
 ;;             101, 102, 104);
 ;;
 ;;     // null event, no var args
-; CHECK: %[[#]] = OpEnqueueKernel %[[#typeInt32]] %[[#default_queue]] %[[#Num0i32]] %[[#]] %[[#Num0i32]] %[[#nullPtrInt8]] %[[#event2]] %[[#InvokeKernel6]] %[[#]] %[[#Num36i32]] %[[#Num8i32]]
+; CHECK: %[[#]] = OpEnqueueKernel %[[#typeInt32]] %[[#default_queue]] %[[#Num0i32]] %[[#]] %[[#Num0i32]] %[[#nullPtrEvent]] %[[#event2]] %[[#InvokeKernel6]] %[[#]] %[[#Num36i32]] %[[#Num8i32]]
 ;;     enqueue_kernel(default_queue, flags, ndrange, 0, NULL, &clk_event,
 ;;             ^(void) {
 ;;             a[i] = b[i];

``````````

</details>


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


More information about the llvm-commits mailing list