Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -7273,6 +7273,8 @@ defm sycl_allow_device_image_dependencies: BoolOptionWithoutMarshalling<"f", "sy
def fsycl_dump_device_code_EQ : Joined<["-"], "fsycl-dump-device-code=">,
Flags<[NoXarchOption]>,
HelpText<"Dump device code into the user provided directory.">;
def fsyclbin : Flag<["-"], "fsyclbin">,
HelpText<"Create a SYCLBIN file">;
} // let Group = sycl_Group

// FIXME: -fsycl-explicit-simd is deprecated. remove it when support is dropped.
Expand Down
39 changes: 35 additions & 4 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,9 +1221,11 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
// We need to generate a SYCL toolchain if the user specified -fsycl.
// If -fsycl is supplied without any of these we will assume SPIR-V.
// Use of -fsycl-device-only overrides -fsycl.
// Use of -fsyclbin enables SYCL device compilation.
bool IsSYCL = C.getInputArgs().hasFlag(options::OPT_fsycl,
options::OPT_fno_sycl, false) ||
C.getInputArgs().hasArg(options::OPT_fsycl_device_only);
C.getInputArgs().hasArgNoClaim(options::OPT_fsycl_device_only,
options::OPT_fsyclbin);

auto argSYCLIncompatible = [&](OptSpecifier OptId) {
if (!IsSYCL)
Expand Down Expand Up @@ -3464,7 +3466,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
Arg *InputTypeArg = nullptr;
bool IsSYCL =
Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) ||
Args.hasArg(options::OPT_fsycl_device_only);
Args.hasArgNoClaim(options::OPT_fsycl_device_only, options::OPT_fsyclbin);

// The last /TC or /TP option sets the input type to C or C++ globally.
if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,
Expand Down Expand Up @@ -7929,6 +7931,19 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
C.MakeAction<LinkJobAction>(OffloadActions, types::TY_HIP_FATBIN);
DDep.add(*FatbinAction, *C.getSingleOffloadToolChain<Action::OFK_HIP>(),
nullptr, Action::OFK_HIP);
} else if (C.isOffloadingHostKind(Action::OFK_SYCL) &&
Args.hasArg(options::OPT_fsyclbin)) {
// With '-fsyclbin', package all the offloading actions into a single output
// that is sent to the clang-linker-wrapper.
Action *PackagerAction =
C.MakeAction<OffloadPackagerJobAction>(OffloadActions, types::TY_Image);
ActionList PackagerActions;
PackagerActions.push_back(PackagerAction);
Action *LinkAction =
C.MakeAction<LinkerWrapperJobAction>(PackagerActions, types::TY_Image);
DDep.add(*LinkAction, *C.getSingleOffloadToolChain<Action::OFK_Host>(),
nullptr, C.getActiveOffloadKinds());
return C.MakeAction<OffloadAction>(DDep, types::TY_Nothing);
} else {
// Package all the offloading actions into a single output that can be
// embedded in the host and linked.
Expand Down Expand Up @@ -9336,8 +9351,10 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
return C.addResultFile(FinalOutput->getValue(), &JA);
// Output to destination for -fsycl-device-only and Windows -o
if (offloadDeviceOnly() && JA.getOffloadingDeviceKind() == Action::OFK_SYCL)
// Output to destination for -fsycl-device-only/-fsyclbin and Windows -o
if ((offloadDeviceOnly() ||
C.getArgs().hasArgNoClaim(options::OPT_fsyclbin)) &&
JA.getOffloadingDeviceKind() == Action::OFK_SYCL)
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT__SLASH_o))
return C.addResultFile(FinalOutput->getValue(), &JA);
}
Expand Down Expand Up @@ -9506,6 +9523,20 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
else
BaseName = llvm::sys::path::filename(BasePath);

// When compiling with -fsyclbin, maintain a simple output file name for the
// resulting image. A '.syclbin' extension is used to represent the resulting
// output file.
if (JA.getOffloadingDeviceKind() == Action::OFK_SYCL &&
C.getArgs().hasArgNoClaim(options::OPT_fsyclbin) &&
JA.getType() == types::TY_Image) {
SmallString<128> SYCLBinOutput(getDefaultImageName());
if (IsCLMode())
// Use BaseName for the syclbin output name.
SYCLBinOutput = BaseName;
llvm::sys::path::replace_extension(SYCLBinOutput, ".syclbin");
return C.addResultFile(C.getArgs().MakeArgString(SYCLBinOutput), &JA);
}

// Determine what the derived output name should be.
const char *NamedOutput;

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11470,6 +11470,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(
Args.MakeArgString("--sycl-target-link-options=" + LinkOptString));
}
// Add option to enable creating of the .syclbin file.
if (Args.hasArg(options::OPT_fsyclbin))
CmdArgs.push_back(Args.MakeArgString("--syclbin"));
}

// Construct the link job so we can wrap around it.
Expand Down
67 changes: 67 additions & 0 deletions clang/test/Driver/fsyclbin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/// Tests behaviors of -fsyclbin

