[clang] [Clang] Add a flag to include GPU startup files (PR #112025)

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 25 16:36:47 PDT 2024


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/112025

>From a02a27171801ad3f5618099b5035ef8185c2f835 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 11 Oct 2024 12:21:49 -0500
Subject: [PATCH 1/4] [Clang] Add a flag to include GPU startup files

Summary:
The C library for GPUs provides the ability to target regular C/C++
programs by providing the C library and a file containing kernels that
call the `main` function. This is mostly used for unit tests, this patch
provides a quick way to add them without needing to know the paths. I
currently do this explicitly, but according to the libc++ contributors
we don't want to need to specify these paths manually. See the
discussion in https://github.com/llvm/llvm-project/pull/104515.

I just default to `lib/` if the target-specific one isn't found because
the linker will handle giving a reasonable error message if it's not
found. Basically the use-case looks like this.

```console
$ clang test.c --target=amdgcn-amd-amdhsa -mcpu=native -gpustartfiles
$ amdhsa-loader a.out
PASS!
```
---
 clang/include/clang/Driver/Options.td  | 3 +++
 clang/lib/Driver/ToolChains/AMDGPU.cpp | 9 +++++++++
 clang/lib/Driver/ToolChains/Cuda.cpp   | 9 +++++++++
 clang/test/Driver/gpustartfiles.c      | 7 +++++++
 4 files changed, 28 insertions(+)
 create mode 100644 clang/test/Driver/gpustartfiles.c

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 379e75b197cf96..3583f46a972314 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1316,6 +1316,9 @@ defm offload_via_llvm : BoolFOption<"offload-via-llvm",
   BothFlags<[], [ClangOption], " LLVM/Offload as portable offloading runtime.">>;
 }
 
+def gpustartfiles : Flag<["-"], "gpustartfiles">, Group<Link_Group>,
+  HelpText<"Link the GPU C startup utilities automatically, used for testing.">;
+
 // CUDA options
 let Group = cuda_Group in {
 def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">,
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 2c85d21ebd738c..9a648be4ea3915 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -648,6 +648,15 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
         Args.MakeArgString("-plugin-opt=-mattr=" + llvm::join(Features, ",")));
   }
 
