[clang] [AMDGPU][clang] Fix clang driver check for multiple sanitizer arguments (PR #166851)
Robert Imschweiler via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 17 04:26:02 PST 2025
https://github.com/ro-i updated https://github.com/llvm/llvm-project/pull/166851
>From bc0aad0726eda18a9aa984f6e16dcd25580aef86 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Thu, 6 Nov 2025 15:36:50 -0600
Subject: [PATCH 1/7] [AMDGPU][clang] Fix clang driver check for multiple
sanitizer arguments
`-fsanitize=address,fuzzer` should be rejected like
`-fsanitize=fuzzer,address`.
The address sanitizer enables the device sanitizer pipeline. The fuzzer
implicitly turns on LLVMs SanitizerCoverage, which the driver then
forwards to the device cc1. SanitizerCoverage is not supported on
amdgcn.
---
clang/lib/Driver/ToolChains/AMDGPU.cpp | 8 +++++---
clang/lib/Driver/ToolChains/AMDGPU.h | 12 +++++++-----
clang/test/Driver/amdgpu-openmp-sanitize-options.c | 13 +++++++++++++
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 1a243fef9532d..2f6ad4c4fa327 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1092,9 +1092,11 @@ bool AMDGPUToolChain::shouldSkipSanitizeOption(
auto &Diags = TC.getDriver().getDiags();
// For simplicity, we only allow -fsanitize=address
- SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false);
- if (K != SanitizerKind::Address)
- return true;
+ for (const char *Value : A->getValues()) {
+ SanitizerMask K = parseSanitizerValue(Value, /*AllowGroups=*/false);
+ if (K != SanitizerKind::Address)
+ return true;
+ }
// Check 'xnack+' availability by default
llvm::StringRef Processor =
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index e90a5736911e4..c5680a9d486bd 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -161,11 +161,13 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
return;
auto &Diags = getDriver().getDiags();
for (auto *A : Args.filtered(options::OPT_fsanitize_EQ)) {
- SanitizerMask K =
- parseSanitizerValue(A->getValue(), /*Allow Groups*/ false);
- if (K != SanitizerKind::Address)
- Diags.Report(clang::diag::warn_drv_unsupported_option_for_target)
- << A->getAsString(Args) << getTriple().str();
+ for (const char *Value : A->getValues()) {
+ SanitizerMask K =
+ parseSanitizerValue(Value, /*Allow Groups*/ false);
+ if (K != SanitizerKind::Address)
+ Diags.Report(clang::diag::warn_drv_unsupported_option_for_target)
+ << A->getAsString(Args) << getTriple().str();
+ }
}
}
};
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index 10d64984918e6..59ecbcf7b35ba 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -52,6 +52,18 @@
// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack+ -fsanitize=address -fno-gpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSAN,NOGPUSAN,SAN %s
+// Catch invalid combination of sanitizers regardless of their order.
+// The address sanitizer enables the device sanitizer pipeline. The fuzzer
+// 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: | 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: | FileCheck -check-prefixes=HOSTSANCOMBINATION,INVALIDCOMBINATION2 %s
+
+// INVALIDCOMBINATION1: warning: ignoring '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// INVALIDCOMBINATION2: warning: ignoring '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+
// FAIL-DAG: 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
// NOTSUPPORTED-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
@@ -59,6 +71,7 @@
// XNACKNEG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// HOSTSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "c".*}}
+// HOSTSANCOMBINATION: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address,fuzzer,fuzzer-no-link".* "--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".*}}
// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-x" "c".*}}
>From e2a11d36551fccd16ad5e96c76a0a0e1f70cc959 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Thu, 6 Nov 2025 15:44:06 -0600
Subject: [PATCH 2/7] fix formatting
---
clang/lib/Driver/ToolChains/AMDGPU.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index c5680a9d486bd..95d2a53ed5be8 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -162,8 +162,7 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
auto &Diags = getDriver().getDiags();
for (auto *A : Args.filtered(options::OPT_fsanitize_EQ)) {
for (const char *Value : A->getValues()) {
- SanitizerMask K =
- parseSanitizerValue(Value, /*Allow Groups*/ false);
+ SanitizerMask K = parseSanitizerValue(Value, /*Allow Groups*/ false);
if (K != SanitizerKind::Address)
Diags.Report(clang::diag::warn_drv_unsupported_option_for_target)
<< A->getAsString(Args) << getTriple().str();
>From cfa15f4c389aa97fdab748a147119be561799b31 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 7 Nov 2025 08:09:11 -0600
Subject: [PATCH 3/7] ignore sanitizers selectively
---
clang/lib/Driver/ToolChains/AMDGPU.cpp | 22 +++++++++++--------
clang/lib/Driver/ToolChains/AMDGPU.h | 16 ++++++++------
clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp | 14 +++++++-----
clang/lib/Driver/ToolChains/HIPAMD.cpp | 12 +++++++++-
.../Driver/amdgpu-openmp-sanitize-options.c | 13 ++++++-----
clang/test/Driver/hip-sanitize-options.hip | 19 +++++++++++++++-
6 files changed, 67 insertions(+), 29 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 2f6ad4c4fa327..333711e8ba844 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1074,29 +1074,32 @@ ROCMToolChain::getCommonDeviceLibNames(
getSanitizerArgs(DriverArgs).needsAsanRt());
}
-bool AMDGPUToolChain::shouldSkipSanitizeOption(
+std::optional<std::string> AMDGPUToolChain::filterSanitizeOption(
const ToolChain &TC, const llvm::opt::ArgList &DriverArgs,
StringRef TargetID, const llvm::opt::Arg *A) const {
// For actions without targetID, do nothing.
if (TargetID.empty())
- return false;
+ return std::nullopt;
Option O = A->getOption();
if (!O.matches(options::OPT_fsanitize_EQ))
- return false;
+ return std::nullopt;
if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
options::OPT_fno_gpu_sanitize, true))
- return true;
+ return "";
auto &Diags = TC.getDriver().getDiags();
- // For simplicity, we only allow -fsanitize=address
+ // We only allow the address sanitizer and ignore all other sanitizers.
+ SmallVector<std::string, 4> SupportedSanitizers;
for (const char *Value : A->getValues()) {
SanitizerMask K = parseSanitizerValue(Value, /*AllowGroups=*/false);
- if (K != SanitizerKind::Address)
- return true;
+ if (K == SanitizerKind::Address)
+ SupportedSanitizers.push_back(std::string(Value));
}
+ if (SupportedSanitizers.empty())
+ return "";
// Check 'xnack+' availability by default
llvm::StringRef Processor =
@@ -1120,7 +1123,8 @@ bool AMDGPUToolChain::shouldSkipSanitizeOption(
Diags.Report(
clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature)
<< A->getAsString(DriverArgs) << TargetID << "xnack+";
- return true;
+ return "";
}
- return false;
+
+ return llvm::join(SupportedSanitizers, ",");
}
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 95d2a53ed5be8..7c4dcfef8b7f1 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -101,11 +101,13 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
/// Needed for translating LTO options.
const char *getDefaultLinker() const override { return "ld.lld"; }
- /// Should skip sanitize options.
- bool shouldSkipSanitizeOption(const ToolChain &TC,
- const llvm::opt::ArgList &DriverArgs,
- StringRef TargetID,
- const llvm::opt::Arg *A) const;
+ /// Filter supported sanitizers from the sanitize option and return them. If
+ /// there should be no filtering and Arg should be kept as-is, return
+ /// std::nullopt. If no sanitizers are supported, return an empty string.
+ std::optional<std::string>
+ filterSanitizeOption(const ToolChain &TC,
+ const llvm::opt::ArgList &DriverArgs, StringRef TargetID,
+ const llvm::opt::Arg *A) const;
/// Uses amdgpu-arch tool to get arch of the system GPU. Will return error
/// if unable to find one.
@@ -164,8 +166,8 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
for (const char *Value : A->getValues()) {
SanitizerMask K = parseSanitizerValue(Value, /*Allow Groups*/ false);
if (K != SanitizerKind::Address)
- Diags.Report(clang::diag::warn_drv_unsupported_option_for_target)
- << A->getAsString(Args) << getTriple().str();
+ Diags.Report(clang::diag::warn_drv_unsupported_option_part_for_target)
+ << Value << A->getAsString(Args) << getTriple().str();
}
}
}
diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
index 2b41d54a9eb73..8d59116f3cc13 100644
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -66,16 +66,20 @@ llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
const OptTable &Opts = getDriver().getOpts();
- // Skip sanitize options passed from the HostTC. Claim them early.
+ // Skip sanitize options passed from the HostTC. Remove them early.
// The decision to sanitize device code is computed only by
// 'shouldSkipSanitizeOption'.
if (DAL->hasArg(options::OPT_fsanitize_EQ))
- DAL->claimAllArgs(options::OPT_fsanitize_EQ);
+ DAL->eraseArg(options::OPT_fsanitize_EQ);
- for (Arg *A : Args)
- if (!shouldSkipSanitizeOption(*this, Args, BoundArch, A) &&
- !llvm::is_contained(*DAL, A))
+ for (Arg *A : Args) {
+ std::optional<std::string> SupportedSanitizers =
+ filterSanitizeOption(*this, Args, BoundArch, A);
+ if (!SupportedSanitizers)
DAL->append(A);
+ else if (!SupportedSanitizers->empty())
+ DAL->AddJoinedArg(A, A->getOption(), *SupportedSanitizers);
+ }
if (!BoundArch.empty()) {
DAL->eraseArg(options::OPT_march_EQ);
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index c0c8afec07264..648be0ac2db08 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -291,9 +291,19 @@ HIPAMDToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
const OptTable &Opts = getDriver().getOpts();
+ // Skip sanitize options passed from the HostTC. Remove them early.
+ // The decision to sanitize device code is computed only by
+ // 'shouldSkipSanitizeOption'.
+ if (DAL->hasArg(options::OPT_fsanitize_EQ))
+ DAL->eraseArg(options::OPT_fsanitize_EQ);
+
for (Arg *A : Args) {
- if (!shouldSkipSanitizeOption(*this, Args, BoundArch, A))
+ std::optional<std::string> SupportedSanitizers =
+ filterSanitizeOption(*this, Args, BoundArch, A);
+ if (!SupportedSanitizers)
DAL->append(A);
+ else if (!SupportedSanitizers->empty())
+ DAL->AddJoinedArg(A, A->getOption(), *SupportedSanitizers);
}
if (!BoundArch.empty()) {
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index 59ecbcf7b35ba..d197db08cc720 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -52,20 +52,21 @@
// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack+ -fsanitize=address -fno-gpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=HOSTSAN,NOGPUSAN,SAN %s
-// Catch invalid combination of sanitizers regardless of their order.
-// The address sanitizer enables the device sanitizer pipeline. The fuzzer
+// Catch invalid combination of sanitizers regardless of their order and ignore
+// them selectively.
+// (The address sanitizer enables the device sanitizer pipeline. The fuzzer
// implicitly turns on LLVMs SanitizerCoverage, which the driver then forwards
-// to the device cc1. SanitizerCoverage is not supported on amdgcn
+// 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: | 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: | FileCheck -check-prefixes=HOSTSANCOMBINATION,INVALIDCOMBINATION2 %s
-// INVALIDCOMBINATION1: warning: ignoring '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
-// INVALIDCOMBINATION2: warning: ignoring '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// INVALIDCOMBINATION1: warning: ignoring 'fuzzer' in '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// INVALIDCOMBINATION2: warning: ignoring 'fuzzer' in '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
// FAIL-DAG: 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
-// NOTSUPPORTED-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
+// NOTSUPPORTED-DAG: warning: ignoring 'leak' in '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
// NOXNACK: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// XNACKNEG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908:xnack-' as it 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 490385173a4cb..2fce25461ab34 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -52,6 +52,18 @@
// RUN: -fsanitize=leak -nogpuinc --rocm-path=%S/Inputs/rocm \
// RUN: %s 2>&1 | FileCheck -check-prefixes=NOGPUNEG %s
+// Catch invalid combination of sanitizers regardless of their order and ignore
+// them selectively.
+// (The address sanitizer enables the device sanitizer pipeline. The fuzzer
+// 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: -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: -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATION,INVALIDCOMBINATION2 %s
+
// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-fsanitize=address"}}
// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc"}}
// CHECK-NOT: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}}
@@ -67,7 +79,7 @@
// 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
-// XNACK-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
+// XNACK-DAG: warning: ignoring 'leak' in '-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"}}
@@ -101,3 +113,8 @@
// 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: {{"[^"]*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[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address,fuzzer,fuzzer-no-link"}}
>From 1d0052b347b6c63f66dd136ef8e2f5fcf1dc5361 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 7 Nov 2025 08:37:30 -0600
Subject: [PATCH 4/7] add forgotten diagnostic
---
clang/include/clang/Basic/DiagnosticDriverKinds.td | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index afd44a110bc74..863236cacd61e 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -133,6 +133,9 @@ def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
def warn_drv_unsupported_option_for_target : Warning<
"ignoring '%0' option as it is not currently supported for target '%1'">,
InGroup<OptionIgnored>;
+def warn_drv_unsupported_option_part_for_target : Warning<
+ "ignoring '%0' in '%1' option as it is not currently supported for target '%2'">,
+ InGroup<OptionIgnored>;
def warn_drv_invalid_argument_for_flang : Warning<
"'%0' is not valid for Fortran">,
InGroup<OptionIgnored>;
>From da9e71593799dd263f3f936a17c9691553da96f9 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Fri, 7 Nov 2025 09:50:33 -0600
Subject: [PATCH 5/7] fix after rebase
---
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 333711e8ba844..ca6ab13f8a28a 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1111,7 +1111,7 @@ std::optional<std::string> AMDGPUToolChain::filterSanitizeOption(
? llvm::AMDGPU::getArchAttrAMDGCN(ProcKind)
: llvm::AMDGPU::getArchAttrR600(ProcKind);
if (Features & llvm::AMDGPU::FEATURE_XNACK_ALWAYS)
- return false;
+ return std::nullopt;
// Look for the xnack feature in TargetID
llvm::StringMap<bool> FeatureMap;
>From 0ee2fac3dd3cdd485fb2b5861fc3761df26a19d1 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Thu, 13 Nov 2025 05:28:57 -0600
Subject: [PATCH 6/7] refactor code; support errors for explicit -Xarch_device;
improve testing
---
.../clang/Basic/DiagnosticDriverKinds.td | 7 ++
clang/lib/Driver/ToolChains/AMDGPU.cpp | 44 ++++-------
clang/lib/Driver/ToolChains/AMDGPU.h | 75 +++++++++++++++----
clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp | 20 +----
clang/lib/Driver/ToolChains/HIPAMD.cpp | 20 +----
.../Driver/amdgpu-openmp-sanitize-options.c | 28 ++++++-
clang/test/Driver/hip-sanitize-options.hip | 46 +++++++++++-
7 files changed, 161 insertions(+), 79 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 863236cacd61e..2dd2354da7ec9 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -126,6 +126,9 @@ def err_drv_bad_offload_arch_combo : Error<
"invalid offload arch combinations: '%0' and '%1' (for a specific processor, "
"a feature should either exist in all offload archs, or not exist in any "
"offload archs)">;
+def err_drv_unsupported_option_for_offload_arch_req_feature : Error<
+ "'%0' option for offload arch '%1' is not currently supported "
+ "there. Use it with an offload arch containing '%2' instead">;
def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
"ignoring '%0' option for offload arch '%1' as it is not currently supported "
"there. Use it with an offload arch containing '%2' instead">,
@@ -133,9 +136,13 @@ def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
def warn_drv_unsupported_option_for_target : Warning<
"ignoring '%0' option as it is not currently supported for target '%1'">,
InGroup<OptionIgnored>;
+def err_drv_unsupported_option_for_target : Error<
+ "'%0' option is not currently supported for target '%1'">;
def warn_drv_unsupported_option_part_for_target : Warning<
"ignoring '%0' in '%1' option as it is not currently supported for target '%2'">,
InGroup<OptionIgnored>;
+def err_drv_unsupported_option_part_for_target : Error<
+ "'%0' in '%1' option is not currently supported for target '%2'">;
def warn_drv_invalid_argument_for_flang : Warning<
"'%0' is not valid for Fortran">,
InGroup<OptionIgnored>;
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index ca6ab13f8a28a..fe96d238036e8 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1074,32 +1074,12 @@ ROCMToolChain::getCommonDeviceLibNames(
getSanitizerArgs(DriverArgs).needsAsanRt());
}
-std::optional<std::string> AMDGPUToolChain::filterSanitizeOption(
+bool AMDGPUToolChain::shouldSkipSanitizeOption(
const ToolChain &TC, const llvm::opt::ArgList &DriverArgs,
StringRef TargetID, const llvm::opt::Arg *A) const {
- // For actions without targetID, do nothing.
- if (TargetID.empty())
- return std::nullopt;
- Option O = A->getOption();
-
- if (!O.matches(options::OPT_fsanitize_EQ))
- return std::nullopt;
-
- if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
- options::OPT_fno_gpu_sanitize, true))
- return "";
-
auto &Diags = TC.getDriver().getDiags();
-
- // We only allow the address sanitizer and ignore all other sanitizers.
- SmallVector<std::string, 4> SupportedSanitizers;
- for (const char *Value : A->getValues()) {
- SanitizerMask K = parseSanitizerValue(Value, /*AllowGroups=*/false);
- if (K == SanitizerKind::Address)
- SupportedSanitizers.push_back(std::string(Value));
- }
- if (SupportedSanitizers.empty())
- return "";
+ bool IsExplicitDevice =
+ A->getBaseArg().getOption().matches(options::OPT_Xarch_device);
// Check 'xnack+' availability by default
llvm::StringRef Processor =
@@ -1111,7 +1091,7 @@ std::optional<std::string> AMDGPUToolChain::filterSanitizeOption(
? llvm::AMDGPU::getArchAttrAMDGCN(ProcKind)
: llvm::AMDGPU::getArchAttrR600(ProcKind);
if (Features & llvm::AMDGPU::FEATURE_XNACK_ALWAYS)
- return std::nullopt;
+ return false;
// Look for the xnack feature in TargetID
llvm::StringMap<bool> FeatureMap;
@@ -1120,11 +1100,17 @@ std::optional<std::string> AMDGPUToolChain::filterSanitizeOption(
(void)OptionalGpuArch;
auto Loc = FeatureMap.find("xnack");
if (Loc == FeatureMap.end() || !Loc->second) {
- Diags.Report(
- clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature)
- << A->getAsString(DriverArgs) << TargetID << "xnack+";
- return "";
+ if (IsExplicitDevice) {
+ Diags.Report(
+ clang::diag::err_drv_unsupported_option_for_offload_arch_req_feature)
+ << A->getAsString(DriverArgs) << TargetID << "xnack+";
+ } else {
+ Diags.Report(
+ clang::diag::warn_drv_unsupported_option_for_offload_arch_req_feature)
+ << A->getAsString(DriverArgs) << TargetID << "xnack+";
+ }
+ return true;
}
- return llvm::join(SupportedSanitizers, ",");
+ return false;
}
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 7c4dcfef8b7f1..5614b72a872ce 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -101,13 +101,11 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
/// Needed for translating LTO options.
const char *getDefaultLinker() const override { return "ld.lld"; }
- /// Filter supported sanitizers from the sanitize option and return them. If
- /// there should be no filtering and Arg should be kept as-is, return
- /// std::nullopt. If no sanitizers are supported, return an empty string.
- std::optional<std::string>
- filterSanitizeOption(const ToolChain &TC,
- const llvm::opt::ArgList &DriverArgs, StringRef TargetID,
- const llvm::opt::Arg *A) const;
+ /// Should skip sanitize option.
+ bool shouldSkipSanitizeOption(const ToolChain &TC,
+ const llvm::opt::ArgList &DriverArgs,
+ StringRef TargetID,
+ const llvm::opt::Arg *A) const;
/// Uses amdgpu-arch tool to get arch of the system GPU. Will return error
/// if unable to find one.
@@ -157,19 +155,64 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
return SanitizerKind::Address;
}
- void diagnoseUnsupportedSanitizers(const llvm::opt::ArgList &Args) const {
- if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
- true))
- return;
+ bool handleSanitizeOption(const ToolChain &TC, llvm::opt::DerivedArgList &DAL,
+ const llvm::opt::ArgList &DriverArgs,
+ StringRef TargetID, const llvm::opt::Arg *A) const {
+ if (TargetID.empty())
+ return false;
+ // If this isn't a sanitizer option, don't handle it.
+ if (!A->getOption().matches(options::OPT_fsanitize_EQ))
+ return false;
+ // If we shouldn't do sanitizing, skip it.
+ if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
+ options::OPT_fno_gpu_sanitize, true))
+ return true;
+
auto &Diags = getDriver().getDiags();
- for (auto *A : Args.filtered(options::OPT_fsanitize_EQ)) {
- for (const char *Value : A->getValues()) {
- SanitizerMask K = parseSanitizerValue(Value, /*Allow Groups*/ false);
- if (K != SanitizerKind::Address)
+ bool IsExplicitDevice =
+ A->getBaseArg().getOption().matches(options::OPT_Xarch_device);
+
+ SmallVector<const char *, 4> SupportedSanitizers;
+ SmallVector<const char *, 4> UnSupportedSanitizers;
+
+ for (const char *Value : A->getValues()) {
+ SanitizerMask K = parseSanitizerValue(Value, /*Allow Groups*/ false);
+ if (K & ROCMToolChain::getSupportedSanitizers())
+ SupportedSanitizers.push_back(Value);
+ else
+ UnSupportedSanitizers.push_back(Value);
+ }
+
+ // If there are no supported sanitizers, drop the whole argument.
+ if (SupportedSanitizers.empty()) {
+ if (IsExplicitDevice) {
+ Diags.Report(clang::diag::err_drv_unsupported_option_for_target)
+ << A->getAsString(DAL) << getTriple().str();
+ } else {
+ Diags.Report(clang::diag::warn_drv_unsupported_option_for_target)
+ << A->getAsString(DAL) << getTriple().str();
+ }
+ return true;
+ }
+ // If only some sanitizers are unsupported, report each one individually.
+ if (!UnSupportedSanitizers.empty()) {
+ for (const char *Value : UnSupportedSanitizers) {
+ if (IsExplicitDevice) {
+ Diags.Report(clang::diag::err_drv_unsupported_option_part_for_target)
+ << Value << A->getAsString(DriverArgs) << getTriple().str();
+ } else {
Diags.Report(clang::diag::warn_drv_unsupported_option_part_for_target)
- << Value << A->getAsString(Args) << getTriple().str();
+ << Value << A->getAsString(DriverArgs) << getTriple().str();
+ }
}
}
+ // If we know the target arch, check if the sanitizer is supported for it.
+ if (shouldSkipSanitizeOption(TC, DriverArgs, TargetID, A))
+ return true;
+
+ // Add a new argument with only the supported sanitizers.
+ DAL.AddJoinedArg(A, A->getOption(), llvm::join(SupportedSanitizers, ","));
+ return true;
}
};
diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
index 8d59116f3cc13..66ae1fa7b6c34 100644
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
@@ -28,8 +28,6 @@ AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D,
// Lookup binaries into the driver directory, this is used to
// discover the 'amdgpu-arch' executable.
getProgramPaths().push_back(getDriver().Dir);
- // Diagnose unsupported sanitizer options only once.
- diagnoseUnsupportedSanitizers(Args);
}
void AMDGPUOpenMPToolChain::addClangTargetOptions(
@@ -66,19 +64,10 @@ llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
const OptTable &Opts = getDriver().getOpts();
- // Skip sanitize options passed from the HostTC. Remove them early.
- // The decision to sanitize device code is computed only by
- // 'shouldSkipSanitizeOption'.
- if (DAL->hasArg(options::OPT_fsanitize_EQ))
- DAL->eraseArg(options::OPT_fsanitize_EQ);
-
for (Arg *A : Args) {
- std::optional<std::string> SupportedSanitizers =
- filterSanitizeOption(*this, Args, BoundArch, A);
- if (!SupportedSanitizers)
+ // Filter unsupported sanitizers passed from the HostTC.
+ if (!handleSanitizeOption(*this, *DAL, Args, BoundArch, A))
DAL->append(A);
- else if (!SupportedSanitizers->empty())
- DAL->AddJoinedArg(A, A->getOption(), *SupportedSanitizers);
}
if (!BoundArch.empty()) {
@@ -119,9 +108,8 @@ void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
SanitizerMask AMDGPUOpenMPToolChain::getSupportedSanitizers() const {
// The AMDGPUOpenMPToolChain only supports sanitizers in the sense that it
// allows sanitizer arguments on the command line if they are supported by the
- // host toolchain. The AMDGPUOpenMPToolChain will actually ignore any command
- // line arguments for any of these "supported" sanitizers. That means that no
- // sanitization of device code is actually supported at this time.
+ // host toolchain. The AMDGPUOpenMPToolChain will later filter unsupported
+ // sanitizers from the command line arguments.
//
// This behavior is necessary because the host and device toolchains
// invocations often share the command line, so the device toolchain must
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index 648be0ac2db08..d666456881780 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -219,8 +219,6 @@ HIPAMDToolChain::HIPAMDToolChain(const Driver &D, const llvm::Triple &Triple,
// Lookup binaries into the driver directory, this is used to
// discover the clang-offload-bundler executable.
getProgramPaths().push_back(getDriver().Dir);
- // Diagnose unsupported sanitizer options only once.
- diagnoseUnsupportedSanitizers(Args);
}
void HIPAMDToolChain::addClangTargetOptions(
@@ -291,19 +289,10 @@ HIPAMDToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
const OptTable &Opts = getDriver().getOpts();
- // Skip sanitize options passed from the HostTC. Remove them early.
- // The decision to sanitize device code is computed only by
- // 'shouldSkipSanitizeOption'.
- if (DAL->hasArg(options::OPT_fsanitize_EQ))
- DAL->eraseArg(options::OPT_fsanitize_EQ);
-
for (Arg *A : Args) {
- std::optional<std::string> SupportedSanitizers =
- filterSanitizeOption(*this, Args, BoundArch, A);
- if (!SupportedSanitizers)
+ // Filter unsupported sanitizers passed from the HostTC.
+ if (!handleSanitizeOption(*this, *DAL, Args, BoundArch, A))
DAL->append(A);
- else if (!SupportedSanitizers->empty())
- DAL->AddJoinedArg(A, A->getOption(), *SupportedSanitizers);
}
if (!BoundArch.empty()) {
@@ -358,9 +347,8 @@ void HIPAMDToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
SanitizerMask HIPAMDToolChain::getSupportedSanitizers() const {
// The HIPAMDToolChain only supports sanitizers in the sense that it allows
// sanitizer arguments on the command line if they are supported by the host
- // toolchain. The HIPAMDToolChain will actually ignore any command line
- // arguments for any of these "supported" sanitizers. That means that no
- // sanitization of device code is actually supported at this time.
+ // toolchain. The HIPAMDToolChain will later filter unsupported sanitizers
+ // from the command line arguments.
//
// This behavior is necessary because the host and device toolchains
// invocations often share the command line, so the device toolchain must
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index d197db08cc720..b9cd315520d94 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -57,22 +57,44 @@
// (The address sanitizer enables the device sanitizer pipeline. The fuzzer
// 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: | 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: | 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: | 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: | 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: | FileCheck -check-prefixes=HOSTSANCOMBINATION2,NOTSUPPORTED-DAG,INVALIDCOMBINATION2 %s
+
+// Test -Xarch_device error scenario
+
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -Xarch_device -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=UNSUPPORTEDERROR %s
+
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack- -Xarch_device -fsanitize=address --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=XNACKERROR %s
+
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -Xarch_device -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATIONERROR %s
+
// INVALIDCOMBINATION1: warning: ignoring 'fuzzer' in '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
// INVALIDCOMBINATION2: warning: ignoring 'fuzzer' in '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
// FAIL-DAG: 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
-// NOTSUPPORTED-DAG: warning: ignoring 'leak' in '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
+// NOTSUPPORTED-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
// NOXNACK: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// XNACKNEG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// HOSTSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "--offload-targets=amdgcn-amd-amdhsa".* "-x" "c".*}}
// 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".*}}
// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-x" "c".*}}
@@ -80,3 +102,7 @@
// 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)".*}}
+
+// 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
+// INVALIDCOMBINATIONERROR: error: 'fuzzer' in '-fsanitize=fuzzer,address' option is not currently supported for target 'amdgcn-amd-amdhsa'
diff --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip
index 2fce25461ab34..3fc3de9a66ff2 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -57,6 +57,7 @@
// (The address sanitizer enables the device sanitizer pipeline. The fuzzer
// 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: -fsanitize=address,fuzzer --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATION,INVALIDCOMBINATION1 %s
@@ -64,6 +65,29 @@
// 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: -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: -fsanitize=fuzzer,address -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=MULT2,XNACK2 %s
+
+// Test -Xarch_device error scenario
+
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
+// RUN: -Xarch_device -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=UNSUPPORTEDERROR %s
+
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack- \
+// RUN: -Xarch_device -fsanitize=address --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=XNACKERROR %s
+
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
+// RUN: -Xarch_device -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATIONERROR %s
+
// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-fsanitize=address"}}
// CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc"}}
// CHECK-NOT: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}}
@@ -79,7 +103,7 @@
// 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
-// XNACK-DAG: warning: ignoring 'leak' in '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
+// 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"}}
@@ -118,3 +142,23 @@
// 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[^"]*".* "-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]
+// MULT1-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// MULT1-DAG: warning: ignoring 'fuzzer' in '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// MULT1-DAG: warning: ignoring '-fsanitize=address,fuzzer' option for offload arch 'gfx908:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead [-Woption-ignored]
+// MULT1-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+
+// MULT2-DAG: warning: ignoring 'fuzzer' in '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// MULT2-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// MULT2-DAG: warning: ignoring 'fuzzer' in '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
+// 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[^"]*".* "-target-cpu" "gfx908"}}
+// XNACK2-DAG: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address,fuzzer,fuzzer-no-link,leak"}}
+
+// UNSUPPORTEDERROR: error: '-fsanitize=leak' option is not currently supported for target 'amdgcn-amd-amdhsa'
+// XNACKERROR: error: '-fsanitize=address' option for offload arch 'gfx900:xnack-' is not currently supported there. Use it with an offload arch containing 'xnack+' instead
+// INVALIDCOMBINATIONERROR: error: 'fuzzer' in '-fsanitize=fuzzer,address' option is not currently supported for target 'amdgcn-amd-amdhsa'
>From 53fe7b7d943f600eb9d9fcd8f0a21653de704563 Mon Sep 17 00:00:00 2001
From: Robert Imschweiler <robert.imschweiler at amd.com>
Date: Mon, 17 Nov 2025 06:25:31 -0600
Subject: [PATCH 7/7] add fsan_cov_group
---
clang/include/clang/Driver/Options.td | 31 ++++++++--
clang/lib/Driver/ToolChains/AMDGPU.h | 57 ++++++++++++-------
.../Driver/amdgpu-openmp-sanitize-options.c | 11 ++++
clang/test/Driver/hip-sanitize-options.hip | 12 ++++
4 files changed, 85 insertions(+), 26 deletions(-)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 11e81e032d5fc..4b2f87f5c04d9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -201,6 +201,10 @@ def hlsl_Group : OptionGroup<"<HLSL group>">, Group<f_Group>,
DocName<"HLSL options">,
Visibility<[ClangOption]>;
+def fsan_cov_Group : OptionGroup<"<-fsanitize-coverage group>">,
+ Group<f_clang_Group>,
+ DocName<"Sanitizer Coverage options">;
+
// Feature groups - these take command line options that correspond directly to
// target specific features and can be translated directly from command line
// options.
@@ -2407,26 +2411,26 @@ def : Flag<["-"], "fno-sanitize-blacklist">,
Group<f_clang_Group>, Flags<[HelpHidden]>, Alias<fno_sanitize_ignorelist>;
def fsanitize_coverage : CommaJoined<["-"], "fsanitize-coverage=">,
- Group<f_clang_Group>,
+ Group<fsan_cov_Group>,
HelpText<"Specify the type of coverage instrumentation for Sanitizers">;
def fno_sanitize_coverage : CommaJoined<["-"], "fno-sanitize-coverage=">,
- Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<fsan_cov_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable features of coverage instrumentation for Sanitizers">,
Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,"
"8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters,"
"inline-bool-flag">;
def fsanitize_coverage_allowlist : Joined<["-"], "fsanitize-coverage-allowlist=">,
- Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<fsan_cov_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Restrict sanitizer coverage instrumentation exclusively to modules and functions that match the provided special case list, except the blocked ones">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageAllowlistFiles">>;
def fsanitize_coverage_ignorelist : Joined<["-"], "fsanitize-coverage-ignorelist=">,
- Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
+ Group<fsan_cov_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable sanitizer coverage instrumentation for modules and functions "
"that match the provided special case list, even the allowed ones">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageIgnorelistFiles">>;
def fsanitize_coverage_stack_depth_callback_min_EQ
: Joined<["-"], "fsanitize-coverage-stack-depth-callback-min=">,
- Group<f_clang_Group>,
+ Group<fsan_cov_Group>,
MetaVarName<"<M>">,
HelpText<"Use callback for max stack depth tracing with minimum stack "
"depth M">,
@@ -7898,70 +7902,87 @@ def linker_option : Joined<["--"], "linker-option=">,
HelpText<"Add linker option">,
MarshallingInfoStringVector<CodeGenOpts<"LinkerOptions">>;
def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">,
+ Group<fsan_cov_Group>,
HelpText<"Sanitizer coverage type">,
MarshallingInfoInt<CodeGenOpts<"SanitizeCoverageType">>;
def fsanitize_coverage_indirect_calls
: Flag<["-"], "fsanitize-coverage-indirect-calls">,
+ Group<fsan_cov_Group>,
HelpText<"Enable sanitizer coverage for indirect calls">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageIndirectCalls">>;
def fsanitize_coverage_trace_bb
: Flag<["-"], "fsanitize-coverage-trace-bb">,
+ Group<fsan_cov_Group>,
HelpText<"Enable basic block tracing in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceBB">>;
def fsanitize_coverage_trace_cmp
: Flag<["-"], "fsanitize-coverage-trace-cmp">,
+ Group<fsan_cov_Group>,
HelpText<"Enable cmp instruction tracing in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceCmp">>;
def fsanitize_coverage_trace_div
: Flag<["-"], "fsanitize-coverage-trace-div">,
+ Group<fsan_cov_Group>,
HelpText<"Enable div instruction tracing in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceDiv">>;
def fsanitize_coverage_trace_gep
: Flag<["-"], "fsanitize-coverage-trace-gep">,
+ Group<fsan_cov_Group>,
HelpText<"Enable gep instruction tracing in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceGep">>;
def fsanitize_coverage_8bit_counters
: Flag<["-"], "fsanitize-coverage-8bit-counters">,
+ Group<fsan_cov_Group>,
HelpText<"Enable frequency counters in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverage8bitCounters">>;
def fsanitize_coverage_inline_8bit_counters
: Flag<["-"], "fsanitize-coverage-inline-8bit-counters">,
+ Group<fsan_cov_Group>,
HelpText<"Enable inline 8-bit counters in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageInline8bitCounters">>;
def fsanitize_coverage_inline_bool_flag
: Flag<["-"], "fsanitize-coverage-inline-bool-flag">,
+ Group<fsan_cov_Group>,
HelpText<"Enable inline bool flag in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageInlineBoolFlag">>;
def fsanitize_coverage_pc_table
: Flag<["-"], "fsanitize-coverage-pc-table">,
+ Group<fsan_cov_Group>,
HelpText<"Create a table of coverage-instrumented PCs">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoveragePCTable">>;
def fsanitize_coverage_control_flow
: Flag<["-"], "fsanitize-coverage-control-flow">,
+ Group<fsan_cov_Group>,
HelpText<"Collect control flow of function">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageControlFlow">>;
def fsanitize_coverage_trace_pc
: Flag<["-"], "fsanitize-coverage-trace-pc">,
+ Group<fsan_cov_Group>,
HelpText<"Enable PC tracing in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTracePC">>;
def fsanitize_coverage_trace_pc_guard
: Flag<["-"], "fsanitize-coverage-trace-pc-guard">,
+ Group<fsan_cov_Group>,
HelpText<"Enable PC tracing with guard in sanitizer coverage">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTracePCGuard">>;
def fsanitize_coverage_no_prune
: Flag<["-"], "fsanitize-coverage-no-prune">,
+ Group<fsan_cov_Group>,
HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageNoPrune">>;
def fsanitize_coverage_stack_depth
: Flag<["-"], "fsanitize-coverage-stack-depth">,
+ Group<fsan_cov_Group>,
HelpText<"Enable max stack depth tracing">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageStackDepth">>;
def fsanitize_coverage_trace_loads
: Flag<["-"], "fsanitize-coverage-trace-loads">,
+ Group<fsan_cov_Group>,
HelpText<"Enable tracing of loads">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceLoads">>;
def fsanitize_coverage_trace_stores
: Flag<["-"], "fsanitize-coverage-trace-stores">,
+ Group<fsan_cov_Group>,
HelpText<"Enable tracing of stores">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceStores">>;
def fexperimental_sanitize_metadata_EQ_covered
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 5614b72a872ce..fb4b918c44aab 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -155,22 +155,49 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
return SanitizerKind::Address;
}
+ bool diagnoseUnsupportedOption(const llvm::opt::Arg *A,
+ const llvm::opt::DerivedArgList &DAL,
+ const llvm::opt::ArgList &DriverArgs,
+ const char *Value = nullptr) const {
+ auto &Diags = getDriver().getDiags();
+ bool IsExplicitDevice =
+ A->getBaseArg().getOption().matches(options::OPT_Xarch_device);
+
+ if (Value) {
+ unsigned DiagID =
+ IsExplicitDevice
+ ? clang::diag::err_drv_unsupported_option_part_for_target
+ : clang::diag::warn_drv_unsupported_option_part_for_target;
+ Diags.Report(DiagID) << Value << A->getAsString(DriverArgs)
+ << getTriple().str();
+ } else {
+ unsigned DiagID =
+ IsExplicitDevice
+ ? clang::diag::err_drv_unsupported_option_for_target
+ : clang::diag::warn_drv_unsupported_option_for_target;
+ Diags.Report(DiagID) << A->getAsString(DAL) << getTriple().str();
+ }
+ return true;
+ }
+
bool handleSanitizeOption(const ToolChain &TC, llvm::opt::DerivedArgList &DAL,
const llvm::opt::ArgList &DriverArgs,
StringRef TargetID, const llvm::opt::Arg *A) const {
if (TargetID.empty())
return false;
- // If this isn't a sanitizer option, don't handle it.
- if (!A->getOption().matches(options::OPT_fsanitize_EQ))
- return false;
// If we shouldn't do sanitizing, skip it.
if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
options::OPT_fno_gpu_sanitize, true))
return true;
-
- auto &Diags = getDriver().getDiags();
- bool IsExplicitDevice =
- A->getBaseArg().getOption().matches(options::OPT_Xarch_device);
+ const llvm::opt::Option &Opt = A->getOption();
+ // Sanitizer coverage is currently not supported for AMDGPU, so warn/error
+ // on every related option.
+ if (Opt.matches(options::OPT_fsan_cov_Group)) {
+ diagnoseUnsupportedOption(A, DAL, DriverArgs);
+ }
+ // If this isn't a sanitizer option, don't handle it.
+ if (!Opt.matches(options::OPT_fsanitize_EQ))
+ return false;
SmallVector<const char *, 4> SupportedSanitizers;
SmallVector<const char *, 4> UnSupportedSanitizers;
@@ -185,25 +212,13 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
// If there are no supported sanitizers, drop the whole argument.
if (SupportedSanitizers.empty()) {
- if (IsExplicitDevice) {
- Diags.Report(clang::diag::err_drv_unsupported_option_for_target)
- << A->getAsString(DAL) << getTriple().str();
- } else {
- Diags.Report(clang::diag::warn_drv_unsupported_option_for_target)
- << A->getAsString(DAL) << getTriple().str();
- }
+ diagnoseUnsupportedOption(A, DAL, DriverArgs);
return true;
}
// If only some sanitizers are unsupported, report each one individually.
if (!UnSupportedSanitizers.empty()) {
for (const char *Value : UnSupportedSanitizers) {
- if (IsExplicitDevice) {
- Diags.Report(clang::diag::err_drv_unsupported_option_part_for_target)
- << Value << A->getAsString(DriverArgs) << getTriple().str();
- } else {
- Diags.Report(clang::diag::warn_drv_unsupported_option_part_for_target)
- << Value << A->getAsString(DriverArgs) << getTriple().str();
- }
+ diagnoseUnsupportedOption(A, DAL, DriverArgs, Value);
}
}
// If we know the target arch, check if the sanitizer is supported for it.
diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
index b9cd315520d94..fd7d11803249c 100644
--- a/clang/test/Driver/amdgpu-openmp-sanitize-options.c
+++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c
@@ -72,6 +72,10 @@
// 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: | FileCheck -check-prefixes=HOSTSANCOMBINATION2,NOTSUPPORTED-DAG,INVALIDCOMBINATION2 %s
+// Check for -fsanitize-coverage options
+// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fsanitize-coverage=inline-bool-flag --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=WARNSANCOV %s
+
// Test -Xarch_device error scenario
// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -Xarch_device -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
@@ -83,6 +87,10 @@
// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -Xarch_device -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATIONERROR %s
+// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -Xarch_device -fsanitize-coverage-stack-depth-callback-min=42 --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=ERRSANCOV %s
+
+
// INVALIDCOMBINATION1: warning: ignoring 'fuzzer' in '-fsanitize=address,fuzzer' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
// INVALIDCOMBINATION2: warning: ignoring 'fuzzer' in '-fsanitize=fuzzer,address' option as it is not currently supported for target 'amdgcn-amd-amdhsa' [-Woption-ignored]
@@ -106,3 +114,6 @@
// 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
// INVALIDCOMBINATIONERROR: error: 'fuzzer' in '-fsanitize=fuzzer,address' option is not currently supported for target 'amdgcn-amd-amdhsa'
+
+// WARNSANCOV: warning: ignoring '-fsanitize-coverage=inline-bool-flag' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
+// ERRSANCOV: error: '-fsanitize-coverage-stack-depth-callback-min=42' option is not currently supported for target 'amdgcn-amd-amdhsa'
diff --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip
index 3fc3de9a66ff2..d436756ee046b 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -74,6 +74,11 @@
// RUN: -fsanitize=fuzzer,address -fsanitize=leak --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=MULT2,XNACK2 %s
+// Check for -fsanitize-coverage options
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
+// RUN: -fsanitize=address -fsanitize-coverage=inline-bool-flag --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=WARNSANCOV %s
+
// Test -Xarch_device error scenario
// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
@@ -88,6 +93,10 @@
// RUN: -Xarch_device -fsanitize=fuzzer,address --rocm-path=%S/Inputs/rocm %s 2>&1 \
// RUN: | FileCheck -check-prefixes=INVALIDCOMBINATIONERROR %s
+// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \
+// RUN: -fsanitize=address -Xarch_device -fsanitize-coverage-stack-depth-callback-min=42 --rocm-path=%S/Inputs/rocm %s 2>&1 \
+// 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: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}}
@@ -162,3 +171,6 @@
// UNSUPPORTEDERROR: error: '-fsanitize=leak' option is not currently supported for target 'amdgcn-amd-amdhsa'
// XNACKERROR: error: '-fsanitize=address' option for offload arch 'gfx900:xnack-' is not currently supported there. Use it with an offload arch containing 'xnack+' instead
// INVALIDCOMBINATIONERROR: error: 'fuzzer' in '-fsanitize=fuzzer,address' option is not currently supported for target 'amdgcn-amd-amdhsa'
+
+// WARNSANCOV: warning: ignoring '-fsanitize-coverage=inline-bool-flag' option as it is not currently supported for target 'amdgcn-amd-amdhsa'
+// ERRSANCOV: error: '-fsanitize-coverage-stack-depth-callback-min=42' option is not currently supported for target 'amdgcn-amd-amdhsa'
More information about the cfe-commits
mailing list