/// -fsyclbin is only used with the new offloading model.
// RUN: %clangxx -fsycl -fsyclbin --no-offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=UNUSED
// UNUSED: warning: argument unused during compilation: '-fsyclbin'

/// -fsyclbin -fsycl-device-only usage. -fsycl-device-only will 'win' and
/// -fsyclbin is effectively ignored.
// RUN: %clangxx -fsycl-device-only -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=SYCLBIN_UNUSED
// RUN: %clang_cl -fsycl-device-only -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=SYCLBIN_UNUSED
// SYCLBIN_UNUSED: warning: argument unused during compilation: '-fsyclbin'

/// Check tool invocation contents.
// RUN: %clangxx -fsycl -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_TOOLS
// RUN: %clangxx -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_TOOLS
// RUN: %clang_cl -fsycl -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_TOOLS
// CHECK_TOOLS: clang-offload-packager
// CHECK_TOOLS-SAME: --image=file={{.*}}.bc,triple=spir64-unknown-unknown
// CHECK_TOOLS-SAME: kind=sycl
// CHECK_TOOLS: clang-linker-wrapper
// CHECK_TOOLS-SAME: --syclbin

/// Check compilation phases, only device compile should be performed
// RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsycl -fsyclbin \
// RUN: --offload-new-driver %s -ccc-print-phases 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_PHASES
// RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsyclbin \
// RUN: --offload-new-driver %s -ccc-print-phases 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_PHASES
// CHECK_PHASES: 0: input, "{{.*}}", c++, (device-sycl)
// CHECK_PHASES: 1: preprocessor, {0}, c++-cpp-output, (device-sycl)
// CHECK_PHASES: 2: compiler, {1}, ir, (device-sycl)
// CHECK_PHASES: 3: backend, {2}, ir, (device-sycl)
// CHECK_PHASES: 4: offload, "device-sycl (spir64-unknown-unknown)" {3}, ir
// CHECK_PHASES: 5: clang-offload-packager, {4}, image, (device-sycl)
// CHECK_PHASES: 6: clang-linker-wrapper, {5}, image, (device-sycl)
// CHECK_PHASES: 7: offload, "device-sycl (x86_64-unknown-linux-gnu)" {6}, none

/// Check the output file names (file.syclbin, or -o <file>)
// RUN: %clangxx -fsyclbin --offload-new-driver -o file.syclbin %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_NAMED_OUTPUT
// CHECK_NAMED_OUTPUT: clang-linker-wrapper
// CHECK_NAMED_OUTPUT-SAME: "-o" "file.syclbin"

// RUN: %clang_cl -fsyclbin --offload-new-driver -o file.syclbin %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_NAMED_OUTPUT_WIN
// CHECK_NAMED_OUTPUT_WIN: clang-linker-wrapper
// CHECK_NAMED_OUTPUT_WIN-SAME: "-out:file.syclbin"

/// For Linux - the default is 'a.out' so the syclbin file is 'a.syclbin'
// RUN: %clangxx -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_LINUX_DEFAULT_OUTPUT
// CHECK_LINUX_DEFAULT_OUTPUT: clang-linker-wrapper
// CHECK_LINUX_DEFAULT_OUTPUT-SAME: "-o" "a.syclbin"

/// For Windows - the default is based on the source file so the syclbin file
/// is 'fsyclbin.syclbin'
// RUN: %clang_cl -fsyclbin --offload-new-driver %s -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK_WIN_DEFAULT_OUTPUT
// CHECK_WIN_DEFAULT_OUTPUT: clang-linker-wrapper
// CHECK_WIN_DEFAULT_OUTPUT-SAME: "-out:{{.*}}fsyclbin.syclbin"
10 changes: 1 addition & 9 deletions sycl/test/syclbin/simple_kernel.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// RUN: %clangxx -fsycl-device-only -Xclang -emit-llvm-bc -o %t.bc %s
// RUN: clang-offload-packager -o %t.out "--image=file=%t.bc,triple=spir64-unknown-unknown,arch=,kind=sycl,compile-opts="
// RUN: clang-linker-wrapper --syclbin --host-triple=x86_64-unknown-linux-gnu -sycl-device-libraries="libsycl-crt.new.o" -sycl-device-library-location=%sycl_libs_dir --sycl-post-link-options="-device-globals" --llvm-spirv-options=-spirv-max-version=1.4 -o %t.syclbin %t.out
// RUN: %clangxx --offload-new-driver -fsyclbin -o %t.syclbin %s
// RUN: syclbin-dump %t.syclbin | FileCheck %s

// Checks the generated SYCLBIN contents of a simple SYCL free function kernel.

// TODO: Replace clang tooling invocation with -fsyclbin clang driver command
// when available. Once this is in place, Windows should also be
// supported.
// UNSUPPORTED: windows
// UNSUPPORTED-TRACKER: CMPLRLLVM-65259

#include <sycl/sycl.hpp>

extern "C" {
Expand Down
Loading