Skip to content

[SPIR-V] Don't emit OpLifetime for Vulkan #135166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 11, 2025
Merged

Conversation

Keenuts
Copy link
Contributor

@Keenuts Keenuts commented Apr 10, 2025

Those instructions require the Kernel capability, which is not available when targeting Vulkan.

Those instructions require the Kernel capability, which is not
available when targeting Vulkan.
@llvmbot
Copy link
Member

llvmbot commented Apr 10, 2025

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

Author: Nathan Gauër (Keenuts)

Changes

Those instructions require the Kernel capability, which is not available when targeting Vulkan.


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

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp (+11-7)
  • (modified) llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll (+47-24)
diff --git a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
index 628688d83a314..bd039871dec44 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
@@ -380,6 +380,7 @@ static bool toSpvOverloadedIntrinsic(IntrinsicInst *II, Intrinsic::ID NewID,
 // or calls to proper generated functions. Returns True if F was modified.
 bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) {
   bool Changed = false;
+  const SPIRVSubtarget &STI = TM.getSubtarget<SPIRVSubtarget>(*F);
   for (BasicBlock &BB : *F) {
     for (Instruction &I : BB) {
       auto Call = dyn_cast<CallInst>(&I);
@@ -400,19 +401,22 @@ bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) {
         Changed = true;
         break;
       case Intrinsic::assume:
-      case Intrinsic::expect: {
-        const SPIRVSubtarget &STI = TM.getSubtarget<SPIRVSubtarget>(*F);
+      case Intrinsic::expect:
         if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume))
           lowerExpectAssume(II);
         Changed = true;
-      } break;
+        break;
       case Intrinsic::lifetime_start:
-        Changed |= toSpvOverloadedIntrinsic(
-            II, Intrinsic::SPVIntrinsics::spv_lifetime_start, {1});
+        if (STI.isOpenCLEnv()) {
+          Changed |= toSpvOverloadedIntrinsic(
+              II, Intrinsic::SPVIntrinsics::spv_lifetime_start, {1});
+        }
         break;
       case Intrinsic::lifetime_end:
-        Changed |= toSpvOverloadedIntrinsic(
-            II, Intrinsic::SPVIntrinsics::spv_lifetime_end, {1});
+        if (STI.isOpenCLEnv()) {
+          Changed |= toSpvOverloadedIntrinsic(
+              II, Intrinsic::SPVIntrinsics::spv_lifetime_end, {1});
+        }
         break;
       case Intrinsic::ptr_annotation:
         lowerPtrAnnotation(II);
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll
index 45683585d6514..2d2ffe36d97bd 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/lifetime.ll
@@ -1,24 +1,35 @@
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,CL
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
-; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,CL
 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
 
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-vulkan1.3-compute %s -o - | FileCheck %s --check-prefixes=CHECK,VK
+
+; FIXME(135165) Alignment capability emitted for Vulkan.
+; FIXME: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan1.3-compute %s -o - -filetype=obj | spirv-val %}
+
 ; CHECK-DAG: %[[#Char:]] = OpTypeInt 8 0
 ; CHECK-DAG: %[[#PtrChar:]] = OpTypePointer Function %[[#Char]]
 
 %tprange = type { %tparray }
 %tparray = type { [2 x i64] }
 
-; CHECK: OpFunction
-; CHECK: %[[#FooVar:]] = OpVariable
-; CHECK: %[[#Casted1:]] = OpBitcast %[[#PtrChar]] %[[#FooVar]]
-; CHECK: OpLifetimeStart %[[#Casted1]], 72
-; CHECK: OpCopyMemorySized
-; CHECK: OpBitcast
-; CHECK: OpInBoundsPtrAccessChain
-; CHECK: %[[#Casted2:]] = OpBitcast %[[#PtrChar]] %[[#FooVar]]
-; CHECK: OpLifetimeStop %[[#Casted2]], 72
+; CL:      OpFunction
+; CL:      %[[#FooVar:]] = OpVariable
+; CL-NEXT: %[[#Casted1:]] = OpBitcast %[[#PtrChar]] %[[#FooVar]]
+; CL-NEXT: OpLifetimeStart %[[#Casted1]], 72
+; CL-NEXT: OpCopyMemorySized
+; CL-NEXT: OpBitcast
+; CL-NEXT: OpInBoundsPtrAccessChain
+; CL-NEXT: %[[#Casted2:]] = OpBitcast %[[#PtrChar]] %[[#FooVar]]
+; CL-NEXT: OpLifetimeStop %[[#Casted2]], 72
+
+; VK:      OpFunction
+; VK:      %[[#FooVar:]] = OpVariable
+; VK-NEXT: OpCopyMemorySized
+; VK-NEXT: OpInBoundsAccessChain
+; VK-NEXT: OpReturn
 define spir_func void @foo(ptr noundef byval(%tprange) align 8 %_arg_UserRange) {
   %RoundedRangeKernel = alloca %tprange, align 8
   call void @llvm.lifetime.start.p0(i64 72, ptr nonnull %RoundedRangeKernel)
@@ -28,13 +39,19 @@ define spir_func void @foo(ptr noundef byval(%tprange) align 8 %_arg_UserRange)
   ret void
 }
 
-; CHECK: OpFunction
-; CHECK: %[[#BarVar:]] = OpVariable
-; CHECK: OpLifetimeStart %[[#BarVar]], 0
-; CHECK: OpCopyMemorySized
-; CHECK: OpBitcast
-; CHECK: OpInBoundsPtrAccessChain
-; CHECK: OpLifetimeStop %[[#BarVar]], 0
+; CL: OpFunction
+; CL: %[[#BarVar:]] = OpVariable
+; CL-NEXT: OpLifetimeStart %[[#BarVar]], 0
+; CL-NEXT: OpCopyMemorySized
+; CL-NEXT: OpBitcast
+; CL-NEXT: OpInBoundsPtrAccessChain
+; CL-NEXT: OpLifetimeStop %[[#BarVar]], 0
+
+; VK:      OpFunction
+; VK:      %[[#BarVar:]] = OpVariable
+; VK-NEXT: OpCopyMemorySized
+; VK-NEXT: OpInBoundsAccessChain
+; VK-NEXT: OpReturn
 define spir_func void @bar(ptr noundef byval(%tprange) align 8 %_arg_UserRange) {
   %RoundedRangeKernel = alloca %tprange, align 8
   call void @llvm.lifetime.start.p0(i64 -1, ptr nonnull %RoundedRangeKernel)
@@ -44,12 +61,18 @@ define spir_func void @bar(ptr noundef byval(%tprange) align 8 %_arg_UserRange)
   ret void
 }
 
-; CHECK: OpFunction
-; CHECK: %[[#TestVar:]] = OpVariable
-; CHECK: OpLifetimeStart %[[#TestVar]], 1
-; CHECK: OpCopyMemorySized
-; CHECK: OpInBoundsPtrAccessChain
-; CHECK: OpLifetimeStop %[[#TestVar]], 1
+; CL: OpFunction
+; CL: %[[#TestVar:]] = OpVariable
+; CL-NEXT: OpLifetimeStart %[[#TestVar]], 1
+; CL-NEXT: OpCopyMemorySized
+; CL-NEXT: OpInBoundsPtrAccessChain
+; CL-NEXT: OpLifetimeStop %[[#TestVar]], 1
+
+; VK:      OpFunction
+; VK:      %[[#Test:]] = OpVariable
+; VK-NEXT: OpCopyMemorySized
+; VK-NEXT: OpInBoundsAccessChain
+; VK-NEXT: OpReturn
 define spir_func void @test(ptr noundef align 8 %_arg) {
   %var = alloca i8, align 8
   call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %var)

@Keenuts Keenuts merged commit 476c1c5 into llvm:main Apr 11, 2025
12 checks passed
@Keenuts Keenuts deleted the lifetime-emit branch April 11, 2025 09:12
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
Those instructions require the Kernel capability, which is not available
when targeting Vulkan.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants