Skip to content

Conversation

@YixingZhang007
Copy link
Contributor

@YixingZhang007 YixingZhang007 commented Nov 19, 2025

In another patch #19579, compilation and linking options used in ClangLinkerWrapper are changed to be consumed from the SYCLImage, instead of sycl_backend_compile_options_EQ and sycl_target_link_options_EQ that are passed as argument to the ClangLinkerWrapper. Because option in SYCLImage are options passed at compiler-time, we want to support for link-time options by passing them through device-compiler and device-linker argument for ClangLinkerWrapper. The specific changes are listed below.

  1. Remove gpu_tool_arg_EQ and cpu_tool_arg_EQ options specification in LinkerWrapperOpts.td. We are now passing the link time backend compile option through OPT_device_compiler_args_EQ to ClangLinkerWrapper, as coded in Clang.cpp. We are also passing link time linker option through OPT_device_linker_args_EQ to ClangLinkerWrapper.
  2. In Clang.cpp, we call AddImpliedTargetArgs to add SYCL target-specific arguments to ClangLinkerWrapper by processing the arguments passed to Clang. OPT_ftarget_register_alloc_mode_EQ is added to the CompilerOptions so that it can be available in AddImpliedTargetArgs for determining whether to add -ftarget-register-alloc-mode=xxx to the compiler arguments.
  3. In ClangLinkerWrapper.cpp, the options in OPT_device_compiler_args_EQ and OPT_device_linker_args_EQ are added and handled together with other compiler and linker options passed through SYCLImage.
  4. Modify the tests that are associated with these changes, such as those that are checking the compiler backend option and linker option passed into ClangLinkerWrapper.

With this patch, the following SYCL E2E tests pass with the new offloading model:

  1. KernelAndProgram/level-zero-link-flags.cpp
  2. ESIMD/private_memory/pm_access_1.cpp
  3. ESIMD/private_memory/pm_access_2.cpp
  4. ESIMD/private_memory/pm_access_3.cpp

@YixingZhang007 YixingZhang007 requested review from a team as code owners November 19, 2025 18:59
@YixingZhang007 YixingZhang007 marked this pull request as draft November 19, 2025 18:59
@YixingZhang007 YixingZhang007 force-pushed the fix_linker_unrecognized_option_issue branch from 43ec9a6 to 2c3b7bc Compare November 25, 2025 22:39
@YixingZhang007
Copy link
Contributor Author

The CI result of running with the new offloading model enabled as default with this patch can be found at https://github.com/intel/llvm/actions/runs/20794404398/job/59724084542?pr=20691. When comparing with the reference CI result (with only the new offloading model enabled as default, found at https://github.com/intel/llvm/actions/runs/20782646887/job/59683703668?pr=20570), we can see that 4 SYCL E2E tests (listed in the PR description) are now passing with the new offloading model and there are no regression tests.

@YixingZhang007
Copy link
Contributor Author

@intel/dpcpp-clang-driver-reviewers Could you please help review this PR? Thank you!

ArgStringList LinkerArgs;
const DerivedArgList &ToolChainArgs =
C.getArgsForToolChain(TC, /*BoundArch=*/"", Kind);
DerivedArgList BaseCompilerArgs(ToolChainArgs.getBaseArgs());
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: When we invoke getBaseArgs() on getArgsForToolChain() , we get back the original argument list that existed before Clang tailored the arguments for that toolchain.
Why not just use Args here instead of creating a new redundant variable?
We could invoke : SYCLTC.AddImpliedTargetArgs(SYCLTC.getTriple(), Args, CompilerArgs, JA, *HostTC);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As we can see in the following code, we are selectively populating BaseCompilerArgs:

 for (Arg *A : ToolChainArgs) {
        if (A->getOption().matches(OPT_Zlinker_input))
          LinkerArgs.emplace_back(A->getValue());
        else if (ShouldForward(CompilerOptions, A, *TC))
          BaseCompilerArgs.append(A);
        else if (ShouldForward(LinkerOptions, A, *TC))
          A->render(Args, LinkerArgs);
      }

DerivedArgList BaseCompilerArgs(ToolChainArgs.getBaseArgs()); creates a new container BaseCompilerArgs initialized with the base arguments, and we then update BaseCompilerArgs by selectively adding arguments from ToolChainArgs based on the filtering logic. Therefore, not every argument from Args or ToolChainArgs will be present in BaseCompilerArgs,. Therefore, I don't think we can directly use Args to replace BaseCompilerArgs. Please correct me if any mistake in my understanding. Thanks!

Copy link
Contributor

@YuriPlyakhin YuriPlyakhin Jan 9, 2026

Choose a reason for hiding this comment

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

BaseCompilerArgs is the original argument list. ToolChainArgs is a subset of BaseCompilerArgs - is that correct?
If so, how adding some options from ToolChainArgs to BaseCompilerArgs helps, when BaseCompilerArgs contains everything that ToolChainArgs contain already? Or what am I missing?

Copy link
Contributor

@srividya-sundaram srividya-sundaram Jan 9, 2026

Choose a reason for hiding this comment

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

@YixingZhang007 For this simple invocation:
clang++ -fsycl sycl.cpp
Args will be -fsycl sycl.cpp
ToolChainArgs will be (simplified) -fsycl sycl.cpp -fsycl-targets=spir64 -internal-isystem <sycl include path>
Calling getBaseArgs() on ToolChainArgs will return the original Args.
I was wondering if we could call append() on Args directly, but since Args is a const that is not possible.
So it makes sense to create BaseCompilerArgs to hold this new list.
One small nit is we could just do DerivedArgList BaseCompilerArgs(Args); but it nbd.

Copy link
Contributor

Choose a reason for hiding this comment

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

@YuriPlyakhin

when BaseCompilerArgs contains everything that ToolChainArgs contain already?

I don't think BaseCompilerArgs will contain everything that ToolChainArgs contains.
Typically, getArgsForToolChain() produces a new argument list that keeps the original args but also adds all the required args needed for the selected toolchain.( additional SYCL args, include paths for SYCL headers etc that will not be in BaseCompilerArgs)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@srividya-sundaram Thank you for the explanation! In this case, I guess we would keep the code as it is then rn :)

@YixingZhang007
Copy link
Contributor Author

I don't think the current CI failure is caused by changes in this PR. Before the last commit (which only modified a comment), all CI tests passed. @intel/llvm-gatekeepers could you please help merge this PR? Thank you!

@sarnex sarnex merged commit 1b41e95 into intel:sycl Jan 9, 2026
25 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-offload-model Enables testing with NewOffloadModel.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants