diff --git a/llvm/test/tools/sycl-post-link/erase_used.ll b/llvm/test/tools/sycl-post-link/erase_used.ll index 45400975cec0f..5514d26159908 100644 --- a/llvm/test/tools/sycl-post-link/erase_used.ll +++ b/llvm/test/tools/sycl-post-link/erase_used.ll @@ -1,9 +1,16 @@ ; This test checks that the post-link tool does not add "llvm.used" global to -; the output modules when splitting kernels. +; the output modules when splitting modules, creating a single row table, +; and outputing IR only ; ; RUN: sycl-post-link -split=kernel -S %s -o %t.files.table ; RUN: FileCheck %s -input-file=%t.files_0.ll ; RUN: FileCheck %s -input-file=%t.files_1.ll +; +; RUN: sycl-post-link -S -split=auto -symbols -split-esimd -lower-esimd -O2 -spec-const=default %s -o %t.out.table +; RUN: FileCheck %s --input-file=%t.out_0.ll +; +; RUN: sycl-post-link -S -split=auto -ir-output-only %s -o %t.out_ir_only.ll +; RUN: FileCheck %s --input-file %t.out_ir_only.ll target triple = "spir64-unknown-unknown-sycldevice" diff --git a/llvm/tools/sycl-post-link/sycl-post-link.cpp b/llvm/tools/sycl-post-link/sycl-post-link.cpp index b67eab8a30e1d..2e5c7af154ac4 100644 --- a/llvm/tools/sycl-post-link/sycl-post-link.cpp +++ b/llvm/tools/sycl-post-link/sycl-post-link.cpp @@ -714,6 +714,20 @@ static TableFiles processOneModule(std::unique_ptr M, bool IsEsimd, if (!M) return TblFiles; + // After linking device bitcode "llvm.used" holds references to the kernels + // that are defined in the device image. But after splitting device image into + // separate kernels we may end up with having references to kernel declaration + // originating from "llvm.used" in the IR that is passed to llvm-spirv tool, + // and these declarations cause an assertion in llvm-spirv. To workaround this + // issue remove "llvm.used" from the input module before performing any other + // actions. + bool IsLLVMUsedRemoved = false; + if (GlobalVariable *GV = M->getGlobalVariable("llvm.used")) { + assert(GV->user_empty() && "unexpected llvm.used users"); + GV->eraseFromParent(); + IsLLVMUsedRemoved = true; + } + if (IsEsimd && LowerEsimd) LowerEsimdConstructs(*M); @@ -773,7 +787,8 @@ static TableFiles processOneModule(std::unique_ptr M, bool IsEsimd, // no spec constants and no splitting. // We cannot reuse input module for ESIMD code since it was transformed. bool CanReuseInputModule = !SpecConstsMet && (ResultModules.size() == 1) && - !SyclAndEsimdCode && !IsEsimd; + !SyclAndEsimdCode && !IsEsimd && + !IsLLVMUsedRemoved; string_vector Files = CanReuseInputModule ? string_vector{InputFilename} @@ -981,18 +996,6 @@ int main(int argc, char **argv) { return 1; } - // After linking device bitcode "llvm.used" holds references to the kernels - // that are defined in the device image. But after splitting device image into - // separate kernels we may end up with having references to kernel declaration - // originating from "llvm.used" in the IR that is passed to llvm-spirv tool, - // and these declarations cause an assertion in llvm-spirv. To workaround this - // issue remove "llvm.used" from the input module before performing any other - // actions. - if (GlobalVariable *GV = MPtr->getGlobalVariable("llvm.used")) { - assert(GV->user_empty() && "unexpected llvm.used users"); - GV->eraseFromParent(); - } - if (OutputFilename.getNumOccurrences() == 0) OutputFilename = (Twine(sys::path::stem(InputFilename)) + ".files").str();