Skip to content

Let clang-cl support CUDA/HIP #68921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 19, 2023
Merged

Let clang-cl support CUDA/HIP #68921

merged 1 commit into from
Oct 19, 2023

Conversation

yxsamliu
Copy link
Collaborator

clang-cl is a driver mode that accepts options of MSVC cl.exe as a drop-in replacement for cl.exe. Currently clang-cl accepts mixed clang style options and cl style options. To let clang-cl accept a clang-style option, just need to add visibility CLOption to that option.

Currently nvcc can pass cl style options to cl.exe, which allows nvcc to compile C++ and CUDA programs with mixed nvcc and cl style options. On the other hand, clang cannot use mixed clang and cl style options to compile CUDA/HIP programs.

This patch add visibility CLOption to options needed to compile CUDA/HIP programs. This allows clang-cl to compile CUDA/HIP programs with mixed clang and cl style options.

clang-cl is a driver mode that accepts options of MSVC cl.exe as a drop-in
replacement for cl.exe. Currently clang-cl accepts mixed clang style options
and cl style options. To let clang-cl accept a clang-style option, just
need to add visibility CLOption to that option.

Currently nvcc can pass cl style options to cl.exe, which allows nvcc to
compile C++ and CUDA programs with mixed nvcc and cl style options. On
the other hand, clang cannot use mixed clang and cl style options to compile
CUDA/HIP programs.

This patch add visibility CLOption to options needed to compile CUDA/HIP
programs. This allows clang-cl to compile CUDA/HIP programs with mixed
clang and cl style options.
@yxsamliu yxsamliu requested review from MaskRay and Artem-B October 12, 2023 18:38
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Oct 12, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 12, 2023

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Yaxun (Sam) Liu (yxsamliu)

Changes

clang-cl is a driver mode that accepts options of MSVC cl.exe as a drop-in replacement for cl.exe. Currently clang-cl accepts mixed clang style options and cl style options. To let clang-cl accept a clang-style option, just need to add visibility CLOption to that option.

Currently nvcc can pass cl style options to cl.exe, which allows nvcc to compile C++ and CUDA programs with mixed nvcc and cl style options. On the other hand, clang cannot use mixed clang and cl style options to compile CUDA/HIP programs.

This patch add visibility CLOption to options needed to compile CUDA/HIP programs. This allows clang-cl to compile CUDA/HIP programs with mixed clang and cl style options.


Full diff: https://github.com/llvm/llvm-project/pull/68921.diff

3 Files Affected:

  • (modified) clang/include/clang/Driver/Options.td (+30-17)
  • (modified) clang/lib/Driver/Driver.cpp (+4-1)
  • (added) clang/test/Driver/cl-offload.cu (+27)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3f2058a5d4650ca..ceeb4c5e7c424cf 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -148,7 +148,8 @@ def pedantic_Group : OptionGroup<"<pedantic group>">, Group<f_Group>,
                      DocFlatten;
 
 def offload_Group : OptionGroup<"<offload group>">, Group<f_Group>,
-                   DocName<"Common Offloading options">;
+                   DocName<"Common Offloading options">,
+                   Visibility<[ClangOption, CLOption]>;
 
 def opencl_Group : OptionGroup<"<opencl group>">, Group<f_Group>,
                    DocName<"OpenCL options">;
@@ -157,13 +158,16 @@ def sycl_Group : OptionGroup<"<SYCL group>">, Group<f_Group>,
                  DocName<"SYCL options">;
 
 def cuda_Group : OptionGroup<"<CUDA group>">, Group<f_Group>,
-                   DocName<"CUDA options">;
+                   DocName<"CUDA options">,
+                   Visibility<[ClangOption, CLOption]>;
 
 def hip_Group : OptionGroup<"<HIP group>">, Group<f_Group>,
-                   DocName<"HIP options">;
+                   DocName<"HIP options">,
+                   Visibility<[ClangOption, CLOption]>;
 
 def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>,
-              DocName<"Target-dependent compilation options">;
+              DocName<"Target-dependent compilation options">,
+              Visibility<[ClangOption, CLOption]>;
 
 // Feature groups - these take command line options that correspond directly to
 // target specific features and can be translated directly from command line
@@ -5164,14 +5168,16 @@ def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules"
 def prebind : Flag<["-"], "prebind">;
 def preload : Flag<["-"], "preload">;
 def print_file_name_EQ : Joined<["-", "--"], "print-file-name=">,
-  HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">;
+  HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">,
+  Visibility<[ClangOption, CLOption]>;
 def print_ivar_layout : Flag<["-"], "print-ivar-layout">,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Enable Objective-C Ivar layout bitmap print trace">,
   MarshallingInfoFlag<LangOpts<"ObjCGCBitmapPrint">>;
 def print_libgcc_file_name : Flag<["-", "--"], "print-libgcc-file-name">,
   HelpText<"Print the library path for the currently used compiler runtime "
-           "library (\"libgcc.a\" or \"libclang_rt.builtins.*.a\")">;
+           "library (\"libgcc.a\" or \"libclang_rt.builtins.*.a\")">,
+  Visibility<[ClangOption, CLOption]>;
 def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
 def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
 def print_multi_flags : Flag<["-", "--"], "print-multi-flags-experimental">,