+  if (Args.hasArg(options::OPT_gpustartfiles)) {
+    auto IncludePath = getToolChain().getStdlibPath();
+    if (!IncludePath)
+      IncludePath = "/lib";
+    SmallString<128> P(*IncludePath);
+    llvm::sys::path::append(P, "crt1.o");
+    CmdArgs.append({"-lc", "-lm", Args.MakeArgString(P)});
+  }
+
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
   C.addCommand(std::make_unique<Command>(
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index b368c473756731..20ec010ade04cb 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -643,6 +643,15 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
   CmdArgs.push_back(Args.MakeArgString(Twine("-L") + DefaultLibPath));
 
+  if (Args.hasArg(options::OPT_gpustartfiles)) {
+    auto IncludePath = getToolChain().getStdlibPath();
+    if (!IncludePath)
+      IncludePath = "/lib";
+    SmallString<128> P(*IncludePath);
+    llvm::sys::path::append(P, "crt1.o");
+    CmdArgs.append({"-lc", "-lm", Args.MakeArgString(P)});
+  }
+
   C.addCommand(std::make_unique<Command>(
       JA, *this,
       ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
diff --git a/clang/test/Driver/gpustartfiles.c b/clang/test/Driver/gpustartfiles.c
new file mode 100644
index 00000000000000..c1b7a6fa922df4
--- /dev/null
+++ b/clang/test/Driver/gpustartfiles.c
@@ -0,0 +1,7 @@
+// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_61 -gpustartfiles \
+// RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=NVPTX %s
+// NVPTX: clang-nvlink-wrapper{{.*}}"-lc" "-lm" "{{.*}}crt1.o"
+//
+// RUN: %clang -target amdgcn-amd-amdhsa -march=gfx90a -gpustartfiles \
+// RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=AMDGPU %s
+// AMDGPU: ld.lld{{.*}}"-lc" "-lm" "{{.*}}crt1.o"

>From 6ccba0250b564045c71ac693c2caf196ab993b1a Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 11 Oct 2024 12:52:49 -0500
Subject: [PATCH 2/4] Add -startfiles -stdlib positive versions for GPU

---
 clang/include/clang/Driver/Options.td  | 7 ++++---
 clang/lib/Driver/ToolChains/AMDGPU.cpp | 6 ++++--
 clang/lib/Driver/ToolChains/Cuda.cpp   | 6 ++++--
 clang/test/Driver/gpustartfiles.c      | 4 ++--
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 3583f46a972314..a10330e992d016 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1316,9 +1316,6 @@ defm offload_via_llvm : BoolFOption<"offload-via-llvm",
   BothFlags<[], [ClangOption], " LLVM/Offload as portable offloading runtime.">>;
 }
 
-def gpustartfiles : Flag<["-"], "gpustartfiles">, Group<Link_Group>,
-  HelpText<"Link the GPU C startup utilities automatically, used for testing.">;
-
 // CUDA options
 let Group = cuda_Group in {
 def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">,
@@ -5615,6 +5612,7 @@ def noprebind : Flag<["-"], "noprebind">;
 def noprofilelib : Flag<["-"], "noprofilelib">;
 def noseglinkedit : Flag<["-"], "noseglinkedit">;
 def nostartfiles : Flag<["-"], "nostartfiles">, Group<Link_Group>;
+def startfiles : Flag<["-"], "startfiles">, Group<Link_Group>;
 def nostdinc : Flag<["-"], "nostdinc">,
   Visibility<[ClangOption, CLOption, DXCOption]>, Group<IncludePath_Group>,
   HelpText<"Disable both standard system #include directories and builtin #include directories">;
@@ -5627,6 +5625,9 @@ def nostdincxx : Flag<["-"], "nostdinc++">, Visibility<[ClangOption, CC1Option]>
 def nostdlib : Flag<["-"], "nostdlib">,
   Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
   Group<Link_Group>;
+def stdlib : Flag<["-"], "stdlib">,
+  Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>,
+  Group<Link_Group>;
 def nostdlibxx : Flag<["-"], "nostdlib++">;
 def object : Flag<["-"], "object">;
 def o : JoinedOrSeparate<["-"], "o">,
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 9a648be4ea3915..301f4855c9f250 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -648,13 +648,15 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
         Args.MakeArgString("-plugin-opt=-mattr=" + llvm::join(Features, ",")));
   }
 
-  if (Args.hasArg(options::OPT_gpustartfiles)) {
+  if (Args.hasArg(options::OPT_stdlib))
+    CmdArgs.append({"-lc", "-lm"});
+  if (Args.hasArg(options::OPT_startfiles)) {
     auto IncludePath = getToolChain().getStdlibPath();
     if (!IncludePath)
       IncludePath = "/lib";
     SmallString<128> P(*IncludePath);
     llvm::sys::path::append(P, "crt1.o");
-    CmdArgs.append({"-lc", "-lm", Args.MakeArgString(P)});
+    CmdArgs.push_back(Args.MakeArgString(P));
   }
 
   CmdArgs.push_back("-o");
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 20ec010ade04cb..a5c59ad21a9b3f 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -643,13 +643,15 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
   CmdArgs.push_back(Args.MakeArgString(Twine("-L") + DefaultLibPath));
 
-  if (Args.hasArg(options::OPT_gpustartfiles)) {
+  if (Args.hasArg(options::OPT_stdlib))
+    CmdArgs.append({"-lc", "-lm"});
+  if (Args.hasArg(options::OPT_startfiles)) {
     auto IncludePath = getToolChain().getStdlibPath();
     if (!IncludePath)
       IncludePath = "/lib";
     SmallString<128> P(*IncludePath);
     llvm::sys::path::append(P, "crt1.o");
-    CmdArgs.append({"-lc", "-lm", Args.MakeArgString(P)});
+    CmdArgs.push_back(Args.MakeArgString(P));
   }
 
   C.addCommand(std::make_unique<Command>(
diff --git a/clang/test/Driver/gpustartfiles.c b/clang/test/Driver/gpustartfiles.c
index c1b7a6fa922df4..35dac09f658c90 100644
--- a/clang/test/Driver/gpustartfiles.c
+++ b/clang/test/Driver/gpustartfiles.c
@@ -1,7 +1,7 @@
-// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_61 -gpustartfiles \
+// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_61 -stdlib -startfiles \
 // RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=NVPTX %s
 // NVPTX: clang-nvlink-wrapper{{.*}}"-lc" "-lm" "{{.*}}crt1.o"
 //
-// RUN: %clang -target amdgcn-amd-amdhsa -march=gfx90a -gpustartfiles \
+// RUN: %clang -target amdgcn-amd-amdhsa -march=gfx90a -stdlib -startfiles \
 // RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=AMDGPU %s
 // AMDGPU: ld.lld{{.*}}"-lc" "-lm" "{{.*}}crt1.o"

>From c1ec9bcf815eab8e775af8c441885301603b8ded Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 11 Oct 2024 12:55:01 -0500
Subject: [PATCH 3/4] move test

---
 clang/test/Driver/amdgpu-toolchain.c     | 4 ++++
 clang/test/Driver/cuda-cross-compiling.c | 4 ++++
 clang/test/Driver/gpustartfiles.c        | 7 -------
 3 files changed, 8 insertions(+), 7 deletions(-)
 delete mode 100644 clang/test/Driver/gpustartfiles.c

diff --git a/clang/test/Driver/amdgpu-toolchain.c b/clang/test/Driver/amdgpu-toolchain.c
index b60d31bae62700..c1c5aa8e90e686 100644
--- a/clang/test/Driver/amdgpu-toolchain.c
+++ b/clang/test/Driver/amdgpu-toolchain.c
@@ -32,3 +32,7 @@
 // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \
 // RUN:   -r %s 2>&1 | FileCheck -check-prefixes=RELO %s
 // RELO-NOT: -shared
+
+// RUN: %clang -target amdgcn-amd-amdhsa -march=gfx90a -stdlib -startfiles \
+// RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=STARTUP %s
+// STARTUP: ld.lld{{.*}}"-lc" "-lm" "{{.*}}crt1.o"
diff --git a/clang/test/Driver/cuda-cross-compiling.c b/clang/test/Driver/cuda-cross-compiling.c
index 5f24e7a5accb08..04c5abd305950d 100644
--- a/clang/test/Driver/cuda-cross-compiling.c
+++ b/clang/test/Driver/cuda-cross-compiling.c
@@ -105,3 +105,7 @@
 // RUN:   | FileCheck -check-prefix=FEATURE %s
 
 // FEATURE: clang-nvlink-wrapper{{.*}}"--feature" "+ptx63"
+
+// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_61 -stdlib -startfiles \
+// RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=STARTUP %s
+// STARTUP: clang-nvlink-wrapper{{.*}}"-lc" "-lm" "{{.*}}crt1.o"
diff --git a/clang/test/Driver/gpustartfiles.c b/clang/test/Driver/gpustartfiles.c
deleted file mode 100644
index 35dac09f658c90..00000000000000
--- a/clang/test/Driver/gpustartfiles.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_61 -stdlib -startfiles \
-// RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=NVPTX %s
-// NVPTX: clang-nvlink-wrapper{{.*}}"-lc" "-lm" "{{.*}}crt1.o"
-//
-// RUN: %clang -target amdgcn-amd-amdhsa -march=gfx90a -stdlib -startfiles \
-// RUN:   -nogpulib -nogpuinc -### %s 2>&1 | FileCheck -check-prefix=AMDGPU %s
-// AMDGPU: ld.lld{{.*}}"-lc" "-lm" "{{.*}}crt1.o"

>From 79d1432e1dafcc4ca7a1cbd04ec2c7a93bedf7cb Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 25 Oct 2024 18:36:37 -0500
Subject: [PATCH 4/4] Update AMDGPU.cpp

---
 clang/lib/Driver/ToolChains/AMDGPU.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 301f4855c9f250..a8061ffd9321f5 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -651,7 +651,7 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   if (Args.hasArg(options::OPT_stdlib))
     CmdArgs.append({"-lc", "-lm"});
   if (Args.hasArg(options::OPT_startfiles)) {
-    auto IncludePath = getToolChain().getStdlibPath();
+    std::optional<std::string> IncludePath = getToolChain().getStdlibPath();
     if (!IncludePath)
       IncludePath = "/lib";
     SmallString<128> P(*IncludePath);



More information about the cfe-commits mailing list