diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp index 190be0aa3919d..04ac9f82d20b2 100644 --- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -575,6 +575,17 @@ void DeadArgumentEliminationPass::surveyFunction(const Function &F) { return; } + // Do not modify arguments when the SYCL kernel is a free function kernel. + // In this case, the user sets the arguments of the kernel by themselves + // and dead argument elimination may interfere with their expectations. + const bool FuncIsSyclFreeFunctionKernel = + F.hasFnAttribute("sycl-single-task-kernel") || + F.hasFnAttribute("sycl-nd-range-kernel"); + if (FuncIsSyclFreeFunctionKernel) { + markFrozen(F); + return; + } + LLVM_DEBUG( dbgs() << "DeadArgumentEliminationPass - Inspecting callers for fn: " << F.getName() << "\n"); diff --git a/llvm/test/Transforms/DeadArgElim/sycl-kernels-neg.ll b/llvm/test/Transforms/DeadArgElim/sycl-kernels-neg.ll index 9f09f37de8012..370224d551c57 100644 --- a/llvm/test/Transforms/DeadArgElim/sycl-kernels-neg.ll +++ b/llvm/test/Transforms/DeadArgElim/sycl-kernels-neg.ll @@ -24,7 +24,30 @@ define weak_odr void @NotASpirKernel(float %arg1, float %arg2) { define weak_odr void @ESIMDKernel(float %arg1, float %arg2) !sycl_explicit_simd !0 { ; CHECK-LABEL: define {{[^@]+}}@ESIMDKernel -; CHECK-SAME: (float [[ARG1:%.*]], float [[ARG2:%.*]]) !sycl_explicit_simd !0 { +; CHECK-SAME: (float [[ARG1:%.*]], float [[ARG2:%.*]]) {{.*}}{ +; CHECK-NEXT: call void @foo(float [[ARG1]]) +; CHECK-NEXT: ret void +; + call void @foo(float %arg1) + ret void +} + +; The following two tests ensure that dead arguments are not eliminated +; from a free function kernel. + +define weak_odr spir_kernel void @FreeFuncKernelSingleTask(float %arg1, float %arg2) "sycl-single-task-kernel"="0" { +; CHECK-LABEL: define {{[^@]+}}@FreeFuncKernelSingleTask +; CHECK-SAME: (float [[ARG1:%.*]], float [[ARG2:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: call void @foo(float [[ARG1]]) +; CHECK-NEXT: ret void +; + call void @foo(float %arg1) + ret void +} + +define weak_odr spir_kernel void @FreeFuncKernelNdRange(float %arg1, float %arg2) "sycl-nd-range-kernel"="0" { +; CHECK-LABEL: define {{[^@]+}}@FreeFuncKernelNdRange +; CHECK-SAME: (float [[ARG1:%.*]], float [[ARG2:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: call void @foo(float [[ARG1]]) ; CHECK-NEXT: ret void ; diff --git a/sycl/test-e2e/FreeFunctionKernels/template_specialization.cpp b/sycl/test-e2e/FreeFunctionKernels/template_specialization.cpp index 65ce6daaa0d32..3d0a0b9b6be7d 100644 --- a/sycl/test-e2e/FreeFunctionKernels/template_specialization.cpp +++ b/sycl/test-e2e/FreeFunctionKernels/template_specialization.cpp @@ -173,7 +173,10 @@ int main() { test_func_custom_type(); test_func, float>(); test_func, uint32_t>(); - test_func, double>(); + // Variadic template functions do not work with free function kernels. See + // CMPLRLLVM-69528. + // TODO: Uncomment the following line once the tracker is resolved. + // test_func, double>(); test_func, float>(); test_accessor(); test_shared();