[PATCH] disable load widening in ThreadSanitizer mode

Kostya Serebryany kcc at google.com
Mon Feb 11 05:12:48 PST 2013


Hi dvyukov, nicholas,

load-widening is unfriendly to ThreadSanitizer, so 
we disable it if ThreadSafety attribute is set. 
This is similar to what we do with AddressSanitizer, 
although with ASAN we do allow some kinds of load widening.
An llvm bitcode test is included. 
A C++ test is at projects/compiler-rt/lib/tsan/lit_tests/tsan-vs-gvn.cc

http://llvm-reviews.chandlerc.com/D391

Files:
  lib/Analysis/MemoryDependenceAnalysis.cpp
  test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll

Index: lib/Analysis/MemoryDependenceAnalysis.cpp
===================================================================
--- lib/Analysis/MemoryDependenceAnalysis.cpp
+++ lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -283,6 +283,12 @@
                                 const DataLayout &TD) {
   // We can only extend simple integer loads.
   if (!isa<IntegerType>(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;
Index: test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll
===================================================================
--- test/Instrumentation/ThreadSanitizer/tsan-vs-gvn.ll
+++ 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}
+
+ at 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
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D391.1.patch
Type: text/x-patch
Size: 2107 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130211/4720ceaf/attachment.bin>


More information about the llvm-commits mailing list