@@ -5180,27 +5186,34 @@ def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
   Flags<[Unsupported]>;
 def print_target_triple : Flag<["-", "--"], "print-target-triple">,
   HelpText<"Print the normalized target triple">,
-  Visibility<[ClangOption, FlangOption]>;
+  Visibility<[ClangOption, FlangOption, CLOption]>;
 def print_effective_triple : Flag<["-", "--"], "print-effective-triple">,
   HelpText<"Print the effective target triple">,
-  Visibility<[ClangOption, FlangOption]>;
+  Visibility<[ClangOption, FlangOption, CLOption]>;
 // GCC --disable-multiarch, GCC --enable-multiarch (upstream and Debian
 // specific) have different behaviors. We choose not to support the option.
 def : Flag<["-", "--"], "print-multiarch">, Flags<[Unsupported]>;
 def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">,
-  HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
+  HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">,
+  Visibility<[ClangOption, CLOption]>;
 def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
-  HelpText<"Print the resource directory pathname">;
+  HelpText<"Print the resource directory pathname">,
+  Visibility<[ClangOption, CLOption]>;
 def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
-  HelpText<"Print the paths used for finding libraries and programs">;
+  HelpText<"Print the paths used for finding libraries and programs">,
+  Visibility<[ClangOption, CLOption]>;
 def print_targets : Flag<["-", "--"], "print-targets">,
-  HelpText<"Print the registered targets">;
+  HelpText<"Print the registered targets">,
+  Visibility<[ClangOption, CLOption]>;
 def print_rocm_search_dirs : Flag<["-", "--"], "print-rocm-search-dirs">,
-  HelpText<"Print the paths used for finding ROCm installation">;
+  HelpText<"Print the paths used for finding ROCm installation">,
+  Visibility<[ClangOption, CLOption]>;
 def print_runtime_dir : Flag<["-", "--"], "print-runtime-dir">,
-  HelpText<"Print the directory pathname containing clangs runtime libraries">;
+  HelpText<"Print the directory pathname containing clangs runtime libraries">,
+  Visibility<[ClangOption, CLOption]>;
 def print_diagnostic_options : Flag<["-", "--"], "print-diagnostic-options">,
-  HelpText<"Print all of Clang's warning options">;
+  HelpText<"Print all of Clang's warning options">,
+  Visibility<[ClangOption, CLOption]>;
 def private__bundle : Flag<["-"], "private_bundle">;
 def pthreads : Flag<["-"], "pthreads">;
 defm pthread : BoolOption<"", "pthread",
@@ -5227,7 +5240,7 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, CLOption, DXCOption]>,
   Alias<resource_dir>;
 def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>;
-def rtlib_EQ : Joined<["-", "--"], "rtlib=">,
+def rtlib_EQ : Joined<["-", "--"], "rtlib=">, Visibility<[ClangOption, CLOption]>,
   HelpText<"Compiler runtime library to use">;
 def frtlib_add_rpath: Flag<["-"], "frtlib-add-rpath">, Flags<[NoArgumentUnused]>,
   HelpText<"Add -rpath with architecture-specific resource directory to the linker flags. "
@@ -5393,7 +5406,7 @@ def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">,
   MarshallingInfoFlag<DiagnosticOpts<"IgnoreWarnings">>;
 def x : JoinedOrSeparate<["-"], "x">,
 Flags<[NoXarchOption]>,
-  Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+  Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, CLOption]>,
   HelpText<"Treat subsequent input files as having type <language>">,
   MetaVarName<"<language>">;
 def y : Joined<["-"], "y">;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 77328e1f99e5021..f5fd900a6447fe3 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2589,8 +2589,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
       Diag(clang::diag::note_drv_t_option_is_global);
   }
 
+  // CUDA/HIP and their preprocessor expansions can be accepted by CL mode.
   // Warn -x after last input file has no effect
