From 3838f279053d7351f7a5ee64eb94bcf2f2805de0 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Wed, 13 Feb 2013 05:59:45 +0000 Subject: [PATCH] [tsan] disable load widening in ThreadSanitizer mode llvm-svn: 175034 --- .../lib/Analysis/MemoryDependenceAnalysis.cpp | 6 +++++ .../ThreadSanitizer/tsan-vs-gvn.ll | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 llvm/test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 5cb001688552..9a1edc763f18 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -283,6 +283,12 @@ getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs, const DataLayout &TD) { // We can only extend simple integer loads. if (!isa(LI->getType()) || !LI->isSimple()) return 0; + + // Load widening is hostile to ThreadSanitizer: it may cause false positives + // or make the reports more cryptic (access sizes are wrong). + if (LI->getParent()->getParent()->getAttributes(). + hasAttribute(AttributeSet::FunctionIndex, Attribute::ThreadSafety)) + return 0; // Get the base of this load. int64_t LIOffs = 0; diff --git a/llvm/test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll b/llvm/test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll new file mode 100644 index 000000000000..2eee6a5e7300 --- /dev/null +++ b/llvm/test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll @@ -0,0 +1,26 @@ +; RUN: opt < %s -basicaa -gvn -tsan -S | FileCheck %s +; TSAN conflicts with load widening. Make sure the load widening is off with -tsan. + +; 32-bit little endian target. +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" + +%struct_of_8_bytes_4_aligned = type { i32, i8, i8, i8, i8} + +@f = global %struct_of_8_bytes_4_aligned zeroinitializer, align 4 + +; Accessing bytes 4 and 6, not ok to widen to i32 if thread_safety is set. + +define i32 @test_widening_bad(i8* %P) nounwind ssp noredzone thread_safety { +entry: + %tmp = load i8* getelementptr inbounds (%struct_of_8_bytes_4_aligned* @f, i64 0, i32 1), align 4 + %conv = zext i8 %tmp to i32 + %tmp1 = load i8* getelementptr inbounds (%struct_of_8_bytes_4_aligned* @f, i64 0, i32 3), align 1 + %conv2 = zext i8 %tmp1 to i32 + %add = add nsw i32 %conv, %conv2 + ret i32 %add +; CHECK: @test_widening_bad +; CHECK: call void @__tsan_read1 +; CHECK: call void @__tsan_read1 +; CHECK-NOT: call void @__tsan_read4 +; CHECK: ret i32 +}