[llvm] [Asan] Skip pre-split coroutine and noop coroutine frame (PR #99415)

Wei Wang via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 18 15:38:54 PDT 2024


https://github.com/apolloww updated https://github.com/llvm/llvm-project/pull/99415

>From 7aab1b7fc23ca24db7a124c085a7e826a00db5de Mon Sep 17 00:00:00 2001
From: Wei Wang <wangwei at meta.com>
Date: Wed, 17 Jul 2024 17:00:19 -0700
Subject: [PATCH 1/3] update

---
 .../Instrumentation/AddressSanitizer.cpp      |  2 ++
 .../AddressSanitizer/skip-coro.ll             | 36 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 llvm/test/Instrumentation/AddressSanitizer/skip-coro.ll

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index adf77f20cb1c7..89cba2b219c25 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2032,6 +2032,7 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
   if (G->isThreadLocal()) return false;
   // For now, just ignore this Global if the alignment is large.
   if (G->getAlign() && *G->getAlign() > getMinRedzoneSizeForGlobal()) return false;
+  if (G->getName() == "NoopCoro.Frame.Const") return false;
 
   // For non-COFF targets, only instrument globals known to be defined by this
   // TU.
@@ -2947,6 +2948,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
   if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
   if (!ClDebugFunc.empty() && ClDebugFunc == F.getName()) return false;
   if (F.getName().starts_with("__asan_")) return false;
+  if (F.isPresplitCoroutine()) return false;
 
   bool FunctionModified = false;
 
diff --git a/llvm/test/Instrumentation/AddressSanitizer/skip-coro.ll b/llvm/test/Instrumentation/AddressSanitizer/skip-coro.ll
new file mode 100644
index 0000000000000..7aaf6ee8c471b
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/skip-coro.ll
@@ -0,0 +1,36 @@
+; Tests that asan skips pre-split coroutine and NoopCoro.Frame
+; RUN: opt < %s -S -passes=coro-early,asan | FileCheck %s
+
+; CHECK: %NoopCoro.Frame = type { ptr, ptr }
+; CHECK: @NoopCoro.Frame.Const = private constant %NoopCoro.Frame { ptr @__NoopCoro_ResumeDestroy, ptr @__NoopCoro_ResumeDestroy }
+; CHECK-NOT: @0 = private alias { %NoopCoro.Frame,
+
+%struct.Promise = type { %"struct.std::__n4861::coroutine_handle" }
+%"struct.std::__n4861::coroutine_handle" = type { ptr }
+
+; CHECK-LABEL: @foo(
+define ptr @foo() #0 {
+; CHECK-NEXT: entry
+; CHECK-NOT: %asan_local_stack_base
+entry:
+  %__promise = alloca %struct.Promise, align 8
+  %0 = call token @llvm.coro.id(i32 16, ptr nonnull %__promise, ptr nonnull @foo, ptr null)
+  %1 = call ptr @llvm.coro.noop()
+  ret ptr %1
+}
+
+declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr)
+declare ptr @llvm.coro.noop()
+
+attributes #0 = { sanitize_address presplitcoroutine }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "hand-written", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "<stdin>", directory: "")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+
+

>From c319847e34b30d45044ee89068ec53525bc65aac Mon Sep 17 00:00:00 2001
From: Wei Wang <wangwei at meta.com>
Date: Wed, 17 Jul 2024 17:36:03 -0700
Subject: [PATCH 2/3] format

---
 llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 89cba2b219c25..81b9aa20fd200 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2032,7 +2032,8 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
   if (G->isThreadLocal()) return false;
   // For now, just ignore this Global if the alignment is large.
   if (G->getAlign() && *G->getAlign() > getMinRedzoneSizeForGlobal()) return false;
-  if (G->getName() == "NoopCoro.Frame.Const") return false;
+  if (G->getName() == "NoopCoro.Frame.Const")
+    return false;
 
   // For non-COFF targets, only instrument globals known to be defined by this
   // TU.
@@ -2948,7 +2949,8 @@ bool AddressSanitizer::instrumentFunction(Function &F,
   if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
   if (!ClDebugFunc.empty() && ClDebugFunc == F.getName()) return false;
   if (F.getName().starts_with("__asan_")) return false;
-  if (F.isPresplitCoroutine()) return false;
+  if (F.isPresplitCoroutine())
+    return false;
 
   bool FunctionModified = false;
 

>From d073eb02481a1ab7e3cabbc04f4776a4f49b107d Mon Sep 17 00:00:00 2001
From: Wei Wang <wangwei at meta.com>
Date: Thu, 18 Jul 2024 15:37:03 -0700
Subject: [PATCH 3/3] add nosan metadata to gv

---
 llvm/lib/Transforms/Coroutines/CoroEarly.cpp             | 1 +
 llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index 489106422e199..d8e827e9cebcf 100644
--- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -148,6 +148,7 @@ void Lowerer::lowerCoroNoop(IntrinsicInst *II) {
     NoopCoro = new GlobalVariable(M, NoopCoroConst->getType(), /*isConstant=*/true,
                                 GlobalVariable::PrivateLinkage, NoopCoroConst,
                                 "NoopCoro.Frame.Const");
+    cast<GlobalVariable>(NoopCoro)->setNoSanitizeMetadata();
   }
 
   Builder.SetInsertPoint(II);
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 81b9aa20fd200..19bcc5e3af981 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2032,8 +2032,6 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
   if (G->isThreadLocal()) return false;
   // For now, just ignore this Global if the alignment is large.
   if (G->getAlign() && *G->getAlign() > getMinRedzoneSizeForGlobal()) return false;
-  if (G->getName() == "NoopCoro.Frame.Const")
-    return false;
 
   // For non-COFF targets, only instrument globals known to be defined by this
   // TU.



More information about the llvm-commits mailing list