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

>From 39c5fe12024ec2999062141d680758924a291891 Mon Sep 17 00:00:00 2001
From: Joseph Huber <[email protected]>
Date: Sun, 5 Jul 2026 11:41:50 -0500
Subject: [PATCH] [AMDGPU] Add and support '-fsanitize=concurrency' in the
 AMDGPU toolchain

Summary:
Adds a new `-fsanitize=concurrency` that is supported by the AMDGPU
target. This re-uses the TSan instrumentation but links a different
runtime. This was suggested in the dicussions at
https://discourse.llvm.org/t/rfc-a-thread-concurrency-sanitizer-for-gpus-in-compiler-rt/91113
and is done to keep users from confusing the probabalistic sampling that
users like KCSan do with the traditional, deterministic happends-before
model.
---
 clang/include/clang/Basic/Sanitizers.def      |  3 ++
 clang/include/clang/Driver/SanitizerArgs.h    |  3 ++
 clang/lib/Driver/SanitizerArgs.cpp            | 11 ++++++-
 clang/lib/Driver/ToolChains/AMDGPU.cpp        |  1 +
 clang/lib/Driver/ToolChains/Clang.cpp         | 13 ++++++++
 clang/lib/Driver/ToolChains/CommonArgs.cpp    |  2 ++
 clang/test/CodeGen/allow-ubsan-check.c        | 32 +++++++++----------
 .../lib/amdgcn-amd-amdhsa/libclang_rt.csan.a  |  0
 clang/test/Driver/amdgpu-toolchain.c          |  7 ++++
 clang/test/Driver/fsanitize.c                 |  5 +++
 10 files changed, 60 insertions(+), 17 deletions(-)
 create mode 100644 
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/amdgcn-amd-amdhsa/libclang_rt.csan.a

diff --git a/clang/include/clang/Basic/Sanitizers.def 
b/clang/include/clang/Basic/Sanitizers.def
index da85431625026..9499eb37de67c 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -79,6 +79,9 @@ SANITIZER("type", Type)
 // ThreadSanitizer
 SANITIZER("thread", Thread)
 
+// ConcurrencySanitizer
+SANITIZER("concurrency", Concurrency)
+
 // Numerical stability sanitizer.
 SANITIZER("numerical", NumericalStability)
 
diff --git a/clang/include/clang/Driver/SanitizerArgs.h 
b/clang/include/clang/Driver/SanitizerArgs.h
index 6a01b3e36d44c..78f577a412ecb 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -104,6 +104,9 @@ class SanitizerArgs {
   }
   bool needsTysanRt() const { return Sanitizers.has(SanitizerKind::Type); }
   bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
+  bool needsCsanRt() const {
+    return Sanitizers.has(SanitizerKind::Concurrency);
+  }
   bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
   bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }
   bool needsLsanRt() const {
diff --git a/clang/lib/Driver/SanitizerArgs.cpp 
b/clang/lib/Driver/SanitizerArgs.cpp
index e813efc89073d..09ab10b922c15 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -1486,7 +1486,16 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const 
llvm::opt::ArgList &Args,
 
   if (Sanitizers.empty())
     return;
-  CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
+
+  // The concurrency sampler re-uses the thread sanitizer instrumentation. We
+  // lower it to `-fsanitize=thread` but the driver selects a differnt runtime.
+  SanitizerSet EmittedSanitizers = Sanitizers;
+  if (EmittedSanitizers.has(SanitizerKind::Concurrency)) {
+    EmittedSanitizers.set(SanitizerKind::Concurrency, false);
+    EmittedSanitizers.set(SanitizerKind::Thread, true);
+  }
+  CmdArgs.push_back(
+      Args.MakeArgString("-fsanitize=" + toString(EmittedSanitizers)));
 
   if (!SuppressUBSanFeature.empty())
     CmdArgs.push_back(
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp 
b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 032c108d3d10d..a9d96674a57aa 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1161,6 +1161,7 @@ SanitizerMask AMDGPUToolChain::getSupportedSanitizers(
   // arch xnack support.
   if (!BA || isXnackAvailable(getTriple(), BA.ArchName))
     SupportedMask |= SanitizerKind::Address;
+  SupportedMask |= SanitizerKind::Concurrency;
 
   return SupportedMask;
 }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index fe01e6ffd59ef..192210567853b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -9734,6 +9734,17 @@ static bool requiresUBSanRT(unsigned ID) {
   }
 }
 
+// Options that need the csan compiler-rt library on the target toolchain.
+static bool requiresCSanRT(unsigned ID) {
+  switch (ID) {
+  case options::OPT_fsanitize_EQ:
+  case options::OPT_fno_sanitize_EQ:
+    return true;
+  default:
+    return false;
+  }
+}
+
 void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
                                  const InputInfo &Output,
                                  const InputInfoList &Inputs,
@@ -9813,6 +9824,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const 
JobAction &JA,
     // Without this check using it on the host would result in linker errors.
     if (requiresUBSanRT(ID) && !ToolChainHasRT(TC, "ubsan_minimal"))
       return false;
+    if (requiresCSanRT(ID) && !ToolChainHasRT(TC, "csan"))
+      return false;
     // Don't forward -mllvm to toolchains that don't support LLVM.
     return TC.HasNativeLLVMSupport() || ID != OPT_mllvm;
   };
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index dfd13fbe8a4eb..021d616ca001d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1722,6 +1722,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const 
ArgList &Args,
     if (SanArgs.linkCXXRuntimes())
       StaticRuntimes.push_back("tsan_cxx");
   }
