From 151ed6aa38a3ec6c01973b35f684586b6e1c0f7e Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 15 May 2020 14:14:18 +0200 Subject: [PATCH] [TSAN] Add option to allow instrumenting reads of reads-before-writes Add -tsan-instrument-read-before-write which allows instrumenting reads of reads-before-writes. This is required for KCSAN [1], where under certain configurations plain writes behave differently (e.g. aligned writes up to word size may be treated as atomic). In order to avoid missing potential data races due to plain RMW operations ("x++" etc.), we will require instrumenting reads of reads-before-writes. [1] https://github.com/google/ktsan/wiki/KCSAN Author: melver (Marco Elver) Reviewed-in: https://reviews.llvm.org/D79983 --- llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 6 +++++- llvm/test/Instrumentation/ThreadSanitizer/read_before_write.ll | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 793ef44..313fe74 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -72,6 +72,10 @@ static cl::opt ClDistinguishVolatile( "tsan-distinguish-volatile", cl::init(false), cl::desc("Emit special instrumentation for accesses to volatiles"), cl::Hidden); +static cl::opt ClInstrumentReadBeforeWrite( + "tsan-instrument-read-before-write", cl::init(false), + cl::desc("Do not eliminate read instrumentation for read-before-writes"), + cl::Hidden); STATISTIC(NumInstrumentedReads, "Number of instrumented reads"); STATISTIC(NumInstrumentedWrites, "Number of instrumented writes"); @@ -413,7 +417,7 @@ void ThreadSanitizer::chooseInstructionsToInstrument( Value *Addr = Load->getPointerOperand(); if (!shouldInstrumentReadWriteFromAddress(I->getModule(), Addr)) continue; - if (WriteTargets.count(Addr)) { + if (!ClInstrumentReadBeforeWrite && WriteTargets.count(Addr)) { // We will write to this temp, so no reason to analyze the read. NumOmittedReadsBeforeWrite++; continue; diff --git a/llvm/test/Instrumentation/ThreadSanitizer/read_before_write.ll b/llvm/test/Instrumentation/ThreadSanitizer/read_before_write.ll index c15ab13..33c4f3a 100644 --- a/llvm/test/Instrumentation/ThreadSanitizer/read_before_write.ll +++ b/llvm/test/Instrumentation/ThreadSanitizer/read_before_write.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -tsan -S | FileCheck %s +; RUN: opt < %s -tsan -tsan-instrument-read-before-write -S | FileCheck %s --check-prefixes=CHECK,CHECK-UNOPT 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" @@ -11,6 +12,7 @@ entry: } ; CHECK: define void @IncrementMe ; CHECK-NOT: __tsan_read +; CHECK-UNOPT: __tsan_read ; CHECK: __tsan_write ; CHECK: ret void -- 2.7.4