diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 15b81a8f94adc..9390b92b4bf34 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -12154,6 +12154,14 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fsycl_link_EQ)) CmdArgs.push_back(Args.MakeArgString("--sycl-device-link")); + // Propagate [no-]rdc mode to the linker wrapper for the SYCL case. + // The default behaviour is rdc mode ON, which requires no special flags. + // In order to enable non-rdc mode, we pass --no-sycl-rdc to the linker + // wrapper. Note: -f[no-]sycl-rdc is an alias of -f[no-]gpu-rdc. + if (!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, + /*default=*/true)) + CmdArgs.push_back("--no-sycl-rdc"); + // -sycl-device-library-location= provides the location in which the // SYCL device libraries can be found. SmallString<128> DeviceLibDir(D.Dir); diff --git a/clang/test/Driver/sycl-no-rdc-new-driver.cpp b/clang/test/Driver/sycl-no-rdc-new-driver.cpp new file mode 100644 index 0000000000000..31416f2f0234c --- /dev/null +++ b/clang/test/Driver/sycl-no-rdc-new-driver.cpp @@ -0,0 +1,64 @@ +/// Tests for -f[no-]sycl-rdc with --offload-new-driver. + +// Verifies that --no-sycl-rdc is propagated to clang-linker-wrapper when +// -fno-sycl-rdc is passed. RDC is ON by default; --no-sycl-rdc signals +// RDC is OFF. + +// RUN: touch %t.cpp + +// Default (no flag): RDC is ON by default for SYCL, so --no-sycl-rdc should NOT appear. +// RUN: %clang -### --offload-new-driver --target=x86_64-unknown-linux-gnu -fsycl --no-offloadlib -fno-sycl-instrument-device-code %t.cpp 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-DEFAULT %s +// CHK-DEFAULT-NOT: --no-sycl-rdc + +// -fno-sycl-rdc: --no-sycl-rdc should appear. +// RUN: %clang -### --offload-new-driver -Werror --target=x86_64-unknown-linux-gnu -fsycl -fno-sycl-rdc --no-offloadlib -fno-sycl-instrument-device-code %t.cpp 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-NO-RDC %s +// CHK-NO-RDC: clang-linker-wrapper{{.*}} "--no-sycl-rdc" + +// AOT Intel GPU target, default RDC: --no-sycl-rdc should NOT appear. +// RUN: %clang -### --offload-new-driver --target=x86_64-unknown-linux-gnu -fsycl -fsycl-targets=intel_gpu_pvc --no-offloadlib -fno-sycl-instrument-device-code %t.cpp 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-AOT-RDC %s +// CHK-AOT-RDC-NOT: --no-sycl-rdc + +// AOT Intel GPU target + -fno-sycl-rdc: --no-sycl-rdc should appear. +// RUN: %clang -### --offload-new-driver -Werror --target=x86_64-unknown-linux-gnu -fsycl -fsycl-targets=intel_gpu_pvc -fno-sycl-rdc --no-offloadlib -fno-sycl-instrument-device-code %t.cpp 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-AOT-NO-RDC %s +// CHK-AOT-NO-RDC: clang-linker-wrapper{{.*}} "--no-sycl-rdc" + +// Test compilation step. +// RUN: not %clang -### --offload-new-driver -Werror --target=x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64_gen -fno-sycl-rdc --no-offloadlib -fno-sycl-instrument-device-code %t.cpp -c -o %t.o 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-COMPILE-STEP-ERROR %s + +// CHK-COMPILE-STEP-ERROR: error: argument unused during compilation: '-fno-sycl-rdc' [-Werror,-Wunused-command-line-argument] + +// Verify pipeline with --offload-new-driver -fno-sycl-rdc. +// RUN: touch %t1.cpp +// RUN: touch %t2.cpp +// RUN: %clang -### --offload-new-driver --target=x86_64-unknown-linux-gnu -fsycl -fno-sycl-rdc %t1.cpp %t2.cpp 2>&1 -ccc-print-phases | FileCheck %s --check-prefix=CHECK-PIPELINE + +// CHECK-PIPELINE: 0: input, "{{.*}}1.cpp", c++, (host-sycl) +// CHECK-PIPELINE: 1: preprocessor, {0}, c++-cpp-output, (host-sycl) +// CHECK-PIPELINE: 2: compiler, {1}, ir, (host-sycl) +// CHECK-PIPELINE: 3: input, "{{.*}}1.cpp", c++, (device-sycl) +// CHECK-PIPELINE: 4: preprocessor, {3}, c++-cpp-output, (device-sycl) +// CHECK-PIPELINE: 5: compiler, {4}, ir, (device-sycl) +// CHECK-PIPELINE: 6: backend, {5}, ir, (device-sycl) +// CHECK-PIPELINE: 7: offload, "device-sycl (spir64-unknown-unknown)" {6}, ir +// CHECK-PIPELINE: 8: llvm-offload-binary, {7}, image, (device-sycl) +// CHECK-PIPELINE: 9: offload, "host-sycl (x86_64-unknown-linux-gnu)" {2}, "device-sycl (x86_64-unknown-linux-gnu)" {8}, ir +// CHECK-PIPELINE: 10: backend, {9}, assembler, (host-sycl) +// CHECK-PIPELINE: 11: assembler, {10}, object, (host-sycl) +// CHECK-PIPELINE: 12: input, "{{.*}}2.cpp", c++, (host-sycl) +// CHECK-PIPELINE: 13: preprocessor, {12}, c++-cpp-output, (host-sycl) +// CHECK-PIPELINE: 14: compiler, {13}, ir, (host-sycl) +// CHECK-PIPELINE: 15: input, "{{.*}}2.cpp", c++, (device-sycl) +// CHECK-PIPELINE: 16: preprocessor, {15}, c++-cpp-output, (device-sycl) +// CHECK-PIPELINE: 17: compiler, {16}, ir, (device-sycl) +// CHECK-PIPELINE: 18: backend, {17}, ir, (device-sycl) +// CHECK-PIPELINE: 19: offload, "device-sycl (spir64-unknown-unknown)" {18}, ir +// CHECK-PIPELINE: 20: llvm-offload-binary, {19}, image, (device-sycl) +// CHECK-PIPELINE: 21: offload, "host-sycl (x86_64-unknown-linux-gnu)" {14}, "device-sycl (x86_64-unknown-linux-gnu)" {20}, ir +// CHECK-PIPELINE: 22: backend, {21}, assembler, (host-sycl) +// CHECK-PIPELINE: 23: assembler, {22}, object, (host-sycl) +// CHECK-PIPELINE: 24: clang-linker-wrapper, {11, 23}, image, (host-sycl) diff --git a/sycl/doc/design/NonRelocatableDeviceCode.md b/sycl/doc/design/NonRelocatableDeviceCode.md index 8b74beca63be0..edb843185a98c 100644 --- a/sycl/doc/design/NonRelocatableDeviceCode.md +++ b/sycl/doc/design/NonRelocatableDeviceCode.md @@ -1,5 +1,7 @@ # Non-Relocatable Device Code +Note: This document reflects the design of NoRDC Mode support in the Old Offload Model. + ## Overview By default, SYCL allows device code to be relocatable, where function calls outside of the current translation unit are allowed using the `SYCL_EXTERNAL` attribute. diff --git a/sycl/doc/design/OffloadDesign.md b/sycl/doc/design/OffloadDesign.md index 35a86d2184ea2..0485e6ad48e63 100644 --- a/sycl/doc/design/OffloadDesign.md +++ b/sycl/doc/design/OffloadDesign.md @@ -243,6 +243,18 @@ are needed to pass along this information. *Table: Ahead of Time Info* +### NoRDC Mode support + +For the Old Offload Model support of NoRDC Mode see [NonRelocatableDeviceCode.md](NonRelocatableDeviceCode.md). + +The default compiler behavior is -fsycl-rdc, which incorporates linking of device code. If -fno-sycl-rdc is specified, the compiler skips linking of device code and performs offload processing on every module individually. + +A follow-up patch will add support for specifying `-fno-sycl-rdc` at the compile step +(i.e. `clang++ --offload-new-driver -fsycl -fno-sycl-rdc -c`), matching the old offload +model's usage pattern. This will be implemented by invoking `clang-linker-wrapper +--sycl-device-link --no-sycl-rdc` per translation unit at compile time to finalize each +TU's device code independently, embedding the result directly into the host object. + #### Format of the --device-compiler Option The `--device-compiler` option uses the format `--device-compiler=[:][=]` where: - `` : specifies the offloading kind (e.g., sycl, hip, openmp) and is optional. diff --git a/sycl/test-e2e/AOT/early_aot.cpp b/sycl/test-e2e/AOT/early_aot.cpp index 49385d7857fa5..6727d91a53f69 100644 --- a/sycl/test-e2e/AOT/early_aot.cpp +++ b/sycl/test-e2e/AOT/early_aot.cpp @@ -1,13 +1,14 @@ // Test early-AOT behaviors with -fsycl -fno-sycl-rdc. This targets spir64_gen // REQUIRES: ocloc, gpu, target-spir -// XFAIL: new-offload-model -// XFAIL-TRACKER: CMPLRLLVM-51875 + +// Note: New Offload Model temporarily requires -fno-sycl-rdc to be specified +// at the linking step. Old Offload Model requires it at the compilation step. // Build the early AOT device binaries -// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend=spir64_gen %gpu_aot_target_opts -fno-sycl-rdc -c -DADD_CPP %s -o %t_add.o -// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend=spir64_gen %gpu_aot_target_opts -fno-sycl-rdc -c -DSUB_CPP %s -o %t_sub.o -// RUN: %clangxx -fsycl -DMAIN_CPP %s %t_add.o %t_sub.o -o %t.out +// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend=spir64_gen %gpu_aot_target_opts %if !new-offload-model %{ -fno-sycl-rdc %} -c -DADD_CPP %s -o %t_add.o +// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend=spir64_gen %gpu_aot_target_opts %if !new-offload-model %{ -fno-sycl-rdc %} -c -DSUB_CPP %s -o %t_sub.o +// RUN: %clangxx -fsycl %if new-offload-model %{ -fno-sycl-rdc %} -DMAIN_CPP %s %t_add.o %t_sub.o -o %t.out // RUN: %{run} %t.out