[clang] [OpenMP][ASan][Driver] Update build steps for OpenMP ASan. (PR #179636)
Amit Kumar Pandey via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 16 21:39:45 PST 2026
https://github.com/ampandey-1995 updated https://github.com/llvm/llvm-project/pull/179636
>From 5bef6b574f43cbe7c2752a5389236a579a7a0bcd Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Wed, 4 Feb 2026 15:27:29 +0530
Subject: [PATCH 1/3] [OpenMP][ASan][Driver] Update build steps for OpenMP
ASan.
- Avoid linking asanrtl.bc at compile time. Symbols necessary for GPU
ASan functionality are provided via asanified 'libompdevice.a'
installed at `/opt/rocm/llvm/lib/asan`.
- Replace '-mlink-bitcode-file' to '-mlink-builtin-bitcode' in lit tests
for asanrtl.bc just like other bitcode libs.
---
clang/lib/Driver/ToolChain.cpp | 2 ++
clang/lib/Driver/ToolChains/AMDGPU.cpp | 29 ++++++++++++++-----
clang/lib/Driver/ToolChains/AMDGPU.h | 5 ++++
clang/lib/Driver/ToolChains/Clang.cpp | 1 +
.../Driver/amdgpu-openmp-sanitize-options.c | 4 +--
clang/test/Driver/hip-sanitize-options.hip | 24 +++++++--------
clang/test/Driver/rocm-device-libs.cl | 2 +-
7 files changed, 45 insertions(+), 22 deletions(-)
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 0eee7f917d2b8..e3b30c0ea1458 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1643,6 +1643,8 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {
Res |= SanitizerKind::MemTag;
if (getTriple().isBPF())
Res |= SanitizerKind::KernelAddress;
+ if (getTriple().isAMDGPU())
+ Res |= SanitizerKind::Address;
return Res;
}
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index ef5189359cd1a..dd2370ce891f2 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -629,6 +629,20 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Args.getLastArgValue(options::OPT_mcpu_EQ))));
}
addLinkerCompressDebugSectionsOption(getToolChain(), Args, CmdArgs);
+
+ // ASan instrumented OpenMP+Offload libraries are installed in default ROCm
+ // LLVM ASan custom path.
+ // Below code prepends the LLVM ASan custom path to pick ASan instrumented
+ // libompdevice.a.
+ const SanitizerArgs &SanArgs = getToolChain().getSanitizerArgs(Args);
+ if (SanArgs.needsAsanRt()) {
+ const AMDGPUToolChain &AMDGPU =
+ static_cast<const AMDGPUToolChain &>(getToolChain());
+ StringRef ASanPath = Args.MakeArgString(
+ AMDGPU.getRocmInstallationPath().str() + "/lib/llvm/lib/asan");
+ CmdArgs.push_back(Args.MakeArgString("-L" + ASanPath.str()));
+ }
+
getToolChain().AddFilePathLibArgs(Args, CmdArgs);
Args.AddAllArgs(CmdArgs, options::OPT_L);
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
@@ -1041,17 +1055,18 @@ RocmInstallationDetector::getCommonBitcodeLibs(
BCLib.ShouldInternalize = Internalize;
BCLibs.emplace_back(BCLib);
};
- auto AddSanBCLibs = [&]() {
- if (Pref.GPUSan)
- AddBCLib(getAsanRTLPath(), false);
- };
- AddSanBCLibs();
+ // For OpenMP, openmp-devicertl(libompdevice.a) already contains ASan GPU
+ // runtime and Ockl functions (via POST_BUILD). Don't add it again at driver
+ // level to avoid duplicates as most of the symbols have USED attribute and
+ // duplicates entries in llvm.compiler.used & llvm.used makes their
+ // duplicate definitions persist even with internalization enabled
+ if (Pref.GPUSan && !Pref.IsOpenMP)
+ // Add Gpu Sanitizer RTL bitcode lib required for AMDGPU Sanitizer
+ AddBCLib(getAsanRTLPath());
AddBCLib(getOCMLPath());
if (!Pref.IsOpenMP)
AddBCLib(getOCKLPath());
- else if (Pref.GPUSan && Pref.IsOpenMP)
- AddBCLib(getOCKLPath(), false);
AddBCLib(getUnsafeMathPath(Pref.UnsafeMathOpt || Pref.FastRelaxedMath));
AddBCLib(getFiniteOnlyPath(Pref.FiniteOnly || Pref.FastRelaxedMath));
AddBCLib(getCorrectlyRoundedSqrtPath(Pref.CorrectSqrt));
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 4dd8188842f83..6afa254952af7 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -98,6 +98,11 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
return true;
}
+ /// Get the ROCm installation path
+ StringRef getRocmInstallationPath() const {
+ return RocmInstallation->getInstallPath();
+ }
+
/// Needed for translating LTO options.
const char *getDefaultLinker() const override { return "ld.lld"; }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c16aa33f29ebb..ff4ba1a79349e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -9227,6 +9227,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
// compilation job.
const llvm::DenseSet<unsigned> CompilerOptions{
OPT_v,
+ OPT_fsanitize_EQ,
OPT_cuda_path_EQ,
OPT_rocm_path_EQ,
OPT_hip_path_EQ,
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index fd7d11803249c..fabb726329314 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -104,12 +104,12 @@
// HOSTSANCOMBINATION: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address,fuzzer,fuzzer-no-link".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "c".*}}
// HOSTSANCOMBINATION2: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address,fuzzer,fuzzer-no-link,leak".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "c".*}}
-// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-mlink-bitcode-file" "[^"]*asanrtl.bc".* "-mlink-bitcode-file" "[^"]*ockl.bc".* "-target-cpu" "(gfx908|gfx900|gfx1250|gfx1251)".* "-fopenmp".* "-fsanitize=address".* "-x" "c".*}}
+// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900|gfx1250|gfx1251)".* "-fopenmp".* "-fsanitize=address".* "-x" "c".*}}
// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-x" "c".*}}
// SAN: {{"[^"]*llvm-offload-binary[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=(gfx908|gfx1250|gfx1251)(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}}
// SAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "ir".*}}
-// SAN: {{"[^"]*clang-linker-wrapper[^"]*".* "--host-triple=x86_64-unknown-linux-gnu".* "--linker-path=[^"]*".* "--whole-archive" "[^"]*(libclang_rt.asan_static.a|libclang_rt.asan_static-x86_64.a)".* "--whole-archive" "[^"]*(libclang_rt.asan.a|libclang_rt.asan-x86_64.a)".*}}
+// SAN: {{"[^"]*clang-linker-wrapper[^"]*".* "--device-compiler=amdgcn-amd-amdhsa=-fsanitize=address".* "--host-triple=x86_64-unknown-linux-gnu".* "--linker-path=[^"]*".* "--whole-archive" "[^"]*(libclang_rt.asan_static.a|libclang_rt.asan_static-x86_64.a)".* "--whole-archive" "[^"]*(libclang_rt.asan.a|libclang_rt.asan-x86_64.a)".*}}
// UNSUPPORTEDERROR: error: '-fsanitize=leak' option is not currently supported for target 'amdgcn-amd-amdhsa'
// XNACKERROR: error: '-fsanitize=address' option for offload arch 'gfx908:xnack-' is not currently supported there. Use it with an offload arch containing 'xnack+' instead
diff --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip
index d436756ee046b..892c1c00bb1bc 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -98,16 +98,16 @@
// RUN: | FileCheck -check-prefixes=ERRSANCOV %s
// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-fsanitize=address"}}
-// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc"}}
+// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-mlink-builtin-bitcode" ".*asanrtl.bc"}}
// CHECK-NOT: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}}
// CHECK: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}}
-// NORDC: {{"[^"]*clang[^"]*".* "-emit-obj".* "-fcuda-is-device".* .* "-mlink-bitcode-file" ".*asanrtl.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.o]]"
+// NORDC: {{"[^"]*clang[^"]*".* "-emit-obj".* "-fcuda-is-device".* .* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.o]]"
// NORDC-NOT: {{"[^"]*lld(\.exe){0,1}".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}}
// NORDC: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}}
// RDC: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}}
-// RDC: {{"[^"]*clang[^"]*".* "-emit-llvm-bc".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]"
+// RDC: {{"[^"]*clang[^"]*".* "-emit-llvm-bc".* "-fcuda-is-device".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]"
// RDC-NOT: {{"[^"]*lld(\.exe){0,1}".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}}
// FAIL: error: cannot find ROCm device library for ABI version 5; provide its path via '--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build without ROCm device library
@@ -115,7 +115,7 @@
// XNACK-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
// XNACK-DAG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx900:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// XNACK-DAG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx906' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
-// XNACK-DAG: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
+// XNACK-DAG: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
// XNACK-DAG: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "-xnack"}}
// XNACK-DAG: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx906"}}
// XNACK-DAG: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address,leak"}}
@@ -124,8 +124,8 @@
// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx906".* "-fsanitize=address,leak"}}
// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "-xnack".* "-fsanitize=address"}}
// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx906".* "-fsanitize=address"}}
-// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "-xnack"}}
-// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx906"}}
+// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "-xnack"}}
+// XNACKNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx906"}}
// XNACKNEG-NOT: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}}
// NOGPU-DAG: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack"}}
@@ -135,21 +135,21 @@
// NOGPUNEG-NOT: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
// NOGPUNEG-NOT: warning: ignoring '-fsanitize=address' option for offload arch 'gfx900:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// NOGPUNEG-NOT: warning: ignoring '-fsanitize=address' option for offload arch 'gfx906' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
-// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
+// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address,leak"}}
// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "-xnack".* "-fsanitize=address,leak"}}
// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx906".* "-fsanitize=address,leak"}}
// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx900".* "-target-feature" "-xnack".* "-fsanitize=address"}}
// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx906".* "-fsanitize=address"}}
-// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack"}}
-// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "-xnack"}}
-// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx906"}}
+// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack"}}
+// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "-xnack"}}
+// NOGPUNEG-NOT: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx906"}}
// NOGPUNEG-NOT: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}}
// INVALIDCOMBINATION1-DAG: warning: ignoring 'fuzzer' in '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
// INVALIDCOMBINATION2-DAG: warning: ignoring 'fuzzer' in '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
-// INVALIDCOMBINATION-DAG: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
+// INVALIDCOMBINATION-DAG: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
// INVALIDCOMBINATION-DAG: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address,fuzzer,fuzzer-no-link"}}
// MULT1-DAG: warning: ignoring 'fuzzer' in '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
@@ -164,7 +164,7 @@
// MULT2-DAG: warning: ignoring '-fsanitize=fuzzer,address' option for offload arch 'gfx908:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead [-Woption-ignored]
// MULT2-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
-// XNACK2-DAG: {{"[^"]*clang[^"]*".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
+// XNACK2-DAG: {{"[^"]*clang[^"]*".* "-mlink-builtin-bitcode" ".*asanrtl.bc".* "-target-cpu" "gfx900".* "-target-feature" "\+xnack".* "-fsanitize=address"}}
// XNACK2-DAG: {{"[^"]*clang[^"]*".* "-target-cpu" "gfx908"}}
// XNACK2-DAG: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address,fuzzer,fuzzer-no-link,leak"}}
diff --git a/clang/test/Driver/rocm-device-libs.cl b/clang/test/Driver/rocm-device-libs.cl
index e77a6a07315ad..c8541f28c4a80 100644
--- a/clang/test/Driver/rocm-device-libs.cl
+++ b/clang/test/Driver/rocm-device-libs.cl
@@ -158,7 +158,7 @@
// COMMON: "-triple" "amdgcn-amd-amdhsa"
// COMMON-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/opencl.bc"
-// ASAN-SAME: "-mlink-bitcode-file" "{{.*}}/amdgcn/bitcode/asanrtl.bc"
+// ASAN-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/asanrtl.bc"
// COMMON-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/ocml.bc"
// COMMON-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/ockl.bc"
>From 2f914191ee605b300d0948fd14918dff72cd3d47 Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Mon, 16 Feb 2026 12:21:10 +0530
Subject: [PATCH 2/3] Support OpenMP ASan libraries detection via
RocmInstallationDetector.
- Add 'detectOpenMPRuntime' method in RocmInstallationDetector.h.
- Initializes 'OpenMPASanRTLPath' after successfull RocmInstallation
Detection.
- Pass forward '-fsantize=address' to device compiler.
- Add helper utility 'checkAndAddAMDGPUSanLibPaths' to initialize the
standard `FilePath` arguments with ASan library path.
---
.../clang/Driver/RocmInstallationDetector.h | 10 +++-
clang/lib/Driver/ToolChains/AMDGPU.cpp | 49 +++++++++++++------
clang/lib/Driver/ToolChains/AMDGPU.h | 7 +--
3 files changed, 45 insertions(+), 21 deletions(-)
diff --git a/clang/include/clang/Driver/RocmInstallationDetector.h b/clang/include/clang/Driver/RocmInstallationDetector.h
index 488d9e7d40587..cbf5c9a7f0b46 100644
--- a/clang/include/clang/Driver/RocmInstallationDetector.h
+++ b/clang/include/clang/Driver/RocmInstallationDetector.h
@@ -142,6 +142,9 @@ class RocmInstallationDetector {
// Asan runtime library
SmallString<0> AsanRTL;
+ // OpenMP ASan runtime library
+ SmallString<0> OpenMPASanRTLPath;
+
// Libraries swapped based on compile flags.
ConditionalLibrary WavefrontSize64;
ConditionalLibrary FiniteOnly;
@@ -177,8 +180,8 @@ class RocmInstallationDetector {
public:
RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args,
- bool DetectHIPRuntime = true);
-
+ bool DetectHIPRuntime = true,
+ bool DetectOpenMPRuntime = true);
/// Get file paths of default bitcode libraries common to AMDGPU based
/// toolchains.
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
@@ -239,6 +242,8 @@ class RocmInstallationDetector {
/// Returns empty string of Asan runtime library is not available.
StringRef getAsanRTLPath() const { return AsanRTL; }
+ StringRef getOpenMPASanRTLPath() const { return OpenMPASanRTLPath; }
+
StringRef getWavefrontSize64Path(bool Enabled) const {
return WavefrontSize64.get(Enabled);
}
@@ -275,6 +280,7 @@ class RocmInstallationDetector {
void detectDeviceLibrary();
void detectHIPRuntime();
+ void detectOpenMPRuntime();
/// Get the values for --rocm-device-lib-path arguments
ArrayRef<std::string> getRocmDeviceLibPathArg() const {
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index dd2370ce891f2..a6360f5ddfa5d 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -323,7 +323,8 @@ RocmInstallationDetector::getInstallationPathCandidates() {
RocmInstallationDetector::RocmInstallationDetector(
const Driver &D, const llvm::Triple &HostTriple,
- const llvm::opt::ArgList &Args, bool DetectHIPRuntime)
+ const llvm::opt::ArgList &Args, bool DetectHIPRuntime,
+ bool DetectOpenMPRuntime)
: D(D) {
Verbose = Args.hasArg(options::OPT_v);
RocmPathArg = Args.getLastArgValue(options::OPT_rocm_path_EQ);
@@ -377,6 +378,25 @@ RocmInstallationDetector::RocmInstallationDetector(
if (DetectHIPRuntime)
detectHIPRuntime();
+ if (DetectOpenMPRuntime)
+ detectOpenMPRuntime();
+}
+
+void RocmInstallationDetector::detectOpenMPRuntime() {
+ assert(OpenMPASanRTLPath.empty());
+ // Set OpenMP ASan library directory path for pre-instrumented device
+ // libraries (e.g., libompdevice.a). This path is used when linking with
+ // -fsanitize=address for OpenMP offloading.
+ OpenMPASanRTLPath = llvm::sys::path::parent_path(D.Dir);
+ llvm::sys::path::append(OpenMPASanRTLPath, "lib", "asan");
+ if (D.getVFS().exists(OpenMPASanRTLPath))
+ return;
+ // Fallback: Search ASan libs in the ROCm tree (e.g. /opt/rocm/llvm/lib/asan).
+ const auto &Candidates = getInstallationPathCandidates();
+ if (Candidates.empty())
+ return;
+ OpenMPASanRTLPath = Candidates.front().Path;
+ llvm::sys::path::append(OpenMPASanRTLPath, "lib", "llvm", "lib", "asan");
}
void RocmInstallationDetector::detectDeviceLibrary() {
@@ -630,19 +650,6 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
addLinkerCompressDebugSectionsOption(getToolChain(), Args, CmdArgs);
- // ASan instrumented OpenMP+Offload libraries are installed in default ROCm
- // LLVM ASan custom path.
- // Below code prepends the LLVM ASan custom path to pick ASan instrumented
- // libompdevice.a.
- const SanitizerArgs &SanArgs = getToolChain().getSanitizerArgs(Args);
- if (SanArgs.needsAsanRt()) {
- const AMDGPUToolChain &AMDGPU =
- static_cast<const AMDGPUToolChain &>(getToolChain());
- StringRef ASanPath = Args.MakeArgString(
- AMDGPU.getRocmInstallationPath().str() + "/lib/llvm/lib/asan");
- CmdArgs.push_back(Args.MakeArgString("-L" + ASanPath.str()));
- }
-
getToolChain().AddFilePathLibArgs(Args, CmdArgs);
Args.AddAllArgs(CmdArgs, options::OPT_L);
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
@@ -727,12 +734,26 @@ AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
// It is done here to avoid repeated warning or error messages for
// each tool invocation.
checkAMDGPUCodeObjectVersion(D, Args);
+ // When ASan is enabled, setup ASan library path configuration early so that
+ // the linker finds ASan-instrumented libraries.
+ checkAndAddAMDGPUSanLibPaths(Args);
}
Tool *AMDGPUToolChain::buildLinker() const {
return new tools::amdgpu::Linker(*this);
}
+// Common function to check and add ASan library paths.
+void AMDGPUToolChain::checkAndAddAMDGPUSanLibPaths(const ArgList &Args) {
+ // For OpenMP: when ASan is enabled, prepend the OpenMP ASan library path so
+ // the linker finds ASan-instrumented libraries.
+ if (getSanitizerArgs(Args).needsAsanRt()) {
+ StringRef OmpASanPath = RocmInstallation->getOpenMPASanRTLPath();
+ if (!OmpASanPath.empty() && getVFS().exists(OmpASanPath))
+ getFilePaths().insert(getFilePaths().begin(), OmpASanPath.str());
+ }
+}
+
DerivedArgList *
AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const {
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 6afa254952af7..b0fc5eeeb9f76 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -98,11 +98,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
return true;
}
- /// Get the ROCm installation path
- StringRef getRocmInstallationPath() const {
- return RocmInstallation->getInstallPath();
- }
-
/// Needed for translating LTO options.
const char *getDefaultLinker() const override { return "ld.lld"; }
@@ -117,6 +112,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
virtual Expected<SmallVector<std::string>>
getSystemGPUArchs(const llvm::opt::ArgList &Args) const override;
+ void checkAndAddAMDGPUSanLibPaths(const llvm::opt::ArgList &Args);
+
protected:
/// Check and diagnose invalid target ID specified by -mcpu.
virtual void checkTargetID(const llvm::opt::ArgList &DriverArgs) const;
>From 4ced4e7119f4097cc834154f8ae32448e798f88b Mon Sep 17 00:00:00 2001
From: Amit Pandey <pandey.kumaramit2023 at gmail.com>
Date: Mon, 16 Feb 2026 22:19:30 +0530
Subject: [PATCH 3/3] Fix Lit test.
Clang run lines jobs which emit error diagnostic has non-zero exit
status. Fix 'amdgpu-openmp-sanitize-options.c' &
'hip-sanitize-options.hip' having run lines which emit error diagnostic
by prepending 'not' before clang invocation.
---
clang/test/Driver/amdgpu-openmp-sanitize-options.c | 12 ++++++------
clang/test/Driver/hip-sanitize-options.hip | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index fabb726329314..a496d1946cf1b 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -9,7 +9,7 @@
// RUN: | FileCheck --check-prefixes=NOTSUPPORTED,FAIL %s
// Memory, Leak, UndefinedBehaviour and Thread Sanitizer are not supported on AMDGPU.
-// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fsanitize=leak -fgpu-sanitize --rocm-path=%S/Inputs/rocm -nogpuinc %s 2>&1 \
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fsanitize=leak -fgpu-sanitize --rocm-path=%S/Inputs/rocm -nogpuinc %s 2>&1 \
// RUN: | FileCheck --check-prefix=NOTSUPPORTED %s
// GPU ASan Enabled Test Cases
@@ -58,18 +58,18 @@
// implicitly turns on LLVMs SanitizerCoverage, which the driver then forwards
// to the device cc1. SanitizerCoverage is not supported on amdgcn.)
-// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSANCOMBINATION,INVALIDCOMBINATION1 %s
-// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSANCOMBINATION,INVALIDCOMBINATION2 %s
// Do the same for multiple -fsanitize arguments and multi-arch scenarios.
-// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack- -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack- -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSANCOMBINATION,INVALIDCOMBINATION1 %s
-// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+,gfx900:xnack- -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+,gfx900:xnack- -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSANCOMBINATION,INVALIDCOMBINATION1 %s
-// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+,gfx900:xnack- -fsanitize=fuzzer,address -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+,gfx900:xnack- -fsanitize=fuzzer,address -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSANCOMBINATION2,NOTSUPPORTED-DAG,INVALIDCOMBINATION2 %s
// Check for -fsanitize-coverage options
diff --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip
index 892c1c00bb1bc..ccbf29d7904bb 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -58,19 +58,19 @@
// implicitly turns on LLVMs SanitizerCoverage, which the driver then forwards
// to the device cc1. SanitizerCoverage is not supported on amdgcn.)
-// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
// RUN: -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATION,INVALIDCOMBINATION1 %s
-// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
// RUN: -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATION,INVALIDCOMBINATION2 %s
// Do the same for multiple -fsanitize arguments and multi-arch scenarios.
-// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ --offload-arch=gfx908:xnack- \
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ --offload-arch=gfx908:xnack- \
// RUN: -fsanitize=address,fuzzer -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=MULT1,XNACK2 %s
-// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+,gfx908:xnack- \
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+,gfx908:xnack- \
// RUN: -fsanitize=fuzzer,address -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=MULT2,XNACK2 %s
More information about the cfe-commits
mailing list