[clang] [clang] Skip host default include paths for GPU triples (PR #192821)

via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 18 20:14:05 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Yaxun (Sam) Liu (yxsamliu)

<details>
<summary>Changes</summary>

GPU compiles are freestanding. They should not search the host system's
`/usr/include` or `/usr/local/include` by default.

A concrete example is

  clang --target=amdgcn-amd-amdhsa -ffreestanding -nogpulib -c foo.c

If `foo.c` contains `#include <string.h>`, Clang should not read the host
header `/usr/include/string.h`. That header belongs to the host libc, not
to the GPU target. On current `main`, however, GPU triples still fall
through to the generic default-include logic, so host include paths are
added and builds can fail on host-only headers such as
`bits/libc-header-start.h`.

Fix this in two parts:

1. In `InitHeaderSearch`, treat all GPU triples (`triple.isGPU()`) like
   other targets whose include paths are managed by the driver, and skip
   the generic host default-include fallback.
2. In the AMDGPU and NVPTX toolchains, add clang's resource-directory
   builtin headers explicitly (`stddef.h`, `float.h`, `stdint.h`, ...).
   These are still needed, but they should come from clang's builtin
   header directory, not from the host libc.

Add a lit test that checks the printed include search list for GPU
triples and verifies that `/usr/include` and `/usr/local/include` are
not present.

Related: PR #<!-- -->177665.



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


4 Files Affected:

- (modified) clang/lib/Driver/ToolChains/AMDGPU.cpp (+15-2) 
- (modified) clang/lib/Driver/ToolChains/Cuda.cpp (+15-2) 
- (modified) clang/lib/Lex/InitHeaderSearch.cpp (+10) 
- (added) clang/test/Preprocessor/gpu-targets-no-host-default-includes.c (+19) 


``````````diff
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index ff4c781d51348..e229635745dc9 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -879,8 +879,21 @@ void AMDGPUToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
 
 void AMDGPUToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                                 ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
-      DriverArgs.hasArg(options::OPT_nostdlibinc))
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  // Add clang's builtin headers (`stddef.h`, `float.h`, `stdint.h`, ...).
+  // These are compiler-provided headers, not host libc headers.
+  //
+  // Example: an amdgcn compile may still need `float.h`, but it should come
+  // from clang's resource directory, not from the host system's `/usr/include`.
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> ResourceDirInclude(getDriver().ResourceDir);
+    llvm::sys::path::append(ResourceDirInclude, "include");
+    addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
   // Add multilib variant include paths in priority order.
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index dcde82cdf4d85..7c248e3c433f9 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -790,8 +790,21 @@ void NVPTXToolChain::addClangTargetOptions(
 
 void NVPTXToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                                ArgStringList &CC1Args) const {
-  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
-      DriverArgs.hasArg(options::OPT_nostdlibinc))
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  // Add clang's builtin headers (`stddef.h`, `float.h`, `stdint.h`, ...).
+  // These are compiler-provided headers, not host libc headers.
+  //
+  // Example: an nvptx compile may still need `float.h`, but it should come
+  // from clang's resource directory, not from the host system's `/usr/include`.
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    SmallString<128> ResourceDirInclude(getDriver().ResourceDir);
+    llvm::sys::path::append(ResourceDirInclude, "include");
+    addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
   // Add multilib variant include paths in priority order.
diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp
index e894086b66e76..7204602dc5514 100644
--- a/clang/lib/Lex/InitHeaderSearch.cpp
+++ b/clang/lib/Lex/InitHeaderSearch.cpp
@@ -210,6 +210,16 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
 
 bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
     const llvm::Triple &triple) {
+  // GPU targets are freestanding, so they should not search the host system's
+  // `/usr/include` or `/usr/local/include`.
+  //
+  // Example: `clang --target=amdgcn-amd-amdhsa -ffreestanding -nogpulib`
+  // compiling a file with `#include <string.h>` should not read the host
+  // glibc header `/usr/include/string.h`. GPU toolchains add their own include
+  // paths explicitly, so skip the generic host fallback here.
+  if (triple.isGPU())
+    return false;
+
   switch (triple.getOS()) {
   case llvm::Triple::AIX:
   case llvm::Triple::DragonFly:
diff --git a/clang/test/Preprocessor/gpu-targets-no-host-default-includes.c b/clang/test/Preprocessor/gpu-targets-no-host-default-includes.c
new file mode 100644
index 0000000000000..952c4b98c0fe9
--- /dev/null
+++ b/clang/test/Preprocessor/gpu-targets-no-host-default-includes.c
@@ -0,0 +1,19 @@
+// Check that GPU targets do not get the host system's default C include
+// paths (e.g. /usr/include, /usr/local/include) appended to the search list.
+// GPU toolchains are freestanding and manage their own include paths.
+//
+// Use `-v -E` on the source with `-nogpulib` to print the toolchain's
+// include search list and verify the host paths are absent.
+
+// RUN: %clang --target=amdgcn-amd-amdhsa -nogpulib -v -E -x c %s \
+// RUN:   -o /dev/null 2>&1 | FileCheck %s
+
+// RUN: %clang --target=amdgcn--amdhsa -nogpulib -v -E -x c %s \
+// RUN:   -o /dev/null 2>&1 | FileCheck %s
+
+// RUN: %clang --target=nvptx64-nvidia-cuda -nogpulib -nogpuinc -v -E -x c %s \
+// RUN:   -o /dev/null 2>&1 | FileCheck %s
+
+// CHECK-NOT: /usr/include{{$}}
+// CHECK-NOT: /usr/local/include{{$}}
+// CHECK:     End of search list.

``````````

</details>


https://github.com/llvm/llvm-project/pull/192821


More information about the cfe-commits mailing list