diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp index 190be0aa3919d..61e84bb6808c2 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. + 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..5b371ae58f6ee 100644 --- a/llvm/test/Transforms/DeadArgElim/sycl-kernels-neg.ll +++ b/llvm/test/Transforms/DeadArgElim/sycl-kernels-neg.ll @@ -32,6 +32,32 @@ define weak_odr void @ESIMDKernel(float %arg1, float %arg2) !sycl_explicit_simd 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:%.*]]) #[[SINGLE_TASK_ATTR]] { +; 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:%.*]]) #[[ND_RANGE_ATTR:[0-9]]] { +; CHECK-NEXT: call void @foo(float [[ARG1]]) +; CHECK-NEXT: ret void +; + call void @foo(float %arg1) + ret void +} + declare void @foo(float %arg) +; CHECK: attributes #[[SINGLE_TASK_ATTR]] = { "sycl-single-task-kernel"="0" } +; CHECK: attributes #[[ND_RANGE_ATTR]] = { "sycl-nd-range-kernel"="0" } + !0 = !{}