[clang] 62ced81 - [Sanitizer] Make sanitizer passes idempotent (#99439)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 11 22:46:48 PDT 2024
Author: Chaitanya
Date: 2024-08-12T11:16:44+05:30
New Revision: 62ced8116ba5274991af0e94cfdf873593c7764d
URL: https://github.com/llvm/llvm-project/commit/62ced8116ba5274991af0e94cfdf873593c7764d
DIFF: https://github.com/llvm/llvm-project/commit/62ced8116ba5274991af0e94cfdf873593c7764d.diff
LOG: [Sanitizer] Make sanitizer passes idempotent (#99439)
This PR changes the sanitizer passes to be idempotent.
When any sanitizer pass is run after it has already been run before,
double instrumentation is seen in the resulting IR. This happens because
there is no check in the pass, to verify if IR has been instrumented
before.
This PR checks if "nosanitize_*" module flag is already present and if
true, return early without running the pass again.
Added:
llvm/test/Instrumentation/AddressSanitizer/asan-pass-second-run.ll
llvm/test/Instrumentation/DataFlowSanitizer/dfsan-pass-second-run.ll
llvm/test/Instrumentation/HWAddressSanitizer/hwasan-pass-second-run.ll
llvm/test/Instrumentation/MemorySanitizer/msan-pass-second-run.ll
llvm/test/Instrumentation/ThreadSanitizer/tsan-pass-second-run.ll
Modified:
clang/test/CodeGenObjC/no-sanitize.m
llvm/include/llvm/Transforms/Instrumentation.h
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll
Removed:
################################################################################
diff --git a/clang/test/CodeGenObjC/no-sanitize.m b/clang/test/CodeGenObjC/no-sanitize.m
index abaf6fab26ab61..b5c6a5ad745f3e 100644
--- a/clang/test/CodeGenObjC/no-sanitize.m
+++ b/clang/test/CodeGenObjC/no-sanitize.m
@@ -2,7 +2,7 @@
@interface I0 @end
@implementation I0
-// CHECK-NOT: sanitize_address
+// CHECK-NOT: Function Attrs: sanitize_address
- (void) im0: (int) a0 __attribute__((no_sanitize("address"))) {
int (^blockName)(void) = ^int(void) { return 0; };
}
diff --git a/llvm/include/llvm/Transforms/Instrumentation.h b/llvm/include/llvm/Transforms/Instrumentation.h
index 969c2cd12f3f08..885d3249fb4f83 100644
--- a/llvm/include/llvm/Transforms/Instrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation.h
@@ -30,6 +30,10 @@ class Triple;
class OptimizationRemarkEmitter;
class Comdat;
class CallBase;
+class Module;
+
+/// Check if module has flag attached, if not add the flag.
+bool checkIfAlreadyInstrumented(Module &M, StringRef Flag);
/// Instrumentation passes often insert conditional checks into entry blocks.
/// Call this function before splitting the entry block to move instructions
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 67dd2b2052472c..d1bb1334aae6a3 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1251,6 +1251,11 @@ AddressSanitizerPass::AddressSanitizerPass(
PreservedAnalyses AddressSanitizerPass::run(Module &M,
ModuleAnalysisManager &MAM) {
+ // Return early if nosanitize_address module flag is present for the module.
+ // This implies that asan pass has already run before.
+ if (checkIfAlreadyInstrumented(M, "nosanitize_address"))
+ return PreservedAnalyses::all();
+
ModuleAddressSanitizer ModuleSanitizer(
M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 113d39b4f2af7b..b4b5f67d2e62da 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -3473,6 +3473,9 @@ void DFSanVisitor::visitPHINode(PHINode &PN) {
PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
ModuleAnalysisManager &AM) {
+ // Return early if nosanitize_dataflow module flag is present for the module.
+ if (checkIfAlreadyInstrumented(M, "nosanitize_dataflow"))
+ return PreservedAnalyses::all();
auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
auto &FAM =
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 812874ff3c1739..95433a216b168d 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -57,6 +57,7 @@
#include "llvm/Support/RandomNumberGenerator.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -455,6 +456,9 @@ class HWAddressSanitizer {
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
ModuleAnalysisManager &MAM) {
+ // Return early if nosanitize_hwaddress module flag is present for the module.
+ if (checkIfAlreadyInstrumented(M, "nosanitize_hwaddress"))
+ return PreservedAnalyses::all();
const StackSafetyGlobalInfo *SSI = nullptr;
auto TargetTriple = llvm::Triple(M.getTargetTriple());
if (shouldUseStackSafetyAnalysis(TargetTriple, Options.DisableOptimization))
diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
index b842d9eef407c2..19f4d8064fc27d 100644
--- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp
@@ -12,12 +12,47 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/TargetParser/Triple.h"
using namespace llvm;
+static cl::opt<bool> ClIgnoreRedundantInstrumentation(
+ "ignore-redundant-instrumentation",
+ cl::desc("Ignore redundant instrumentation"), cl::Hidden, cl::init(false));
+
+namespace {
+/// Diagnostic information for IR instrumentation reporting.
+class DiagnosticInfoInstrumentation : public DiagnosticInfo {
+ const Twine &Msg;
+
+public:
+ DiagnosticInfoInstrumentation(const Twine &DiagMsg,
+ DiagnosticSeverity Severity = DS_Warning)
+ : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
+ void print(DiagnosticPrinter &DP) const override { DP << Msg; }
+};
+} // namespace
+
+/// Check if module has flag attached, if not add the flag.
+bool llvm::checkIfAlreadyInstrumented(Module &M, StringRef Flag) {
+ if (!M.getModuleFlag(Flag)) {
+ M.addModuleFlag(Module::ModFlagBehavior::Override, Flag, 1);
+ return false;
+ }
+ if (ClIgnoreRedundantInstrumentation)
+ return true;
+ std::string diagInfo =
+ "Redundant instrumentation detected, with module flag: " +
+ std::string(Flag);
+ M.getContext().diagnose(
+ DiagnosticInfoInstrumentation(diagInfo, DiagnosticSeverity::DS_Warning));
+ return true;
+}
+
/// Moves I before IP. Returns new insert point.
static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, BasicBlock::iterator IP) {
// If I is IP, move the insert point down.
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 38d5006ab9e4d3..0b3d85afcacf1f 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -198,6 +198,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -706,6 +707,9 @@ MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
PreservedAnalyses MemorySanitizerPass::run(Module &M,
ModuleAnalysisManager &AM) {
+ // Return early if nosanitize_memory module flag is present for the module.
+ if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
+ return PreservedAnalyses::all();
bool Modified = false;
if (!Options.Kernel) {
insertModuleCtor(M);
diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 92e533d2281af8..67385219545202 100644
--- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -191,6 +191,9 @@ PreservedAnalyses ThreadSanitizerPass::run(Function &F,
PreservedAnalyses ModuleThreadSanitizerPass::run(Module &M,
ModuleAnalysisManager &MAM) {
+ // Return early if nosanitize_thread module flag is present for the module.
+ if (checkIfAlreadyInstrumented(M, "nosanitize_thread"))
+ return PreservedAnalyses::all();
insertModuleCtor(M);
return PreservedAnalyses::none();
}
diff --git a/llvm/test/Instrumentation/AddressSanitizer/asan-pass-second-run.ll b/llvm/test/Instrumentation/AddressSanitizer/asan-pass-second-run.ll
new file mode 100644
index 00000000000000..60ef1079624d79
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/asan-pass-second-run.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
+; This test checks in the second run, function is not instrumented again.
+; RUN: opt < %s -passes=asan,asan -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function with sanitize_address is instrumented.
+; Function Attrs: nounwind uwtable
+;.
+; CHECK: @___asan_globals_registered = common hidden global i64 0
+; CHECK: @__start_asan_globals = extern_weak hidden global i64
+; CHECK: @__stop_asan_globals = extern_weak hidden global i64
+;.
+define void @instr_sa(ptr %a) sanitize_address {
+; CHECK: Function Attrs: sanitize_address
+; CHECK-LABEL: define void @instr_sa(
+; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 2147450880
+; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
+; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
+; CHECK-NEXT: br i1 [[TMP5]], label %[[BB6:.*]], label %[[BB12:.*]], !prof [[PROF1:![0-9]+]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[TMP7:%.*]] = and i64 [[TMP0]], 7
+; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], 3
+; CHECK-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i8
+; CHECK-NEXT: [[TMP10:%.*]] = icmp sge i8 [[TMP9]], [[TMP4]]
+; CHECK-NEXT: br i1 [[TMP10]], label %[[BB11:.*]], label %[[BB12]]
+; CHECK: [[BB11]]:
+; CHECK-NEXT: call void @__asan_report_load4(i64 [[TMP0]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: unreachable
+; CHECK: [[BB12]]:
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; CHECK-NEXT: store i32 [[TMP2]], ptr [[A]], align 4
+; CHECK-NEXT: ret void
+;
+entry:
+ %tmp1 = load i32, ptr %a, align 4
+ %tmp2 = add i32 %tmp1, 1
+ store i32 %tmp2, ptr %a, align 4
+ ret void
+}
+;.
+; CHECK: attributes #[[ATTR0]] = { sanitize_address }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; CHECK: attributes #[[ATTR2]] = { nomerge }
+;.
+; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_address", i32 1}
+; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1048575}
+;.
diff --git a/llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll b/llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll
index 762f91c156dd8e..f6553322fd6787 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll
@@ -34,4 +34,4 @@ entry:
!4 = !DISubroutineType(types: !5)
!5 = !{}
-; CHECK: [[DBG]] = !DILocation(line: 0, scope: !3)
+; CHECK: [[DBG]] = !DILocation(line: 0, scope: !4)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/dfsan-pass-second-run.ll b/llvm/test/Instrumentation/DataFlowSanitizer/dfsan-pass-second-run.ll
new file mode 100644
index 00000000000000..7da647be24bbcc
--- /dev/null
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/dfsan-pass-second-run.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -passes=dfsan,dfsan -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i8 @add(i8 %a, i8 %b) {
+ ; CHECK: @add.dfsan
+ ; CHECK-DAG: %[[#ALABEL:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
+ ; CHECK-DAG: %[[#BLABEL:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
+ ; CHECK: %[[#UNION:]] = or i8 %[[#ALABEL]], %[[#BLABEL]]
+ ; CHECK: %c = add i8 %a, %b
+ ; CHECK: store i8 %[[#UNION]], ptr @__dfsan_retval_tls, align [[ALIGN]]
+ ; CHECK: ret i8 %c
+ %c = add i8 %a, %b
+ ret i8 %c
+}
+
+; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_dataflow", i32 1}
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/hwasan-pass-second-run.ll b/llvm/test/Instrumentation/HWAddressSanitizer/hwasan-pass-second-run.ll
new file mode 100644
index 00000000000000..00614b603fe799
--- /dev/null
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/hwasan-pass-second-run.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2
+; Test basic address sanitizer instrumentation.
+;
+; RUN: opt < %s -passes=hwasan,hwasan -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+;.
+; CHECK: @llvm.used = appending global [1 x ptr] [ptr @hwasan.module_ctor], section "llvm.metadata"
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @hwasan.module_ctor, ptr @hwasan.module_ctor }]
+; CHECK: @__start_hwasan_globals = external hidden constant [0 x i8]
+; CHECK: @__stop_hwasan_globals = external hidden constant [0 x i8]
+; CHECK: @hwasan.note = private constant { i32, i32, i32, [8 x i8], i32, i32 } { i32 8, i32 8, i32 3, [8 x i8] c"LLVM\00\00\00\00", i32 trunc (i64 sub (i64 ptrtoint (ptr @__start_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @__stop_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32) }, section ".note.hwasan.globals", comdat($hwasan.module_ctor), align 4
+; CHECK: @hwasan.dummy.global = private constant [0 x i8] zeroinitializer, section "hwasan_globals", comdat($hwasan.module_ctor), !associated [[META0:![0-9]+]]
+; CHECK: @__hwasan_tls = external thread_local(initialexec) global i64
+; CHECK: @llvm.compiler.used = appending global [3 x ptr] [ptr @hwasan.note, ptr @hwasan.dummy.global, ptr @__hwasan_tls], section "llvm.metadata"
+; CHECK: @__hwasan_shadow = external global [0 x i8]
+;.
+define i8 @test_load8(ptr %a) sanitize_hwaddress {
+; CHECK: Function Attrs: sanitize_hwaddress
+; CHECK-LABEL: define i8 @test_load8
+; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
+; CHECK-NEXT: call void @__hwasan_load1(i64 [[TMP0]])
+; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 4
+; CHECK-NEXT: ret i8 [[B]]
+;
+entry:
+ %b = load i8, ptr %a, align 4
+ ret i8 %b
+}
+;.
+; CHECK: attributes #[[ATTR0]] = { sanitize_hwaddress }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
+;.
+; CHECK: [[META0]] = !{ptr @hwasan.note}
+; CHECK: [[META1:![0-9]+]] = !{i32 4, !"nosanitize_hwaddress", i32 1}
+;.
diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan-pass-second-run.ll b/llvm/test/Instrumentation/MemorySanitizer/msan-pass-second-run.ll
new file mode 100644
index 00000000000000..5c135d63e56fd3
--- /dev/null
+++ b/llvm/test/Instrumentation/MemorySanitizer/msan-pass-second-run.ll
@@ -0,0 +1,43 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
+; This test checks in the second run, function is not instrumented again.
+; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan,msan | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+;.
+; CHECK: @llvm.used = appending global [1 x ptr] [ptr @msan.module_ctor], section "llvm.metadata"
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @msan.module_ctor, ptr null }]
+; CHECK: @__msan_retval_tls = external thread_local(initialexec) global [100 x i64]
+; CHECK: @__msan_retval_origin_tls = external thread_local(initialexec) global i32
+; CHECK: @__msan_param_tls = external thread_local(initialexec) global [100 x i64]
+; CHECK: @__msan_param_origin_tls = external thread_local(initialexec) global [200 x i32]
+; CHECK: @__msan_va_arg_tls = external thread_local(initialexec) global [100 x i64]
+; CHECK: @__msan_va_arg_origin_tls = external thread_local(initialexec) global [200 x i32]
+; CHECK: @__msan_va_arg_overflow_size_tls = external thread_local(initialexec) global i64
+;.
+define void @array() sanitize_memory {
+; CHECK: Function Attrs: sanitize_memory
+; CHECK-LABEL: define void @array(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: call void @llvm.donothing()
+; CHECK-NEXT: [[X:%.*]] = alloca i32, i64 5, align 4
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[X]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = xor i64 [[TMP0]], 87960930222080
+; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP2]], i8 -1, i64 20, i1 false)
+; CHECK-NEXT: ret void
+;
+entry:
+ %x = alloca i32, i64 5, align 4
+ ret void
+}
+;.
+; CHECK: attributes #[[ATTR0]] = { sanitize_memory }
+; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
+; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(none) }
+; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
+;.
+; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_memory", i32 1}
+;.
diff --git a/llvm/test/Instrumentation/ThreadSanitizer/tsan-pass-second-run.ll b/llvm/test/Instrumentation/ThreadSanitizer/tsan-pass-second-run.ll
new file mode 100644
index 00000000000000..9614a418480ec8
--- /dev/null
+++ b/llvm/test/Instrumentation/ThreadSanitizer/tsan-pass-second-run.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2
+; RUN: opt < %s -passes=tsan-module,tsan-module -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+declare void @can_throw()
+declare void @cannot_throw() nounwind
+
+;.
+; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tsan.module_ctor], section "llvm.metadata"
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tsan.module_ctor, ptr null }]
+;.
+define i32 @func1() sanitize_thread {
+; CHECK: Function Attrs: sanitize_thread
+; CHECK-LABEL: define i32 @func1
+; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: call void @can_throw()
+; CHECK-NEXT: ret i32 0
+;
+ call void @can_throw()
+ ret i32 0
+}
+;.
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
+; CHECK: attributes #[[ATTR1]] = { sanitize_thread }
+;.
+; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_thread", i32 1}
+;.
More information about the cfe-commits
mailing list