[compiler-rt] [llvm] [ASan][compiler-rt] Implemented Dormant Mode in ASan (PR #99857)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 14 03:26:52 PDT 2024


https://github.com/gbMattN updated https://github.com/llvm/llvm-project/pull/99857

>From 992d2cb9dc349ce83ba9cc07212efef38ec88189 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Mon, 22 Jul 2024 10:13:51 +0000
Subject: [PATCH 01/14] [ASan][compiler-rt] Implemented Dormant Mode in ASan

---
 .../include/sanitizer/asan_interface.h        |  7 +++
 compiler-rt/lib/asan/asan_interface.inc       |  1 +
 .../lib/asan/asan_interface_internal.h        |  6 +++
 compiler-rt/lib/asan/asan_rtl.cpp             |  3 ++
 .../Instrumentation/AddressSanitizer.cpp      | 48 +++++++++++++++++--
 5 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index 37b6d08f4db193..f6ca4acb03e9de 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -269,6 +269,13 @@ void SANITIZER_CDECL __asan_set_death_callback(void (*callback)(void));
 void SANITIZER_CDECL
 __asan_set_error_report_callback(void (*callback)(const char *));
 
+/// Sets whether ASan should be dormant or not. If 0 is passed, ASan resumes
+/// checking memory accesses for errors. If a non-0 value is passed, these
+/// checks will be skipped.
+///
+/// \param dormancy A boolean to control if ASan is dormant or not.
+void SANITIZER_CDECL __asan_set_dormant(int dormancy);
+
 /// User-provided callback on ASan errors.
 ///
 /// You can provide a function that would be called immediately when ASan
diff --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc
index bfc44b46196232..499014fcc4a49d 100644
--- a/compiler-rt/lib/asan/asan_interface.inc
+++ b/compiler-rt/lib/asan/asan_interface.inc
@@ -107,6 +107,7 @@ INTERFACE_FUNCTION(__asan_report_store16_noabort)
 INTERFACE_FUNCTION(__asan_report_store_n_noabort)
 INTERFACE_FUNCTION(__asan_set_death_callback)
 INTERFACE_FUNCTION(__asan_set_error_report_callback)
+INTERFACE_FUNCTION(__asan_set_dormant)
 INTERFACE_FUNCTION(__asan_set_shadow_00)
 INTERFACE_FUNCTION(__asan_set_shadow_01)
 INTERFACE_FUNCTION(__asan_set_shadow_02)
diff --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h
index a9982637802217..9b2752ce7e05bd 100644
--- a/compiler-rt/lib/asan/asan_interface_internal.h
+++ b/compiler-rt/lib/asan/asan_interface_internal.h
@@ -184,6 +184,9 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   void __asan_set_error_report_callback(void (*callback)(const char*));
 
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_dormant(int dormancy);
+
   SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
   void __asan_on_error();
 
@@ -202,6 +205,9 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   extern uptr *__asan_test_only_reported_buggy_pointer;
 
+  SANITIZER_INTERFACE_ATTRIBUTE
+  extern bool __asan_is_dormant;
+
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1(uptr p);
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2(uptr p);
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4(uptr p);
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index d42a75e9e5211a..f242a337a86c2f 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -36,6 +36,9 @@
 uptr __asan_shadow_memory_dynamic_address;  // Global interface symbol.
 int __asan_option_detect_stack_use_after_return;  // Global interface symbol.
 uptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.
+bool __asan_is_dormant = true;
+
+void __asan_set_dormant(int dormancy) { __asan_is_dormant = dormancy; }
 
 namespace __asan {
 
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 5fc4d826e00158..780c2ed1746228 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -179,6 +179,8 @@ const char kAMDGPUAddressPrivateName[] = "llvm.amdgcn.is.private";
 const char kAMDGPUBallotName[] = "llvm.amdgcn.ballot.i64";
 const char kAMDGPUUnreachableName[] = "llvm.amdgcn.unreachable";
 
+const char kAsanDormancyVarName[] = "__asan_is_dormant";
+
 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
 static const size_t kNumberOfAccessSizes = 5;
 
@@ -453,6 +455,10 @@ static cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"),
 static cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug max inst"),
                                cl::Hidden, cl::init(-1));
 
+static cl::opt<bool> CLAsanDormant("asan-dormant",
+                                   cl::desc("Makes asan dormant"), cl::Hidden,
+                                   cl::init(false));
+
 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
 STATISTIC(NumOptimizedAccessesToGlobalVar,
@@ -855,6 +861,7 @@ struct AddressSanitizer {
 
   FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
   Value *LocalDynamicShadow = nullptr;
+  Constant *DormantAsanFlag;
   const StackSafetyGlobalInfo *SSGI;
   DenseMap<const AllocaInst *, bool> ProcessedAllocas;
 
@@ -1587,6 +1594,12 @@ bool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) {
 void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
     Instruction *I, RuntimeCallInserter &RTCI) {
   IRBuilder<> IRB(I);
+
+  if (CLAsanDormant)
+    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)), I,
+        false));
+
   FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
   Value *Param[2] = {I->getOperand(0), I->getOperand(1)};
   for (Value *&i : Param) {
@@ -1601,9 +1614,19 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
                                 MaybeAlign Alignment, unsigned Granularity,
                                 TypeSize TypeStoreSize, bool IsWrite,
                                 Value *SizeArgument, bool UseCalls,
-                                uint32_t Exp, RuntimeCallInserter &RTCI) {
+                                uint32_t Exp, RuntimeCallInserter &RTCI,
+                                Value *DormantAsanFlag) {
   // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
   // if the data is properly aligned.
+
+  Instruction *InsertPoint = InsertBefore;
+  if (CLAsanDormant) {
+    InstrumentationIRBuilder IRB(InsertPoint);
+    InsertPoint = SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertBefore, false);
+  }
+
   if (!TypeStoreSize.isScalable()) {
     const auto FixedSize = TypeStoreSize.getFixedValue();
     switch (FixedSize) {
@@ -1614,12 +1637,12 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
     case 128:
       if (!Alignment || *Alignment >= Granularity ||
           *Alignment >= FixedSize / 8)
-        return Pass->instrumentAddress(I, InsertBefore, Addr, Alignment,
+        return Pass->instrumentAddress(I, InsertPoint, Addr, Alignment,
                                        FixedSize, IsWrite, nullptr, UseCalls,
                                        Exp, RTCI);
     }
   }
-  Pass->instrumentUnusualSizeOrAlignment(I, InsertBefore, Addr, TypeStoreSize,
+  Pass->instrumentUnusualSizeOrAlignment(I, InsertPoint, Addr, TypeStoreSize,
                                          IsWrite, nullptr, UseCalls, Exp, RTCI);
 }
 
@@ -1635,6 +1658,14 @@ void AddressSanitizer::instrumentMaskedLoadOrStore(
 
   IRBuilder IB(I);
   Instruction *LoopInsertBefore = I;
+
+  if (CLAsanDormant) {
+    LoopInsertBefore = SplitBlockAndInsertIfThen(
+        IB.CreateNot(IB.CreateLoad(IB.getInt1Ty(), DormantAsanFlag)),
+        LoopInsertBefore, false);
+    IB.SetInsertPoint(LoopInsertBefore);
+  }
+
   if (EVL) {
     // The end argument of SplitBlockAndInsertForLane is assumed bigger
     // than zero, so we should check whether EVL is zero here.
@@ -1685,7 +1716,7 @@ void AddressSanitizer::instrumentMaskedLoadOrStore(
     }
     doInstrumentAddress(Pass, I, &*IRB.GetInsertPoint(), InstrumentedAddress,
                         Alignment, Granularity, ElemTypeSize, IsWrite,
-                        SizeArgument, UseCalls, Exp, RTCI);
+                        SizeArgument, UseCalls, Exp, RTCI, DormantAsanFlag);
   });
 }
 
