Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[tsan] Cast floating-point types correctly when instrumenting atomic …
…accesses, LLVM part Although rare, atomic accesses to floating-point types seem to be valid, i.e. `%a = load atomic float ...`. The TSan instrumentation pass however tries to emit inttoptr, which is incorrect, we should use a bitcast here. Anyway, IRBuilder already has a convenient helper function for this. Differential Revision: https://reviews.llvm.org/D26266 llvm-svn: 286135
- Loading branch information
1 parent
f530e8b
commit 44e875a
Showing
2 changed files
with
57 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
llvm/test/Instrumentation/ThreadSanitizer/atomic-non-integer.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
; RUN: opt < %s -tsan -S | FileCheck %s | ||
; Check that atomic memory operations on floating-point types are converted to calls into ThreadSanitizer runtime. | ||
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" | ||
|
||
define float @load_float(float* %fptr) { | ||
%v = load atomic float, float* %fptr unordered, align 4 | ||
ret float %v | ||
; CHECK-LABEL: load_float | ||
; CHECK: call i32 @__tsan_atomic32_load(i32* %{{.+}}, i32 0) | ||
; CHECK: bitcast i32 {{.+}} to float | ||
} | ||
|
||
define double @load_double(double* %fptr) { | ||
%v = load atomic double, double* %fptr unordered, align 8 | ||
ret double %v | ||
; CHECK-LABEL: load_double | ||
; CHECK: call i64 @__tsan_atomic64_load(i64* %{{.+}}, i32 0) | ||
; CHECK: bitcast i64 {{.+}} to double | ||
} | ||
|
||
define fp128 @load_fp128(fp128* %fptr) { | ||
%v = load atomic fp128, fp128* %fptr unordered, align 16 | ||
ret fp128 %v | ||
; CHECK-LABEL: load_fp128 | ||
; CHECK: call i128 @__tsan_atomic128_load(i128* %{{.+}}, i32 0) | ||
; CHECK: bitcast i128 {{.+}} to fp128 | ||
} | ||
|
||
define void @store_float(float* %fptr, float %v) { | ||
store atomic float %v, float* %fptr unordered, align 4 | ||
ret void | ||
; CHECK-LABEL: store_float | ||
; CHECK: bitcast float %v to i32 | ||
; CHECK: call void @__tsan_atomic32_store(i32* %{{.+}}, i32 %{{.+}}, i32 0) | ||
} | ||
|
||
define void @store_double(double* %fptr, double %v) { | ||
store atomic double %v, double* %fptr unordered, align 8 | ||
ret void | ||
; CHECK-LABEL: store_double | ||
; CHECK: bitcast double %v to i64 | ||
; CHECK: call void @__tsan_atomic64_store(i64* %{{.+}}, i64 %{{.+}}, i32 0) | ||
} | ||
|
||
define void @store_fp128(fp128* %fptr, fp128 %v) { | ||
store atomic fp128 %v, fp128* %fptr unordered, align 16 | ||
ret void | ||
; CHECK-LABEL: store_fp128 | ||
; CHECK: bitcast fp128 %v to i128 | ||
; CHECK: call void @__tsan_atomic128_store(i128* %{{.+}}, i128 %{{.+}}, i32 0) | ||
} |