+  if (!SanArgs.needsSharedRt() && SanArgs.needsCsanRt())
+    StaticRuntimes.push_back("csan");
   if (!SanArgs.needsSharedRt() && SanArgs.needsTysanRt())
     StaticRuntimes.push_back("tysan");
   if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt()) {
diff --git a/clang/test/CodeGen/allow-ubsan-check.c 
b/clang/test/CodeGen/allow-ubsan-check.c
index 0fc95c41b3e3d..851f7cffed9d7 100644
--- a/clang/test/CodeGen/allow-ubsan-check.c
+++ b/clang/test/CodeGen/allow-ubsan-check.c
@@ -18,10 +18,10 @@
 // CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize 
[[META6]]
 // CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META6]]
 // CHECK-NEXT:    [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]]
-// CHECK-NEXT:    [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), 
!nosanitize [[META6]]
+// CHECK-NEXT:    [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 28), 
!nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize 
[[META6]]
-// CHECK-NEXT:    [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), 
!nosanitize [[META6]]
+// CHECK-NEXT:    [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 42), 
!nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize 
[[META6]]
@@ -42,10 +42,10 @@
 // TR-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize 
[[META6]]
 // TR-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META6]]
 // TR-NEXT:    [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]]
-// TR-NEXT:    [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), 
!nosanitize [[META6]]
+// TR-NEXT:    [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 28), 
!nosanitize [[META6]]
 // TR-NEXT:    [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META6]]
 // TR-NEXT:    [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META6]]
-// TR-NEXT:    [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), 
!nosanitize [[META6]]
+// TR-NEXT:    [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 42), 
!nosanitize [[META6]]
 // TR-NEXT:    [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META6]]
 // TR-NEXT:    [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META6]]
 // TR-NEXT:    [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META6]]
@@ -64,10 +64,10 @@
 // REC-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize 
[[META6]]
 // REC-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META6]]
 // REC-NEXT:    [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]]
-// REC-NEXT:    [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), 
!nosanitize [[META6]]
+// REC-NEXT:    [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 28), 
!nosanitize [[META6]]
 // REC-NEXT:    [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META6]]
 // REC-NEXT:    [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META6]]
-// REC-NEXT:    [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), 
!nosanitize [[META6]]
+// REC-NEXT:    [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 42), 
!nosanitize [[META6]]
 // REC-NEXT:    [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META6]]
 // REC-NEXT:    [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META6]]
 // REC-NEXT:    [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META6]]
@@ -91,7 +91,7 @@ int div(int x, int y) {
 // CHECK-SAME: ptr nofree noundef readonly captures(address_is_null) 
[[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META6]]
-// CHECK-NEXT:    [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), 
!nosanitize [[META6]]
+// CHECK-NEXT:    [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 30), 
!nosanitize [[META6]]
 // CHECK-NEXT:    [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]]
 // CHECK-NEXT:    br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], 
label %[[CONT:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META6]]
 // CHECK:       [[HANDLER_TYPE_MISMATCH]]:
@@ -105,7 +105,7 @@ int div(int x, int y) {
 // TR-SAME: ptr nofree noundef readonly captures(address_is_null) [[X:%.*]]) 
local_unnamed_addr #[[ATTR3:[0-9]+]] {
 // TR-NEXT:  [[ENTRY:.*:]]
 // TR-NEXT:    [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META6]]
-// TR-NEXT:    [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), 
!nosanitize [[META6]]
+// TR-NEXT:    [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 30), 
!nosanitize [[META6]]
 // TR-NEXT:    [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]]
 // TR-NEXT:    br i1 [[DOTNOT1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!prof [[PROF8:![0-9]+]], !nosanitize [[META6]]
 // TR:       [[TRAP]]:
@@ -119,7 +119,7 @@ int div(int x, int y) {
 // REC-SAME: ptr nofree noundef readonly captures(address_is_null) [[X:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
 // REC-NEXT:  [[ENTRY:.*:]]
 // REC-NEXT:    [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META6]]
-// REC-NEXT:    [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), 
!nosanitize [[META6]]
+// REC-NEXT:    [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 30), 
!nosanitize [[META6]]
 // REC-NEXT:    [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]]
 // REC-NEXT:    br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label 
%[[CONT:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META6]]
 // REC:       [[HANDLER_TYPE_MISMATCH]]:
@@ -140,7 +140,7 @@ int null(int* x) {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META6]]
-// CHECK-NEXT:    [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), 
!nosanitize [[META6]]
+// CHECK-NEXT:    [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 42), 
!nosanitize [[META6]]
 // CHECK-NEXT:    [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]]
 // CHECK-NEXT:    br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], 
label %[[CONT:.*]], !prof [[PROF8]], !nosanitize [[META6]]
 // CHECK:       [[HANDLER_ADD_OVERFLOW]]:
@@ -157,7 +157,7 @@ int null(int* x) {
 // TR-NEXT:  [[ENTRY:.*:]]
 // TR-NEXT:    [[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META6]]
 // TR-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META6]]
-// TR-NEXT:    [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), 
!nosanitize [[META6]]
+// TR-NEXT:    [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 42), 
!nosanitize [[META6]]
 // TR-NEXT:    [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]]
 // TR-NEXT:    br i1 [[DOTDEMORGAN]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!prof [[PROF8]], !nosanitize [[META6]]
 // TR:       [[TRAP]]:
@@ -172,7 +172,7 @@ int null(int* x) {
 // REC-NEXT:  [[ENTRY:.*:]]
 // REC-NEXT:    [[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META6]]
 // REC-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META6]]
-// REC-NEXT:    [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), 
!nosanitize [[META6]]
+// REC-NEXT:    [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 42), 
!nosanitize [[META6]]
 // REC-NEXT:    [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]]
 // REC-NEXT:    br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], 
label %[[CONT:.*]], !prof [[PROF8]], !nosanitize [[META6]]
 // REC:       [[HANDLER_ADD_OVERFLOW]]:
@@ -200,7 +200,7 @@ void use(double*);
 // CHECK-NEXT:    call void @use(ptr noundef nonnull [[VLA]]) #[[ATTR7:[0-9]+]]
 // CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[I]] to i64
 // CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i64 [[TMP0]], [[IDXPROM]]
-// CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 71), 
!nosanitize [[META6]]
+// CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 72), 
!nosanitize [[META6]]
 // CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]], !nosanitize 
[[META6]]
 // CHECK-NEXT:    br i1 [[TMP3]], label %[[TRAP:.*]], label %[[BB4:.*]]
 // CHECK:       [[BB4]]:
@@ -219,7 +219,7 @@ void use(double*);
 // TR-NEXT:    call void @use(ptr noundef nonnull [[VLA]]) #[[ATTR8:[0-9]+]]
 // TR-NEXT:    [[IDXPROM:%.*]] = sext i32 [[I]] to i64
 // TR-NEXT:    [[TMP1:%.*]] = icmp ule i64 [[TMP0]], [[IDXPROM]]
-// TR-NEXT:    [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 71), 
!nosanitize [[META6]]
+// TR-NEXT:    [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 72), 
!nosanitize [[META6]]
 // TR-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]]
 // TR-NEXT:    br i1 [[TMP3]], label %[[TRAP:.*]], label %[[BB4:.*]]
 // TR:       [[BB4]]:
@@ -227,7 +227,7 @@ void use(double*);
 // TR-NEXT:    [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa 
[[DOUBLE_TBAA10:![0-9]+]]
 // TR-NEXT:    ret double [[TMP5]]
 // TR:       [[TRAP]]:
-// TR-NEXT:    call void @llvm.ubsantrap(i8 71) #[[ATTR7]], !nosanitize 
[[META6]]
+// TR-NEXT:    call void @llvm.ubsantrap(i8 72) #[[ATTR7]], !nosanitize 
[[META6]]
 // TR-NEXT:    unreachable, !nosanitize [[META6]]
 //
 // REC-LABEL: define dso_local double @lbounds(
@@ -238,7 +238,7 @@ void use(double*);
 // REC-NEXT:    call void @use(ptr noundef nonnull [[VLA]]) #[[ATTR5:[0-9]+]]
 // REC-NEXT:    [[IDXPROM:%.*]] = sext i32 [[I]] to i64
 // REC-NEXT:    [[TMP1:%.*]] = icmp ule i64 [[TMP0]], [[IDXPROM]]
-// REC-NEXT:    [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 71), 
!nosanitize [[META6]]
+// REC-NEXT:    [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 72), 
!nosanitize [[META6]]
 // REC-NEXT:    [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]]
 // REC-NEXT:    br i1 [[TMP3]], label %[[TRAP:.*]], label %[[BB4:.*]]
 // REC:       [[BB4]]:
diff --git 
a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/amdgcn-amd-amdhsa/libclang_rt.csan.a
 
b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/amdgcn-amd-amdhsa/libclang_rt.csan.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/amdgpu-toolchain.c 
b/clang/test/Driver/amdgpu-toolchain.c
index 135129b739603..ef6bd854dd031 100644
--- a/clang/test/Driver/amdgpu-toolchain.c
+++ b/clang/test/Driver/amdgpu-toolchain.c
@@ -63,3 +63,10 @@
 // RUN:   | FileCheck -check-prefixes=UBSAN %s
 //      UBSAN: ld.lld
 // UBSAN-SAME: 
"[[RESOURCE_DIR:.+]]{{/|\\\\}}lib{{/|\\\\}}amdgcn-amd-amdhsa{{/|\\\\}}libclang_rt.ubsan_minimal.a"
+
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \
+// RUN:   -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   -fsanitize=concurrency %s 2>&1 \
+// RUN:   | FileCheck -check-prefixes=CSAN %s
+//      CSAN: ld.lld
+// CSAN-SAME: 
"[[RESOURCE_DIR:.+]]{{/|\\\\}}lib{{/|\\\\}}amdgcn-amd-amdhsa{{/|\\\\}}libclang_rt.csan.a"
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index f6a82d899d5bf..6e34c868608c4 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -292,6 +292,11 @@
 // RUN: not %clang --target=i386-apple-tvos-simulator -fsanitize=thread %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-I386-TVOSSIMULATOR
 // CHECK-TSAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=thread' for 
target 'i386-apple-tvos-simulator'
 
+// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=concurrency %s -### 
2>&1 | FileCheck %s --check-prefix=CHECK-CSAN-X86-64-LINUX
+// CHECK-CSAN-X86-64-LINUX: unsupported option '-fsanitize=concurrency' for 
target 'x86_64-unknown-linux-gnu'
+// RUN: not %clang --target=aarch64-apple-darwin -fsanitize=concurrency %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-CSAN-AARCH64-DARWIN
+// CHECK-CSAN-AARCH64-DARWIN: unsupported option '-fsanitize=concurrency' for 
target 'arm64-apple-darwin'
+
 // RUN: %clang --target=x86_64-linux-gnu -fsanitize=thread 
-fsanitize-thread-memory-access %s -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-TSAN-MEMORY-ACCESS
 // CHECK-TSAN-MEMORY-ACCESS-NOT: -cc1{{.*}}tsan-instrument-memory-accesses=0
 // CHECK-TSAN-MEMORY-ACCESS-NOT: -cc1{{.*}}tsan-instrument-memintrinsics=0

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to