@@ -1742,7 +1773,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
   } else {
     doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment,
                         Granularity, O.TypeStoreSize, O.IsWrite, nullptr,
-                        UseCalls, Exp, RTCI);
+                        UseCalls, Exp, RTCI, DormantAsanFlag);
   }
 }
 
@@ -1854,6 +1885,11 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
   }
 
   InstrumentationIRBuilder IRB(InsertBefore);
+  if (CLAsanDormant)
+    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertBefore, false));
+
   size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
 
   if (UseCalls && ClOptimizeCallbacks) {
@@ -2863,6 +2899,8 @@ void AddressSanitizer::initializeCallbacks(Module &M, const TargetLibraryInfo *T
       M.getOrInsertFunction(kAMDGPUAddressSharedName, IRB.getInt1Ty(), PtrTy);
   AMDGPUAddressPrivate =
       M.getOrInsertFunction(kAMDGPUAddressPrivateName, IRB.getInt1Ty(), PtrTy);
+
+  DormantAsanFlag = M.getOrInsertGlobal(kAsanDormancyVarName, IRB.getInt1Ty());
 }
 
 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {

>From c8355a276df51d6952ffe767c31ec26ec99cbfc1 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Mon, 22 Jul 2024 14:37:42 +0000
Subject: [PATCH 02/14] Added compiler-rt side test

---
 compiler-rt/test/asan/TestCases/dormant.cpp | 37 +++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 compiler-rt/test/asan/TestCases/dormant.cpp

diff --git a/compiler-rt/test/asan/TestCases/dormant.cpp b/compiler-rt/test/asan/TestCases/dormant.cpp
new file mode 100644
index 00000000000000..5efa2f9836a24b
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/dormant.cpp
@@ -0,0 +1,37 @@
+// RUN: %clangxx_asan -DREAD -O0 -mllvm -asan-dormant %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-READ
+// RUN: %clangxx_asan -O0 -mllvm -asan-dormant %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WRITE
+// REQUIRES: stable-runtime
+
+#include <sanitizer/asan_interface.h>
+int readHeapAfterFree(){
+  int * volatile x = new int[10];
+  delete[] x;
+  return x[5];
+}
+
+static int * volatile y;
+int writeHeapAfterFree(){
+  y = new int[10];
+  delete[] y;
+  return y[5] = 413;
+}
+
+int main() {
+#ifdef READ
+  readHeapAfterFree();
+  // CHECK-READCHECK-NOT {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+  __asan_set_dormant(false);
+  readHeapAfterFree();
+  // CHECK-READ: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+
+#else
+
+  writeHeapAfterFree();
+  // CHECK-WRITE-NOT {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+  __asan_set_dormant(false);
+  writeHeapAfterFree();
+  // CHECK-WRITE: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+#endif
+
+  return 0;
+}

>From 960c610eca66559e7f4759e10b5a1870cc453c87 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Wed, 7 Aug 2024 15:38:59 +0000
Subject: [PATCH 03/14] Fixed a codegen bug

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

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 780c2ed1746228..911f4f8ad63981 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1885,10 +1885,6 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
   }
 
   InstrumentationIRBuilder IRB(InsertBefore);
-  if (CLAsanDormant)
-    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
-        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertBefore, false));
 
   size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
 
@@ -1972,6 +1968,11 @@ void AddressSanitizer::instrumentUnusualSizeOrAlignment(
     TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls,
     uint32_t Exp, RuntimeCallInserter &RTCI) {
   InstrumentationIRBuilder IRB(InsertBefore);
+  if (CLAsanDormant)
+    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertBefore, false));
+
   Value *NumBits = IRB.CreateTypeSize(IntptrTy, TypeStoreSize);
   Value *Size = IRB.CreateLShr(NumBits, ConstantInt::get(IntptrTy, 3));
 

>From 3d0736cd0a60f7f0f78a14982091e5687e2be7da Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Thu, 8 Aug 2024 10:17:29 +0000
Subject: [PATCH 04/14] Tidied changes and added comment

---
 compiler-rt/lib/asan/asan_rtl.cpp                        | 2 +-
 llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index f242a337a86c2f..afd27dd076816d 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -36,7 +36,7 @@
 uptr __asan_shadow_memory_dynamic_address;  // Global interface symbol.
 int __asan_option_detect_stack_use_after_return;  // Global interface symbol.
 uptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.