-  if (!IsCLMode()) {
+  auto LastXArg = Args.getLastArgValue(options::OPT_x);
+  const llvm::StringSet<> ValidXArgs = {"cuda", "hip", "cui", "hipi"};
+  if (!IsCLMode() || ValidXArgs.find(LastXArg) != ValidXArgs.end()) {
     Arg *LastXArg = Args.getLastArgNoClaim(options::OPT_x);
     Arg *LastInputArg = Args.getLastArgNoClaim(options::OPT_INPUT);
     if (LastXArg && LastInputArg &&
diff --git a/clang/test/Driver/cl-offload.cu b/clang/test/Driver/cl-offload.cu
new file mode 100644
index 000000000000000..aa5c096338110b0
--- /dev/null
+++ b/clang/test/Driver/cl-offload.cu
@@ -0,0 +1,27 @@
+// RUN: %clang_cl -### --offload-arch=sm_35 -fgpu-rdc \
+// RUN:   --cuda-path=%S/Inputs/CUDA/usr/local/cuda \
+// RUN:   /Wall -x cuda %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CUDA
+
+// RUN: %clang_cl -### --offload-arch=gfx1010 -fgpu-rdc --hip-link \
+// RUN:   --rocm-path=%S/Inputs/rocm /Wall -x hip %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=HIP
+
+// CUDA: "-cc1" "-triple" "nvptx64-nvidia-cuda" "-aux-triple" "x86_64-pc-windows-msvc"
+// CUDA-SAME: "-Weverything"
+// CUDA: ptxas
+// CUDA: "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" "-aux-triple" "nvptx64-nvidia-cuda"
+// CUDA-SAME: "-Weverything"
+// CUDA: link
+
+// HIP: "-cc1" "-triple" "x86_64-pc-windows-msvc{{.*}}" "-aux-triple" "amdgcn-amd-amdhsa"
+// HIP-SAME: "-Weverything"
+// HIP: "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-pc-windows-msvc"
+// HIP-SAME: "-Weverything"
+// HIP: {{lld.* "-flavor" "gnu" "-m" "elf64_amdgpu"}}
+// HIP: {{link.* "amdhip64.lib"}}
+
+// CMake uses this option when finding packages for HIP, so
+// make sure it does not cause error.
+
+// RUN: %clang_cl --print-libgcc-file-name

@Artem-B Artem-B requested a review from rnk October 13, 2023 00:40
@Artem-B
Copy link
Member

Artem-B commented Oct 13, 2023

@rnk -- would that be acceptable for clang-cl on windows?

@yxsamliu
Copy link
Collaborator Author

The main objective is to make porting cmake files easier. Without it, you have to use clang-cl.exe to compile C++ and clang.exe to compile HIP since the options are not compatible. Now you can use clang-cl.exe to compile both, which accepts both MSVC options and clang options.

@yxsamliu
Copy link
Collaborator Author

ping. we tested it on Windows and it is able to compile both C++ and HIP without issues.

Copy link
Collaborator

@rnk rnk left a comment

Choose a reason for hiding this comment

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

Yep, we are fairly liberal about adding new clang options to the clang-cl mode, especially if they are in the feature -f flag namespace, which we believe will not conflict with MSVC flags.

@yxsamliu yxsamliu merged commit e880e8a into llvm:main Oct 19, 2023
@nico
Copy link
Contributor

nico commented Oct 20, 2023

Hello, it looks like this breaks check-clang on mac: http://45.33.8.238/macm1/71368/step_7.txt

Please take a look and revert for now if it takes a while to fix.

@yxsamliu
Copy link
Collaborator Author

yxsamliu commented Oct 20, 2023 via email

@yxsamliu
Copy link
Collaborator Author

yxsamliu commented Oct 20, 2023 via email

@rorth
Copy link
Collaborator

rorth commented Oct 23, 2023

This patch also broke the Solaris/amd64 buildbot. I suspect this happens because that one is configured with -DLLVM_TARGETS_TO_BUILD=X86, thus lacking cuda support. In fact, when manually building with support for all targets, the test PASSes. Please fix.

@yxsamliu
Copy link
Collaborator Author

yxsamliu commented Oct 23, 2023 via email

@statham-arm
Copy link
Collaborator

@yxsamliu I've just raised #70055 which fixes an issue with the new test here. Perhaps it might also allow you to remove the exclusion for system-darwin?

@yxsamliu
Copy link
Collaborator Author

@yxsamliu I've just raised #70055 which fixes an issue with the new test here. Perhaps it might also allow you to remove the exclusion for system-darwin?

Yes it should allow it to remove exclusion of system-darwin. Thanks

huangqinjin added a commit to huangqinjin/llvm-project that referenced this pull request Apr 23, 2024
After llvm#68921,
clang-cl gained option `-x` but only for CUDA/HIP.
This commit simply removes the restriction on parameters to `-x`.
Especially, it is able to use `-x c++-module` and `-x c++-user-header`
to build C++20 modules and header units with clang-cl.

This effectively reverts commit fe08212.

Closes llvm#88006.
huangqinjin added a commit to huangqinjin/llvm-project that referenced this pull request May 7, 2024
After llvm#68921,
clang-cl gained option `-x` but only for CUDA/HIP.
This commit simply removes the restriction on parameters to `-x`.
Especially, it is able to use `-x c++-module` and `-x c++-user-header`
to build C++20 modules and header units with clang-cl.

This effectively reverts commit fe08212.

Closes llvm#88006.
huangqinjin added a commit to huangqinjin/llvm-project that referenced this pull request May 22, 2024
After llvm#68921,
clang-cl gained option `-x` but only for CUDA/HIP.
This commit simply removes the restriction on parameters to `-x`.
Especially, it is able to use `-x c++-module` and `-x c++-system-header`
to build C++20 modules and header units with clang-cl.

This effectively reverts commit fe08212.

Closes llvm#88006.
MaskRay pushed a commit that referenced this pull request May 24, 2024
After #68921, clang-cl gained
option `-x` but only for CUDA/HIP. This commit simply removes the
restriction on parameters to `-x`. Especially, it is able to use `-x
c++-module` and `-x c++-system-header` to build C++20 modules and header
units with clang-cl.

This effectively reverts commit
fe08212.

Closes #88006.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants