Skip to content
Open
24 changes: 12 additions & 12 deletions clang/test/Driver/clang-sycl-linker-test.cpp
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
// Tests the clang-sycl-linker tool.
//
// Test a simple case without arguments.
// RUN: %clangxx -emit-llvm -c %s -o %t_1.bc
// RUN: %clangxx -emit-llvm -c %s -o %t_2.bc
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: %clangxx -emit-llvm -c -target spirv64 %s -o %t_1.bc
// RUN: %clangxx -emit-llvm -c -target spirv64 %s -o %t_2.bc
// RUN: clang-sycl-linker --dry-run -v -triple=spirv64 %t_1.bc %t_2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE
// SIMPLE: "{{.*}}llvm-link{{.*}}" {{.*}}.bc {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// SIMPLE-NEXT: LLVM-SPIRV-Backend: input: {{.*}}.bc, output: a.spv
// SIMPLE-NEXT: SPIR-V Backend: input: {{.*}}.bc, output: a.spv
//
// Test that llvm-link is not called when only one input is present.
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc -o a.spv 2>&1 \
// RUN: clang-sycl-linker --dry-run -v -triple=spirv64 %t_1.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=SIMPLE-NO-LINK
// SIMPLE-NO-LINK: LLVM-SPIRV-Backend: input: {{.*}}.bc, output: a.spv
// SIMPLE-NO-LINK: SPIR-V Backend: input: {{.*}}.bc, output: a.spv
//
// Test a simple case with device library files specified.
// RUN: touch %T/lib1.bc
// RUN: touch %T/lib2.bc
// RUN: clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc -o a.spv 2>&1 \
// RUN: clang-sycl-linker --dry-run -v -triple=spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBS
// DEVLIBS: "{{.*}}llvm-link{{.*}}" {{.*}}.bc {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// DEVLIBS-NEXT: "{{.*}}llvm-link{{.*}}" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}lib1.bc {{.*}}lib2.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings
// DEVLIBS-NEXT: LLVM-SPIRV-Backend: input: [[SECONDLLVMLINKOUT]].bc, output: a.spv
// DEVLIBS-NEXT: SPIR-V Backend: input: [[SECONDLLVMLINKOUT]].bc, output: a.spv
//
// Test a simple case with .o (fat object) as input.
// TODO: Remove this test once fat object support is added.
// RUN: %clangxx -c %s -o %t.o
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t.o -o a.spv 2>&1 \
// RUN: %clangxx -c -target spirv64 %s -o %t.o
// RUN: not clang-sycl-linker --dry-run -v -triple=spirv64 %t.o -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=FILETYPEERROR
// FILETYPEERROR: Unsupported file type
//
// Test to see if device library related errors are emitted.
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs= -o a.spv 2>&1 \
// RUN: not clang-sycl-linker --dry-run -triple=spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs= -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBSERR1
// DEVLIBSERR1: Number of device library files cannot be zero
// RUN: not clang-sycl-linker --dry-run -triple spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc,lib3.bc -o a.spv 2>&1 \
// RUN: not clang-sycl-linker --dry-run -triple=spirv64 %t_1.bc %t_2.bc --library-path=%T --device-libs=lib1.bc,lib2.bc,lib3.bc -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=DEVLIBSERR2
// DEVLIBSERR2: '{{.*}}lib3.bc' SYCL device library file is not found
4 changes: 2 additions & 2 deletions clang/test/Driver/sycl-link-spirv-target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// Test that -Xlinker options are being passed to clang-sycl-linker.
// RUN: touch %t.bc
// RUN: %clangxx -### --target=spirv64 --sycl-link -Xlinker --library-path=/tmp \
// RUN: %clangxx -### --target=spirv64 --sycl-link -Xlinker -triple=spirv64 -Xlinker --library-path=/tmp \
// RUN: -Xlinker --device-libs=lib1.bc,lib2.bc %t.bc 2>&1 \
// RUN: | FileCheck %s -check-prefix=XLINKEROPTS
// XLINKEROPTS: "{{.*}}clang-sycl-linker{{.*}}" "--library-path=/tmp" "--device-libs=lib1.bc,lib2.bc" "{{.*}}.bc" "-o" "a.out"
// XLINKEROPTS: "{{.*}}clang-sycl-linker{{.*}}" "-triple=spirv64" "--library-path=/tmp" "--device-libs=lib1.bc,lib2.bc" "{{.*}}.bc" "-o" "a.out"
47 changes: 20 additions & 27 deletions clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,67 +324,60 @@ static Expected<StringRef> linkDeviceLibFiles(StringRef InputFile,
static Expected<StringRef> runSPIRVCodeGen(StringRef File,
const ArgList &Args) {
llvm::TimeTraceScope TimeScope("SPIR-V code generation");
if (Verbose || DryRun) {
errs() << formatv("LLVM-SPIRV-Backend: input: {0}, output: {1}\n", File,
OutputFile);
if (DryRun)
return OutputFile;
}

// SPIR-V-specific target initialization.
InitializeSPIRVTarget();

// Parse input module.
SMDiagnostic Err;
LLVMContext C;
std::unique_ptr<Module> M = parseIRFile(File, Err, C);
if (!M)
return createStringError(inconvertibleErrorCode(), Err.getMessage());

static const std::string DefaultTriple = "spirv64v1.6-unknown-unknown";

// Correct the Triple value if needed
// TODO: Remove this correction once we start using spirv64/spirv32 triples
// everywhere.
Triple TargetTriple(M->getTargetTriple());
if (TargetTriple.isSPIR()) {
TargetTriple.setArch(TargetTriple.getArch() == Triple::spir64
? Triple::spirv64
: Triple::spirv32,
TargetTriple.getSubArch());
M->setTargetTriple(TargetTriple);
// We need to reset Data Layout to conform with the TargetMachine
M->setDataLayout("");
}
if (TargetTriple.getTriple().empty())
TargetTriple.setTriple(DefaultTriple);
TargetTriple.setArch(TargetTriple.getArch(), Triple::SPIRVSubArch_v16);
Triple TargetTriple(Args.getLastArgValue(OPT_triple_EQ));
M->setTargetTriple(TargetTriple);

// Get a handle to SPIR-V target backend.
std::string Msg;
const Target *T = TargetRegistry::lookupTarget(M->getTargetTriple(), Msg);
if (!T)
return createStringError(Msg + ": " + M->getTargetTriple().str());

// Allocate SPIR-V target machine.
TargetOptions Options;
std::optional<Reloc::Model> RM;
std::optional<CodeModel::Model> CM;
std::unique_ptr<TargetMachine> TM(T->createTargetMachine(
M->getTargetTriple().str(), "", "", Options, RM, CM));
std::unique_ptr<TargetMachine> TM(
T->createTargetMachine(M->getTargetTriple().getTriple(), /* CPU */ "",
/* Features */ "", Options, RM, CM));
if (!TM)
return createStringError("Could not allocate target machine!");

// Set data layout if needed.
if (M->getDataLayout().isDefault())
M->setDataLayout(TM->createDataLayout());

// Open output file for writing.
int FD = -1;
if (std::error_code EC = sys::fs::openFileForWrite(OutputFile, FD))
return errorCodeToError(EC);
auto OS = std::make_unique<llvm::raw_fd_ostream>(FD, true);

// Run SPIR-V codegen passes to generate SPIR-V file.
legacy::PassManager CodeGenPasses;
TargetLibraryInfoImpl TLII(M->getTargetTriple());
CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
if (TM->addPassesToEmitFile(CodeGenPasses, *OS, nullptr,
CodeGenFileType::ObjectFile))
return createStringError("Failed to execute SPIR-V backend");
return createStringError("Failed to execute SPIR-V Backend");
CodeGenPasses.run(*M);

if (Verbose) {
errs() << formatv("SPIR-V Backend: input: {0}, output: {1}\n", File,
OutputFile);
}

return OutputFile;
}

Expand Down
12 changes: 8 additions & 4 deletions clang/tools/clang-sycl-linker/SYCLLinkOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ def device_libs_EQ : CommaJoined<["--", "-"], "device-libs=">,
Flags<[LinkerOnlyOption]>,
HelpText<"A comma separated list of device libraries that are linked during the device link.">;

def triple : Joined<["--"], "triple">,
HelpText<"The device target triple">;
def arch : Separate<["--", "-"], "arch">,
HelpText<"Specify the name of the target architecture.">;
def arch_EQ : Joined<["--", "-"], "arch=">,
Flags<[LinkerOnlyOption]>,
MetaVarName<"<arch>">,
HelpText<"The device subarchitecture">;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HelpText<"The device subarchitecture">;
HelpText<"The device architecture">;

def triple_EQ : Joined<["--", "-"], "triple=">,
Flags<[LinkerOnlyOption]>,
MetaVarName<"<triple>">,
HelpText<"The device target triple">;

def save_temps : Flag<["--", "-"], "save-temps">,
Flags<[LinkerOnlyOption]>, HelpText<"Save intermediate results">;
Expand Down