-bool __asan_is_dormant = true;
+bool __asan_is_dormant = true;  // Used only if compiling with dormant asan
 
 void __asan_set_dormant(int dormancy) { __asan_is_dormant = dormancy; }
 
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 911f4f8ad63981..bf3286996c5f83 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1618,7 +1618,6 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
                                 Value *DormantAsanFlag) {
   // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
   // if the data is properly aligned.
-
   Instruction *InsertPoint = InsertBefore;
   if (CLAsanDormant) {
     InstrumentationIRBuilder IRB(InsertPoint);
@@ -1885,7 +1884,6 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
   }
 
   InstrumentationIRBuilder IRB(InsertBefore);
-
   size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
 
   if (UseCalls && ClOptimizeCallbacks) {

>From 31d25a403c249735fc9eeed88bb792450f112188 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Fri, 9 Aug 2024 09:58:58 +0000
Subject: [PATCH 05/14] Added llvm test

---
 .../AddressSanitizer/dormant.ll               | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 llvm/test/Instrumentation/AddressSanitizer/dormant.ll

diff --git a/llvm/test/Instrumentation/AddressSanitizer/dormant.ll b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
new file mode 100644
index 00000000000000..e7015296530e46
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
@@ -0,0 +1,82 @@
+; RUN: opt < %s -passes=asan -asan-dormant -S | FileCheck --check-prefixes=CHECK %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: mustprogress noinline nounwind optnone uwtable
+define dso_local i32 @test(ptr %a) sanitize_address {
+entry:
+  %a.addr = alloca ptr, align 8
+  store ptr %a, ptr %a.addr, align 8
+  %0 = load ptr, ptr %a.addr, align 8
+  store i32 5, ptr %0, align 4
+  %1 = load ptr, ptr %a.addr, align 8
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
+
+
+; CHECK: %a.addr = alloca ptr, align 8
+; CHECK: store ptr %a, ptr %a.addr, align 8
+; CHECK:   %0 = load ptr, ptr %a.addr, align 8
+; CHECK:   %1 = load i1, ptr @__asan_is_dormant, align 1
+; CHECK:   %2 = xor i1 %1, true
+; CHECK:   br i1 %2, label %3, label %17
+
+; CHECK:   %4 = ptrtoint ptr %0 to i64
+; CHECK:   %5 = lshr i64 %4, 3
+; CHECK:   %6 = add i64 %5, 2147450880
+; CHECK:   %7 = inttoptr i64 %6 to ptr
+; CHECK:   %8 = load i8, ptr %7, align 1
+; CHECK:   %9 = icmp ne i8 %8, 0
+; CHECK:   br i1 %9, label %10, label %16, !prof !6
+
+; CHECK:   %11 = and i64 %4, 7
+; CHECK:   %12 = add i64 %11, 3
+; CHECK:   %13 = trunc i64 %12 to i8
+; CHECK:   %14 = icmp sge i8 %13, %8
+; CHECK:   br i1 %14, label %15, label %16
+
+; CHECK:   call void @__asan_report_store4(i64 %4) #3
+; CHECK:   unreachable
+
+; CHECK:   br label %17
+
+; CHECK:   store i32 5, ptr %0, align 4
+; CHECK:   %18 = load ptr, ptr %a.addr, align 8
+; CHECK:   %19 = load i1, ptr @__asan_is_dormant, align 1
+; CHECK:   %20 = xor i1 %19, true
+; CHECK:   br i1 %20, label %21, label %35
+
+; CHECK:   %22 = ptrtoint ptr %18 to i64
+; CHECK:   %23 = lshr i64 %22, 3
+; CHECK:   %24 = add i64 %23, 2147450880
+; CHECK:   %25 = inttoptr i64 %24 to ptr
+; CHECK:   %26 = load i8, ptr %25, align 1
+; CHECK:   %27 = icmp ne i8 %26, 0
+; CHECK:   br i1 %27, label %28, label %34, !prof !6
+
+; CHECK:   %29 = and i64 %22, 7
+; CHECK:   %30 = add i64 %29, 3
+; CHECK:   %31 = trunc i64 %30 to i8
+; CHECK:   %32 = icmp sge i8 %31, %26
+; CHECK:   br i1 %32, label %33, label %34
+
+; CHECK:   call void @__asan_report_load4(i64 %22) #3
+; CHECK:   unreachable
+
+; CHECK:   br label %35
+
+; CHECK:   %36 = load i32, ptr %18, align 4
+; CHECK:   ret i32 %36
+
+}
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4}
+!llvm.ident = !{!5}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{i32 7, !"frame-pointer", i32 2}
+!5 = !{!"clang version 20.0.0git (https://github.com/gbMattN/llvm-project.git 3d0736cd0a60f7f0f78a14982091e5687e2be7da)"}

>From f99eebef7102395315d3419d03df408704b21e09 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Mon, 12 Aug 2024 12:20:42 +0000
Subject: [PATCH 06/14] Another change in where the branch happens

---
 .../Instrumentation/AddressSanitizer.cpp      | 31 ++++++-------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index bf3286996c5f83..221c23bf13b04a 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1619,12 +1619,6 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
   // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
   // if the data is properly aligned.
   Instruction *InsertPoint = InsertBefore;
-  if (CLAsanDormant) {
-    InstrumentationIRBuilder IRB(InsertPoint);
-    InsertPoint = SplitBlockAndInsertIfThen(
-        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertBefore, false);
-  }
 
   if (!TypeStoreSize.isScalable()) {
     const auto FixedSize = TypeStoreSize.getFixedValue();
@@ -1657,14 +1651,6 @@ void AddressSanitizer::instrumentMaskedLoadOrStore(
 
   IRBuilder IB(I);
   Instruction *LoopInsertBefore = I;
-
-  if (CLAsanDormant) {
-    LoopInsertBefore = SplitBlockAndInsertIfThen(
-        IB.CreateNot(IB.CreateLoad(IB.getInt1Ty(), DormantAsanFlag)),
-        LoopInsertBefore, false);
-    IB.SetInsertPoint(LoopInsertBefore);
-  }
-
   if (EVL) {
     // The end argument of SplitBlockAndInsertForLane is assumed bigger
     // than zero, so we should check whether EVL is zero here.
@@ -1762,15 +1748,23 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
     NumInstrumentedWrites++;
   else
     NumInstrumentedReads++;
+  
+  Instruction* InsertPoint = O.getInsn();
+  if(CLAsanDormant){
+    InstrumentationIRBuilder IRB(InsertPoint);
+    InsertPoint = SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertPoint, false);
+  }
 
   unsigned Granularity = 1 << Mapping.Scale;
   if (O.MaybeMask) {
     instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.MaybeEVL,
-                                O.MaybeStride, O.getInsn(), Addr, O.Alignment,
+                                O.MaybeStride, InsertPoint, Addr, O.Alignment,
                                 Granularity, O.OpType, O.IsWrite, nullptr,
                                 UseCalls, Exp, RTCI);
   } else {
-    doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment,
+    doInstrumentAddress(this, InsertPoint, InsertPoint, Addr, O.Alignment,
                         Granularity, O.TypeStoreSize, O.IsWrite, nullptr,
                         UseCalls, Exp, RTCI, DormantAsanFlag);
   }
@@ -1966,11 +1960,6 @@ void AddressSanitizer::instrumentUnusualSizeOrAlignment(
     TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls,
     uint32_t Exp, RuntimeCallInserter &RTCI) {
   InstrumentationIRBuilder IRB(InsertBefore);
-  if (CLAsanDormant)
-    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
-        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertBefore, false));
-
   Value *NumBits = IRB.CreateTypeSize(IntptrTy, TypeStoreSize);
   Value *Size = IRB.CreateLShr(NumBits, ConstantInt::get(IntptrTy, 3));
 

>From 8e58ea9d35a1ce354cdee33ab40e197eaa70fe8a Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Mon, 22 Jul 2024 10:13:51 +0000
Subject: [PATCH 07/14] [ASan][compiler-rt] Implemented Dormant Mode in ASan

---
 .../include/sanitizer/asan_interface.h        |  7 +++
 compiler-rt/lib/asan/asan_interface.inc       |  1 +
 .../lib/asan/asan_interface_internal.h        |  6 +++
 compiler-rt/lib/asan/asan_rtl.cpp             |  3 ++
 .../Instrumentation/AddressSanitizer.cpp      | 48 +++++++++++++++++--
 5 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index 37b6d08f4db193..f6ca4acb03e9de 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -269,6 +269,13 @@ void SANITIZER_CDECL __asan_set_death_callback(void (*callback)(void));
 void SANITIZER_CDECL
 __asan_set_error_report_callback(void (*callback)(const char *));
 
+/// Sets whether ASan should be dormant or not. If 0 is passed, ASan resumes
+/// checking memory accesses for errors. If a non-0 value is passed, these
+/// checks will be skipped.
+///
+/// \param dormancy A boolean to control if ASan is dormant or not.
+void SANITIZER_CDECL __asan_set_dormant(int dormancy);
+
 /// User-provided callback on ASan errors.
 ///
 /// You can provide a function that would be called immediately when ASan
diff --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc
index bfc44b46196232..499014fcc4a49d 100644
--- a/compiler-rt/lib/asan/asan_interface.inc
+++ b/compiler-rt/lib/asan/asan_interface.inc
@@ -107,6 +107,7 @@ INTERFACE_FUNCTION(__asan_report_store16_noabort)
 INTERFACE_FUNCTION(__asan_report_store_n_noabort)
 INTERFACE_FUNCTION(__asan_set_death_callback)
 INTERFACE_FUNCTION(__asan_set_error_report_callback)
+INTERFACE_FUNCTION(__asan_set_dormant)
 INTERFACE_FUNCTION(__asan_set_shadow_00)
 INTERFACE_FUNCTION(__asan_set_shadow_01)
 INTERFACE_FUNCTION(__asan_set_shadow_02)
diff --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h
index a9982637802217..9b2752ce7e05bd 100644
--- a/compiler-rt/lib/asan/asan_interface_internal.h
+++ b/compiler-rt/lib/asan/asan_interface_internal.h
@@ -184,6 +184,9 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   void __asan_set_error_report_callback(void (*callback)(const char*));
 
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_dormant(int dormancy);
+
   SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
   void __asan_on_error();
 
@@ -202,6 +205,9 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   extern uptr *__asan_test_only_reported_buggy_pointer;
 
+  SANITIZER_INTERFACE_ATTRIBUTE
+  extern bool __asan_is_dormant;
+
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1(uptr p);
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2(uptr p);
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4(uptr p);
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index d42a75e9e5211a..f242a337a86c2f 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -36,6 +36,9 @@
 uptr __asan_shadow_memory_dynamic_address;  // Global interface symbol.
 int __asan_option_detect_stack_use_after_return;  // Global interface symbol.
 uptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.
+bool __asan_is_dormant = true;
+
+void __asan_set_dormant(int dormancy) { __asan_is_dormant = dormancy; }
 
 namespace __asan {
 
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index d1bb1334aae6a3..343c9029146561 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -178,6 +178,8 @@ const char kAMDGPUAddressPrivateName[] = "llvm.amdgcn.is.private";
 const char kAMDGPUBallotName[] = "llvm.amdgcn.ballot.i64";
 const char kAMDGPUUnreachableName[] = "llvm.amdgcn.unreachable";
 
+const char kAsanDormancyVarName[] = "__asan_is_dormant";
+
 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
 static const size_t kNumberOfAccessSizes = 5;
 
@@ -452,6 +454,10 @@ static cl::opt<int> ClDebugMin("asan-debug-min", cl::desc("Debug min inst"),
 static cl::opt<int> ClDebugMax("asan-debug-max", cl::desc("Debug max inst"),
                                cl::Hidden, cl::init(-1));
 
+static cl::opt<bool> CLAsanDormant("asan-dormant",
+                                   cl::desc("Makes asan dormant"), cl::Hidden,
+                                   cl::init(false));
+
 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
 STATISTIC(NumOptimizedAccessesToGlobalVar,
@@ -852,6 +858,7 @@ struct AddressSanitizer {
 
   FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
   Value *LocalDynamicShadow = nullptr;
+  Constant *DormantAsanFlag;
   const StackSafetyGlobalInfo *SSGI;
   DenseMap<const AllocaInst *, bool> ProcessedAllocas;
 
@@ -1584,6 +1591,12 @@ bool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) {
 void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
     Instruction *I, RuntimeCallInserter &RTCI) {
   IRBuilder<> IRB(I);
+
+  if (CLAsanDormant)
+    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)), I,
+        false));
+
   FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
   Value *Param[2] = {I->getOperand(0), I->getOperand(1)};
   for (Value *&i : Param) {
@@ -1598,9 +1611,19 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
                                 MaybeAlign Alignment, unsigned Granularity,
                                 TypeSize TypeStoreSize, bool IsWrite,
                                 Value *SizeArgument, bool UseCalls,
-                                uint32_t Exp, RuntimeCallInserter &RTCI) {
+                                uint32_t Exp, RuntimeCallInserter &RTCI,
+                                Value *DormantAsanFlag) {
   // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
   // if the data is properly aligned.
+
+  Instruction *InsertPoint = InsertBefore;
+  if (CLAsanDormant) {
+    InstrumentationIRBuilder IRB(InsertPoint);
+    InsertPoint = SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertBefore, false);
+  }
+
   if (!TypeStoreSize.isScalable()) {
     const auto FixedSize = TypeStoreSize.getFixedValue();
     switch (FixedSize) {
@@ -1611,12 +1634,12 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
     case 128:
       if (!Alignment || *Alignment >= Granularity ||
           *Alignment >= FixedSize / 8)
-        return Pass->instrumentAddress(I, InsertBefore, Addr, Alignment,
+        return Pass->instrumentAddress(I, InsertPoint, Addr, Alignment,
                                        FixedSize, IsWrite, nullptr, UseCalls,
                                        Exp, RTCI);
     }
   }
-  Pass->instrumentUnusualSizeOrAlignment(I, InsertBefore, Addr, TypeStoreSize,
+  Pass->instrumentUnusualSizeOrAlignment(I, InsertPoint, Addr, TypeStoreSize,
                                          IsWrite, nullptr, UseCalls, Exp, RTCI);
 }
 
@@ -1632,6 +1655,14 @@ void AddressSanitizer::instrumentMaskedLoadOrStore(
 
   IRBuilder IB(I);
   Instruction *LoopInsertBefore = I;
+
+  if (CLAsanDormant) {
+    LoopInsertBefore = SplitBlockAndInsertIfThen(
+        IB.CreateNot(IB.CreateLoad(IB.getInt1Ty(), DormantAsanFlag)),
+        LoopInsertBefore, false);
+    IB.SetInsertPoint(LoopInsertBefore);
+  }
+
   if (EVL) {
     // The end argument of SplitBlockAndInsertForLane is assumed bigger
     // than zero, so we should check whether EVL is zero here.
@@ -1682,7 +1713,7 @@ void AddressSanitizer::instrumentMaskedLoadOrStore(
     }
     doInstrumentAddress(Pass, I, &*IRB.GetInsertPoint(), InstrumentedAddress,
                         Alignment, Granularity, ElemTypeSize, IsWrite,
-                        SizeArgument, UseCalls, Exp, RTCI);
+                        SizeArgument, UseCalls, Exp, RTCI, DormantAsanFlag);
   });
 }
 
@@ -1739,7 +1770,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
   } else {
     doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment,
                         Granularity, O.TypeStoreSize, O.IsWrite, nullptr,
-                        UseCalls, Exp, RTCI);
+                        UseCalls, Exp, RTCI, DormantAsanFlag);
   }
 }
 
@@ -1851,6 +1882,11 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
   }
 
   InstrumentationIRBuilder IRB(InsertBefore);
+  if (CLAsanDormant)
+    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertBefore, false));
+
   size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
 
   if (UseCalls && ClOptimizeCallbacks) {
@@ -2860,6 +2896,8 @@ void AddressSanitizer::initializeCallbacks(Module &M, const TargetLibraryInfo *T
       M.getOrInsertFunction(kAMDGPUAddressSharedName, IRB.getInt1Ty(), PtrTy);
   AMDGPUAddressPrivate =
       M.getOrInsertFunction(kAMDGPUAddressPrivateName, IRB.getInt1Ty(), PtrTy);
+
+  DormantAsanFlag = M.getOrInsertGlobal(kAsanDormancyVarName, IRB.getInt1Ty());
 }
 
 bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {

>From 50fe1fc77473e892c7cf018779a4ffe89e3c6986 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Mon, 22 Jul 2024 14:37:42 +0000
Subject: [PATCH 08/14] Added compiler-rt side test

---
 compiler-rt/test/asan/TestCases/dormant.cpp | 37 +++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 compiler-rt/test/asan/TestCases/dormant.cpp

diff --git a/compiler-rt/test/asan/TestCases/dormant.cpp b/compiler-rt/test/asan/TestCases/dormant.cpp
new file mode 100644
index 00000000000000..5efa2f9836a24b
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/dormant.cpp
@@ -0,0 +1,37 @@
+// RUN: %clangxx_asan -DREAD -O0 -mllvm -asan-dormant %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-READ
+// RUN: %clangxx_asan -O0 -mllvm -asan-dormant %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WRITE
+// REQUIRES: stable-runtime
+
+#include <sanitizer/asan_interface.h>
+int readHeapAfterFree(){
+  int * volatile x = new int[10];
+  delete[] x;
+  return x[5];
+}
+
+static int * volatile y;
+int writeHeapAfterFree(){
+  y = new int[10];
+  delete[] y;
+  return y[5] = 413;
+}
+
+int main() {
+#ifdef READ
+  readHeapAfterFree();
+  // CHECK-READCHECK-NOT {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+  __asan_set_dormant(false);
+  readHeapAfterFree();
+  // CHECK-READ: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+
+#else
+
+  writeHeapAfterFree();
+  // CHECK-WRITE-NOT {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+  __asan_set_dormant(false);
+  writeHeapAfterFree();
+  // CHECK-WRITE: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+#endif
+
+  return 0;
+}

>From 3106aacd4526e1f66e6674670ee099f9775e42e0 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Wed, 7 Aug 2024 15:38:59 +0000
Subject: [PATCH 09/14] Fixed a codegen bug

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

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 343c9029146561..5762903dd19b1d 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1882,10 +1882,6 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
   }
 
   InstrumentationIRBuilder IRB(InsertBefore);
-  if (CLAsanDormant)
-    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
-        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertBefore, false));
 
   size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
 
@@ -1969,6 +1965,11 @@ void AddressSanitizer::instrumentUnusualSizeOrAlignment(
     TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls,
     uint32_t Exp, RuntimeCallInserter &RTCI) {
   InstrumentationIRBuilder IRB(InsertBefore);
+  if (CLAsanDormant)
+    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertBefore, false));
+
   Value *NumBits = IRB.CreateTypeSize(IntptrTy, TypeStoreSize);
   Value *Size = IRB.CreateLShr(NumBits, ConstantInt::get(IntptrTy, 3));
 

>From 619b3d75dc4cd0a9310b270296d70a1c1c49f65c Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Thu, 8 Aug 2024 10:17:29 +0000
Subject: [PATCH 10/14] Tidied changes and added comment

---
 compiler-rt/lib/asan/asan_rtl.cpp                        | 2 +-
 llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index f242a337a86c2f..afd27dd076816d 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -36,7 +36,7 @@
 uptr __asan_shadow_memory_dynamic_address;  // Global interface symbol.
 int __asan_option_detect_stack_use_after_return;  // Global interface symbol.
 uptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.
-bool __asan_is_dormant = true;
+bool __asan_is_dormant = true;  // Used only if compiling with dormant asan
 
 void __asan_set_dormant(int dormancy) { __asan_is_dormant = dormancy; }
 
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 5762903dd19b1d..4afb882aa48693 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1615,7 +1615,6 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
                                 Value *DormantAsanFlag) {
   // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
   // if the data is properly aligned.
-
   Instruction *InsertPoint = InsertBefore;
   if (CLAsanDormant) {
     InstrumentationIRBuilder IRB(InsertPoint);
@@ -1882,7 +1881,6 @@ void AddressSanitizer::instrumentAddress(Instruction *OrigIns,
   }
 
   InstrumentationIRBuilder IRB(InsertBefore);
-
   size_t AccessSizeIndex = TypeStoreSizeToSizeIndex(TypeStoreSize);
 
   if (UseCalls && ClOptimizeCallbacks) {

>From 330f9a345f3e406104bbd360161c5500f0ed9d3a Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Fri, 9 Aug 2024 09:58:58 +0000
Subject: [PATCH 11/14] Added llvm test

---
 .../AddressSanitizer/dormant.ll               | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 llvm/test/Instrumentation/AddressSanitizer/dormant.ll

diff --git a/llvm/test/Instrumentation/AddressSanitizer/dormant.ll b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
new file mode 100644
index 00000000000000..e7015296530e46
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
@@ -0,0 +1,82 @@
+; RUN: opt < %s -passes=asan -asan-dormant -S | FileCheck --check-prefixes=CHECK %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: mustprogress noinline nounwind optnone uwtable
+define dso_local i32 @test(ptr %a) sanitize_address {
+entry:
+  %a.addr = alloca ptr, align 8
+  store ptr %a, ptr %a.addr, align 8
+  %0 = load ptr, ptr %a.addr, align 8
+  store i32 5, ptr %0, align 4
+  %1 = load ptr, ptr %a.addr, align 8
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
+
+
+; CHECK: %a.addr = alloca ptr, align 8
+; CHECK: store ptr %a, ptr %a.addr, align 8
+; CHECK:   %0 = load ptr, ptr %a.addr, align 8
+; CHECK:   %1 = load i1, ptr @__asan_is_dormant, align 1
+; CHECK:   %2 = xor i1 %1, true
+; CHECK:   br i1 %2, label %3, label %17
+
+; CHECK:   %4 = ptrtoint ptr %0 to i64
+; CHECK:   %5 = lshr i64 %4, 3
+; CHECK:   %6 = add i64 %5, 2147450880
+; CHECK:   %7 = inttoptr i64 %6 to ptr
+; CHECK:   %8 = load i8, ptr %7, align 1
+; CHECK:   %9 = icmp ne i8 %8, 0
+; CHECK:   br i1 %9, label %10, label %16, !prof !6
+
+; CHECK:   %11 = and i64 %4, 7
+; CHECK:   %12 = add i64 %11, 3
+; CHECK:   %13 = trunc i64 %12 to i8
+; CHECK:   %14 = icmp sge i8 %13, %8
+; CHECK:   br i1 %14, label %15, label %16
+
+; CHECK:   call void @__asan_report_store4(i64 %4) #3
+; CHECK:   unreachable
+
+; CHECK:   br label %17
+
+; CHECK:   store i32 5, ptr %0, align 4
+; CHECK:   %18 = load ptr, ptr %a.addr, align 8
+; CHECK:   %19 = load i1, ptr @__asan_is_dormant, align 1
+; CHECK:   %20 = xor i1 %19, true
+; CHECK:   br i1 %20, label %21, label %35
+
+; CHECK:   %22 = ptrtoint ptr %18 to i64
+; CHECK:   %23 = lshr i64 %22, 3
+; CHECK:   %24 = add i64 %23, 2147450880
+; CHECK:   %25 = inttoptr i64 %24 to ptr
+; CHECK:   %26 = load i8, ptr %25, align 1
+; CHECK:   %27 = icmp ne i8 %26, 0
+; CHECK:   br i1 %27, label %28, label %34, !prof !6
+
+; CHECK:   %29 = and i64 %22, 7
+; CHECK:   %30 = add i64 %29, 3
+; CHECK:   %31 = trunc i64 %30 to i8
+; CHECK:   %32 = icmp sge i8 %31, %26
+; CHECK:   br i1 %32, label %33, label %34
+
+; CHECK:   call void @__asan_report_load4(i64 %22) #3
+; CHECK:   unreachable
+
+; CHECK:   br label %35
+
+; CHECK:   %36 = load i32, ptr %18, align 4
+; CHECK:   ret i32 %36
+
+}
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4}
+!llvm.ident = !{!5}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{i32 7, !"frame-pointer", i32 2}
+!5 = !{!"clang version 20.0.0git (https://github.com/gbMattN/llvm-project.git 3d0736cd0a60f7f0f78a14982091e5687e2be7da)"}

>From 2d89edd910a8cd383745b25868f82073771643b2 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Mon, 12 Aug 2024 12:20:42 +0000
Subject: [PATCH 12/14] Another change in where the branch happens

---
 .../Instrumentation/AddressSanitizer.cpp      | 31 ++++++-------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 4afb882aa48693..c730c9a1f8820c 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1616,12 +1616,6 @@ static void doInstrumentAddress(AddressSanitizer *Pass, Instruction *I,
   // Instrument a 1-, 2-, 4-, 8-, or 16- byte access with one check
   // if the data is properly aligned.
   Instruction *InsertPoint = InsertBefore;
-  if (CLAsanDormant) {
-    InstrumentationIRBuilder IRB(InsertPoint);
-    InsertPoint = SplitBlockAndInsertIfThen(
-        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertBefore, false);
-  }
 
   if (!TypeStoreSize.isScalable()) {
     const auto FixedSize = TypeStoreSize.getFixedValue();
@@ -1654,14 +1648,6 @@ void AddressSanitizer::instrumentMaskedLoadOrStore(
 
   IRBuilder IB(I);
   Instruction *LoopInsertBefore = I;
-
-  if (CLAsanDormant) {
-    LoopInsertBefore = SplitBlockAndInsertIfThen(
-        IB.CreateNot(IB.CreateLoad(IB.getInt1Ty(), DormantAsanFlag)),
-        LoopInsertBefore, false);
-    IB.SetInsertPoint(LoopInsertBefore);
-  }
-
   if (EVL) {
     // The end argument of SplitBlockAndInsertForLane is assumed bigger
     // than zero, so we should check whether EVL is zero here.
@@ -1759,15 +1745,23 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
     NumInstrumentedWrites++;
   else
     NumInstrumentedReads++;
+  
+  Instruction* InsertPoint = O.getInsn();
+  if(CLAsanDormant){
+    InstrumentationIRBuilder IRB(InsertPoint);
+    InsertPoint = SplitBlockAndInsertIfThen(
+        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
+        InsertPoint, false);
+  }
 
   unsigned Granularity = 1 << Mapping.Scale;
   if (O.MaybeMask) {
     instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.MaybeEVL,
-                                O.MaybeStride, O.getInsn(), Addr, O.Alignment,
+                                O.MaybeStride, InsertPoint, Addr, O.Alignment,
                                 Granularity, O.OpType, O.IsWrite, nullptr,
                                 UseCalls, Exp, RTCI);
   } else {
-    doInstrumentAddress(this, O.getInsn(), O.getInsn(), Addr, O.Alignment,
+    doInstrumentAddress(this, InsertPoint, InsertPoint, Addr, O.Alignment,
                         Granularity, O.TypeStoreSize, O.IsWrite, nullptr,
                         UseCalls, Exp, RTCI, DormantAsanFlag);
   }
@@ -1963,11 +1957,6 @@ void AddressSanitizer::instrumentUnusualSizeOrAlignment(
     TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls,
     uint32_t Exp, RuntimeCallInserter &RTCI) {
   InstrumentationIRBuilder IRB(InsertBefore);
-  if (CLAsanDormant)
-    IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
-        IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertBefore, false));
-
   Value *NumBits = IRB.CreateTypeSize(IntptrTy, TypeStoreSize);
   Value *Size = IRB.CreateLShr(NumBits, ConstantInt::get(IntptrTy, 3));
 

>From e4a3c6a962abc1c75c5fdbb233d1825c2e73d2a6 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Wed, 14 Aug 2024 09:45:46 +0000
Subject: [PATCH 13/14] Ran the test generator and added branch weights

---
 .../Instrumentation/AddressSanitizer.cpp      |   4 +-
 .../AddressSanitizer/dormant.ll               | 116 +++++++++---------
 2 files changed, 63 insertions(+), 57 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index c730c9a1f8820c..cc8c7366acb0f6 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1595,7 +1595,7 @@ void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
   if (CLAsanDormant)
     IRB.SetInsertPoint(SplitBlockAndInsertIfThen(
         IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)), I,
-        false));
+        false, MDBuilder(*C).createUnlikelyBranchWeights()));
 
   FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction;
   Value *Param[2] = {I->getOperand(0), I->getOperand(1)};
@@ -1751,7 +1751,7 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
     InstrumentationIRBuilder IRB(InsertPoint);
     InsertPoint = SplitBlockAndInsertIfThen(
         IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-        InsertPoint, false);
+        InsertPoint, false, MDBuilder(*C).createUnlikelyBranchWeights());
   }
 
   unsigned Granularity = 1 << Mapping.Scale;
diff --git a/llvm/test/Instrumentation/AddressSanitizer/dormant.ll b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
index e7015296530e46..ed3f88decdb748 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 ; RUN: opt < %s -passes=asan -asan-dormant -S | FileCheck --check-prefixes=CHECK %s
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
@@ -5,6 +6,63 @@ target triple = "x86_64-unknown-linux-gnu"
 
 ; Function Attrs: mustprogress noinline nounwind optnone uwtable
 define dso_local i32 @test(ptr %a) sanitize_address {
+; CHECK-LABEL: define dso_local i32 @test(
+; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8
+; CHECK-NEXT:    store ptr [[A]], ptr [[A_ADDR]], align 8
+; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = load i1, ptr @__asan_is_dormant, align 1
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i1 [[TMP1]], true
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[BB3:.*]], label %[[BB17:.*]]
+; CHECK:       [[BB3]]:
+; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[TMP0]] to i64
+; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 3
+; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[TMP5]], 2147450880
+; CHECK-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
+; CHECK-NEXT:    [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 1
+; CHECK-NEXT:    [[TMP9:%.*]] = icmp ne i8 [[TMP8]], 0
+; CHECK-NEXT:    br i1 [[TMP9]], label %[[BB10:.*]], label %[[BB16:.*]], !prof [[PROF7:![0-9]+]]
+; CHECK:       [[BB10]]:
+; CHECK-NEXT:    [[TMP11:%.*]] = and i64 [[TMP4]], 7
+; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[TMP11]], 3
+; CHECK-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
+; CHECK-NEXT:    [[TMP14:%.*]] = icmp sge i8 [[TMP13]], [[TMP8]]
+; CHECK-NEXT:    br i1 [[TMP14]], label %[[BB15:.*]], label %[[BB16]]
+; CHECK:       [[BB15]]:
+; CHECK-NEXT:    call void @__asan_report_store4(i64 [[TMP4]]) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BB16]]:
+; CHECK-NEXT:    br label %[[BB17]]
+; CHECK:       [[BB17]]:
+; CHECK-NEXT:    store i32 5, ptr [[TMP0]], align 4
+; CHECK-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[A_ADDR]], align 8
+; CHECK-NEXT:    [[TMP19:%.*]] = load i1, ptr @__asan_is_dormant, align 1
+; CHECK-NEXT:    [[TMP20:%.*]] = xor i1 [[TMP19]], true
+; CHECK-NEXT:    br i1 [[TMP20]], label %[[BB21:.*]], label %[[BB35:.*]]
+; CHECK:       [[BB21]]:
+; CHECK-NEXT:    [[TMP22:%.*]] = ptrtoint ptr [[TMP18]] to i64
+; CHECK-NEXT:    [[TMP23:%.*]] = lshr i64 [[TMP22]], 3
+; CHECK-NEXT:    [[TMP24:%.*]] = add i64 [[TMP23]], 2147450880
+; CHECK-NEXT:    [[TMP25:%.*]] = inttoptr i64 [[TMP24]] to ptr
+; CHECK-NEXT:    [[TMP26:%.*]] = load i8, ptr [[TMP25]], align 1
+; CHECK-NEXT:    [[TMP27:%.*]] = icmp ne i8 [[TMP26]], 0
+; CHECK-NEXT:    br i1 [[TMP27]], label %[[BB28:.*]], label %[[BB34:.*]], !prof [[PROF7]]
+; CHECK:       [[BB28]]:
+; CHECK-NEXT:    [[TMP29:%.*]] = and i64 [[TMP22]], 7
+; CHECK-NEXT:    [[TMP30:%.*]] = add i64 [[TMP29]], 3
+; CHECK-NEXT:    [[TMP31:%.*]] = trunc i64 [[TMP30]] to i8
+; CHECK-NEXT:    [[TMP32:%.*]] = icmp sge i8 [[TMP31]], [[TMP26]]
+; CHECK-NEXT:    br i1 [[TMP32]], label %[[BB33:.*]], label %[[BB34]]
+; CHECK:       [[BB33]]:
+; CHECK-NEXT:    call void @__asan_report_load4(i64 [[TMP22]]) #[[ATTR3]]
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BB34]]:
+; CHECK-NEXT:    br label %[[BB35]]
+; CHECK:       [[BB35]]:
+; CHECK-NEXT:    [[TMP36:%.*]] = load i32, ptr [[TMP18]], align 4
+; CHECK-NEXT:    ret i32 [[TMP36]]
+;
 entry:
   %a.addr = alloca ptr, align 8
   store ptr %a, ptr %a.addr, align 8
@@ -14,61 +72,6 @@ entry:
   %2 = load i32, ptr %1, align 4
   ret i32 %2
 
-
-; CHECK: %a.addr = alloca ptr, align 8
-; CHECK: store ptr %a, ptr %a.addr, align 8
-; CHECK:   %0 = load ptr, ptr %a.addr, align 8
-; CHECK:   %1 = load i1, ptr @__asan_is_dormant, align 1
-; CHECK:   %2 = xor i1 %1, true
-; CHECK:   br i1 %2, label %3, label %17
-
-; CHECK:   %4 = ptrtoint ptr %0 to i64
-; CHECK:   %5 = lshr i64 %4, 3
-; CHECK:   %6 = add i64 %5, 2147450880
-; CHECK:   %7 = inttoptr i64 %6 to ptr
-; CHECK:   %8 = load i8, ptr %7, align 1
-; CHECK:   %9 = icmp ne i8 %8, 0
-; CHECK:   br i1 %9, label %10, label %16, !prof !6
-
-; CHECK:   %11 = and i64 %4, 7
-; CHECK:   %12 = add i64 %11, 3
-; CHECK:   %13 = trunc i64 %12 to i8
-; CHECK:   %14 = icmp sge i8 %13, %8
-; CHECK:   br i1 %14, label %15, label %16
-
-; CHECK:   call void @__asan_report_store4(i64 %4) #3
-; CHECK:   unreachable
-
-; CHECK:   br label %17
-
-; CHECK:   store i32 5, ptr %0, align 4
-; CHECK:   %18 = load ptr, ptr %a.addr, align 8
-; CHECK:   %19 = load i1, ptr @__asan_is_dormant, align 1
-; CHECK:   %20 = xor i1 %19, true
-; CHECK:   br i1 %20, label %21, label %35
-
-; CHECK:   %22 = ptrtoint ptr %18 to i64
-; CHECK:   %23 = lshr i64 %22, 3
-; CHECK:   %24 = add i64 %23, 2147450880
-; CHECK:   %25 = inttoptr i64 %24 to ptr
-; CHECK:   %26 = load i8, ptr %25, align 1
-; CHECK:   %27 = icmp ne i8 %26, 0
-; CHECK:   br i1 %27, label %28, label %34, !prof !6
-
-; CHECK:   %29 = and i64 %22, 7
-; CHECK:   %30 = add i64 %29, 3
-; CHECK:   %31 = trunc i64 %30 to i8
-; CHECK:   %32 = icmp sge i8 %31, %26
-; CHECK:   br i1 %32, label %33, label %34
-
-; CHECK:   call void @__asan_report_load4(i64 %22) #3
-; CHECK:   unreachable
-
-; CHECK:   br label %35
-
-; CHECK:   %36 = load i32, ptr %18, align 4
-; CHECK:   ret i32 %36
-
 }
 
 !llvm.module.flags = !{!0, !1, !2, !3, !4}
@@ -80,3 +83,6 @@ entry:
 !3 = !{i32 7, !"uwtable", i32 2}
 !4 = !{i32 7, !"frame-pointer", i32 2}
 !5 = !{!"clang version 20.0.0git (https://github.com/gbMattN/llvm-project.git 3d0736cd0a60f7f0f78a14982091e5687e2be7da)"}
+;.
+; CHECK: [[PROF7]] = !{!"branch_weights", i32 1, i32 1048575}
+;.

>From 0a86a04632fd41e983ae14c35a4eaceb77ea89b6 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Wed, 14 Aug 2024 10:26:34 +0000
Subject: [PATCH 14/14] post merge-with-main bugs

---
 llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 6 +++---
 llvm/test/Instrumentation/AddressSanitizer/dormant.ll    | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index b5952797cccca2..cc8c7366acb0f6 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1751,11 +1751,11 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
     InstrumentationIRBuilder IRB(InsertPoint);
     InsertPoint = SplitBlockAndInsertIfThen(
         IRB.CreateNot(IRB.CreateLoad(IRB.getInt1Ty(), DormantAsanFlag)),
-<<<<<<< HEAD
-        InsertPoint, false);
-=======
         InsertPoint, false, MDBuilder(*C).createUnlikelyBranchWeights());
+  }
+
   unsigned Granularity = 1 << Mapping.Scale;
+  if (O.MaybeMask) {
     instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.MaybeEVL,
                                 O.MaybeStride, InsertPoint, Addr, O.Alignment,
                                 Granularity, O.OpType, O.IsWrite, nullptr,
diff --git a/llvm/test/Instrumentation/AddressSanitizer/dormant.ll b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
index ed3f88decdb748..707fcbeab3ada7 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/dormant.ll
@@ -14,7 +14,7 @@ define dso_local i32 @test(ptr %a) sanitize_address {
 ; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i1, ptr @__asan_is_dormant, align 1
 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i1 [[TMP1]], true
-; CHECK-NEXT:    br i1 [[TMP2]], label %[[BB3:.*]], label %[[BB17:.*]]
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[BB3:.*]], label %[[BB17:.*]], !prof [[PROF7:![0-9]+]]
 ; CHECK:       [[BB3]]:
 ; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[TMP0]] to i64
 ; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 3
@@ -22,7 +22,7 @@ define dso_local i32 @test(ptr %a) sanitize_address {
 ; CHECK-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
 ; CHECK-NEXT:    [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 1
 ; CHECK-NEXT:    [[TMP9:%.*]] = icmp ne i8 [[TMP8]], 0
-; CHECK-NEXT:    br i1 [[TMP9]], label %[[BB10:.*]], label %[[BB16:.*]], !prof [[PROF7:![0-9]+]]
+; CHECK-NEXT:    br i1 [[TMP9]], label %[[BB10:.*]], label %[[BB16:.*]], !prof [[PROF7]]
 ; CHECK:       [[BB10]]:
 ; CHECK-NEXT:    [[TMP11:%.*]] = and i64 [[TMP4]], 7
 ; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[TMP11]], 3
@@ -39,7 +39,7 @@ define dso_local i32 @test(ptr %a) sanitize_address {
 ; CHECK-NEXT:    [[TMP18:%.*]] = load ptr, ptr [[A_ADDR]], align 8
 ; CHECK-NEXT:    [[TMP19:%.*]] = load i1, ptr @__asan_is_dormant, align 1
 ; CHECK-NEXT:    [[TMP20:%.*]] = xor i1 [[TMP19]], true
-; CHECK-NEXT:    br i1 [[TMP20]], label %[[BB21:.*]], label %[[BB35:.*]]
+; CHECK-NEXT:    br i1 [[TMP20]], label %[[BB21:.*]], label %[[BB35:.*]], !prof [[PROF7]]
 ; CHECK:       [[BB21]]:
 ; CHECK-NEXT:    [[TMP22:%.*]] = ptrtoint ptr [[TMP18]] to i64
 ; CHECK-NEXT:    [[TMP23:%.*]] = lshr i64 [[TMP22]], 3



More information about the llvm-commits mailing list