aboutsummaryrefslogtreecommitdiffstats
path: root/test/Instrumentation
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /test/Instrumentation
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'test/Instrumentation')
-rw-r--r--test/Instrumentation/AddressSanitizer/X86/asm_mov.ll123
-rw-r--r--test/Instrumentation/AddressSanitizer/X86/asm_mov.s76
-rw-r--r--test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s44
-rw-r--r--test/Instrumentation/AddressSanitizer/X86/bug_11395.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/basic.ll21
-rw-r--r--test/Instrumentation/AddressSanitizer/coverage.ll35
-rw-r--r--test/Instrumentation/AddressSanitizer/different_scale_and_offset.ll41
-rw-r--r--test/Instrumentation/AddressSanitizer/do-not-instrument-internal-globals.ll6
-rw-r--r--test/Instrumentation/AddressSanitizer/do-not-instrument-llvm-metadata.ll12
-rw-r--r--test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll11
-rw-r--r--test/Instrumentation/AddressSanitizer/do-not-touch-threadlocal.ll4
-rw-r--r--test/Instrumentation/AddressSanitizer/freebsd.ll29
-rw-r--r--test/Instrumentation/AddressSanitizer/instrument-no-return.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/instrument_global.ll1
-rw-r--r--test/Instrumentation/AddressSanitizer/instrument_load_then_store.ll4
-rw-r--r--test/Instrumentation/AddressSanitizer/keep-instrumented_functions.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/lifetime-uar.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/lifetime.ll2
-rw-r--r--test/Instrumentation/AddressSanitizer/stack-poisoning.ll43
-rw-r--r--test/Instrumentation/AddressSanitizer/stack_layout.ll49
-rw-r--r--test/Instrumentation/AddressSanitizer/test64.ll8
-rw-r--r--test/Instrumentation/BoundsChecking/phi.ll55
-rw-r--r--test/Instrumentation/BoundsChecking/simple.ll24
-rw-r--r--test/Instrumentation/DataFlowSanitizer/load.ll188
-rw-r--r--test/Instrumentation/DataFlowSanitizer/store.ll179
-rw-r--r--test/Instrumentation/MemorySanitizer/atomics.ll10
-rw-r--r--test/Instrumentation/MemorySanitizer/check_access_address.ll28
-rw-r--r--test/Instrumentation/MemorySanitizer/msan_basic.ll188
-rw-r--r--test/Instrumentation/MemorySanitizer/store-origin.ll73
-rw-r--r--test/Instrumentation/MemorySanitizer/vector_shift.ll100
-rw-r--r--test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll32
-rw-r--r--test/Instrumentation/ThreadSanitizer/atomic.ll50
-rw-r--r--test/Instrumentation/ThreadSanitizer/vptr_update.ll27
34 files changed, 1155 insertions, 318 deletions
diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll b/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll
new file mode 100644
index 0000000..7af8139
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov.ll
@@ -0,0 +1,123 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asan-instrument-inline-assembly | 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-LABEL: mov1b
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: movb {{.*}}, {{.*}}
+define void @mov1b(i8* %dst, i8* %src) #0 {
+entry:
+ tail call void asm sideeffect "movb ($1), %al \0A\09movb %al, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i8* %dst, i8* %src) #1, !srcloc !0
+ ret void
+}
+
+; CHECK-LABEL: mov2b
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_load2@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_store2@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: movw {{.*}}, {{.*}}
+define void @mov2b(i16* %dst, i16* %src) #0 {
+entry:
+ tail call void asm sideeffect "movw ($1), %ax \0A\09movw %ax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i16* %dst, i16* %src) #1, !srcloc !1
+ ret void
+}
+
+; CHECK-LABEL: mov4b
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_load4@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_store4@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: movl {{.*}}, {{.*}}
+define void @mov4b(i32* %dst, i32* %src) #0 {
+entry:
+ tail call void asm sideeffect "movl ($1), %eax \0A\09movl %eax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %dst, i32* %src) #1, !srcloc !2
+ ret void
+}
+
+; CHECK-LABEL: mov8b
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: movq {{.*}}, {{.*}}
+define void @mov8b(i64* %dst, i64* %src) #0 {
+entry:
+ tail call void asm sideeffect "movq ($1), %rax \0A\09movq %rax, ($0) \0A\09", "r,r,~{memory},~{rax},~{dirflag},~{fpsr},~{flags}"(i64* %dst, i64* %src) #1, !srcloc !3
+ ret void
+}
+
+; CHECK-LABEL: mov16b
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: subq $128, %rsp
+; CHECK-NEXT: pushq %rdi
+; CHECK-NEXT: leaq {{.*}}, %rdi
+; CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT
+; CHECK-NEXT: popq %rdi
+; CHECK-NEXT: addq $128, %rsp
+
+; CHECK: movaps {{.*}}, {{.*}}
+define void @mov16b(<2 x i64>* %dst, <2 x i64>* %src) #0 {
+entry:
+ tail call void asm sideeffect "movaps ($1), %xmm0 \0A\09movaps %xmm0, ($0) \0A\09", "r,r,~{memory},~{xmm0},~{dirflag},~{fpsr},~{flags}"(<2 x i64>* %dst, <2 x i64>* %src) #1, !srcloc !4
+ ret void
+}
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind }
+
+!0 = metadata !{i32 98, i32 122, i32 160}
+!1 = metadata !{i32 305, i32 329, i32 367}
+!2 = metadata !{i32 512, i32 537, i32 576}
+!3 = metadata !{i32 721, i32 746, i32 785}
+!4 = metadata !{i32 929, i32 957, i32 999}
diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov.s b/test/Instrumentation/AddressSanitizer/X86/asm_mov.s
new file mode 100644
index 0000000..9001067
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov.s
@@ -0,0 +1,76 @@
+# RUN: llvm-mc %s -triple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 -asan-instrument-inline-assembly | FileCheck %s
+
+ .text
+ .globl mov1b
+ .align 16, 0x90
+ .type mov1b,@function
+# CHECK-LABEL: mov1b:
+#
+# CHECK: subq $128, %rsp
+# CHECK-NEXT: pushq %rdi
+# CHECK-NEXT: leaq (%rsi), %rdi
+# CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT
+# CHECK-NEXT: popq %rdi
+# CHECK-NEXT: addq $128, %rsp
+#
+# CHECK-NEXT: movb (%rsi), %al
+#
+# CHECK-NEXT: subq $128, %rsp
+# CHECK-NEXT: pushq %rdi
+# CHECK-NEXT: leaq (%rdi), %rdi
+# CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT
+# CHECK-NEXT: popq %rdi
+# CHECK-NEXT: addq $128, %rsp
+#
+# CHECK-NEXT: movb %al, (%rdi)
+mov1b: # @mov1b
+ .cfi_startproc
+# BB#0:
+ #APP
+ movb (%rsi), %al
+ movb %al, (%rdi)
+
+ #NO_APP
+ retq
+.Ltmp0:
+ .size mov1b, .Ltmp0-mov1b
+ .cfi_endproc
+
+ .globl mov16b
+ .align 16, 0x90
+ .type mov16b,@function
+# CHECK-LABEL: mov16b:
+#
+# CHECK: subq $128, %rsp
+# CHECK-NEXT: pushq %rdi
+# CHECK-NEXT: leaq (%rsi), %rdi
+# CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT
+# CHECK-NEXT: popq %rdi
+# CHECK-NEXT: addq $128, %rsp
+#
+# CHECK-NEXT: movaps (%rsi), %xmm0
+#
+# CHECK-NEXT: subq $128, %rsp
+# CHECK-NEXT: pushq %rdi
+# CHECK-NEXT: leaq (%rdi), %rdi
+# CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT
+# CHECK-NEXT: popq %rdi
+# CHECK-NEXT: addq $128, %rsp
+#
+# CHECK-NEXT: movaps %xmm0, (%rdi)
+mov16b: # @mov16b
+ .cfi_startproc
+# BB#0:
+ #APP
+ movaps (%rsi), %xmm0
+ movaps %xmm0, (%rdi)
+
+ #NO_APP
+ retq
+.Ltmp1:
+ .size mov16b, .Ltmp1-mov16b
+ .cfi_endproc
+
+
+ .ident "clang version 3.5 "
+ .section ".note.GNU-stack","",@progbits
diff --git a/test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s b/test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s
new file mode 100644
index 0000000..a9ef4df
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/X86/asm_mov_no_instrumentation.s
@@ -0,0 +1,44 @@
+# RUN: llvm-mc %s -triple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+sse2 | FileCheck %s
+
+ .text
+ .globl mov1b
+ .align 16, 0x90
+ .type mov1b,@function
+# CHECK-LABEL: mov1b
+# CHECK-NOT: callq __sanitizer_sanitize_load1@PLT
+# CHECK-NOT: callq __sanitizer_sanitize_store1@PLT
+mov1b: # @mov1b
+ .cfi_startproc
+# BB#0:
+ #APP
+ movb (%rsi), %al
+ movb %al, (%rdi)
+
+ #NO_APP
+ retq
+.Ltmp0:
+ .size mov1b, .Ltmp0-mov1b
+ .cfi_endproc
+
+ .globl mov16b
+ .align 16, 0x90
+ .type mov16b,@function
+# CHECK-LABEL: mov16b
+# CHECK-NOT: callq __sanitizer_sanitize_load16@PLT
+# CHECK-NOT: callq __sanitizer_sanitize_store16@PLT
+mov16b: # @mov16b
+ .cfi_startproc
+# BB#0:
+ #APP
+ movaps (%rsi), %xmm0
+ movaps %xmm0, (%rdi)
+
+ #NO_APP
+ retq
+.Ltmp1:
+ .size mov16b, .Ltmp1-mov16b
+ .cfi_endproc
+
+
+ .ident "clang version 3.5 "
+ .section ".note.GNU-stack","",@progbits
diff --git a/test/Instrumentation/AddressSanitizer/X86/bug_11395.ll b/test/Instrumentation/AddressSanitizer/X86/bug_11395.ll
index 2c4d82e..63477aa 100644
--- a/test/Instrumentation/AddressSanitizer/X86/bug_11395.ll
+++ b/test/Instrumentation/AddressSanitizer/X86/bug_11395.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -asan -S | llc -o /dev/null
+; RUN: opt < %s -asan -asan-module -S | llc -o /dev/null
; The bug manifests as a reg alloc failure:
; error: ran out of registers during register allocation
; ModuleID = 'z.o'
diff --git a/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll b/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll
index 1087c9a..75adf40 100644
--- a/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll
+++ b/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -basicaa -gvn -asan -S | FileCheck %s
+; RUN: opt < %s -basicaa -gvn -asan -asan-module -S | FileCheck %s
; ASAN conflicts with load widening iff the widened load accesses data out of bounds
; (while the original unwidened loads do not).
; http://code.google.com/p/address-sanitizer/issues/detail?id=20#c1
diff --git a/test/Instrumentation/AddressSanitizer/basic.ll b/test/Instrumentation/AddressSanitizer/basic.ll
index 6002b9e..4863a3d 100644
--- a/test/Instrumentation/AddressSanitizer/basic.ll
+++ b/test/Instrumentation/AddressSanitizer/basic.ll
@@ -1,6 +1,6 @@
; Test basic address sanitizer instrumentation.
;
-; RUN: opt < %s -asan -S | FileCheck %s
+; RUN: opt < %s -asan -asan-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"
target triple = "x86_64-unknown-linux-gnu"
@@ -89,25 +89,6 @@ entry:
; CHECK-NOT: = alloca
; CHECK: ret void
-; Check that asan does not touch allocas with alignment > 32.
-define void @alloca_alignment_test() sanitize_address {
-entry:
- %x = alloca [10 x i8], align 64
- %y = alloca [10 x i8], align 128
- %z = alloca [10 x i8], align 256
- call void @alloca_test_use([10 x i8]* %x)
- call void @alloca_test_use([10 x i8]* %y)
- call void @alloca_test_use([10 x i8]* %z)
- ret void
-}
-
-; CHECK: define void @alloca_alignment_test()
-; CHECK: = alloca{{.*}} align 64
-; CHECK: = alloca{{.*}} align 128
-; CHECK: = alloca{{.*}} align 256
-; CHECK: ret void
-
-
define void @LongDoubleTest(x86_fp80* nocapture %a) nounwind uwtable sanitize_address {
entry:
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %a, align 16
diff --git a/test/Instrumentation/AddressSanitizer/coverage.ll b/test/Instrumentation/AddressSanitizer/coverage.ll
index 47a54c0..0670132 100644
--- a/test/Instrumentation/AddressSanitizer/coverage.ll
+++ b/test/Instrumentation/AddressSanitizer/coverage.ll
@@ -1,13 +1,30 @@
-; RUN: opt < %s -asan -asan-coverage=1 -S | FileCheck %s
+; RUN: opt < %s -asan -asan-module -asan-coverage=1 -S | FileCheck %s --check-prefix=CHECK1
+; RUN: opt < %s -asan -asan-module -asan-coverage=2 -S | FileCheck %s --check-prefix=CHECK2
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"
target triple = "x86_64-unknown-linux-gnu"
-define i32 @foo(i32* %a) sanitize_address {
+define void @foo(i32* %a) sanitize_address {
entry:
- ret i32 0
+ %tobool = icmp eq i32* %a, null
+ br i1 %tobool, label %if.end, label %if.then
+
+ if.then: ; preds = %entry
+ store i32 0, i32* %a, align 4
+ br label %if.end
+
+ if.end: ; preds = %entry, %if.then
+ ret void
}
-; CHECK: define i32 @foo(i32* %a) #0 {
-; CHECK: %0 = load atomic i8* @__asan_gen_cov_foo monotonic, align 1
-; CHECK: %1 = icmp eq i8 0, %0
-; CHECK: br i1 %1, label %2, label %3
-; CHECK: call void @__sanitizer_cov(i64 ptrtoint (i32 (i32*)* @foo to i64))
-; CHECK: store atomic i8 1, i8* @__asan_gen_cov_foo monotonic, align 1
+; CHECK1-LABEL: define void @foo
+; CHECK1: %0 = load atomic i8* @__asan_gen_cov_foo monotonic, align 1
+; CHECK1: %1 = icmp eq i8 0, %0
+; CHECK1: br i1 %1, label %2, label %3
+; CHECK1: call void @__sanitizer_cov
+; CHECK1-NOT: call void @__sanitizer_cov
+; CHECK1: store atomic i8 1, i8* @__asan_gen_cov_foo monotonic, align 1
+
+; CHECK2-LABEL: define void @foo
+; CHECK2: call void @__sanitizer_cov
+; CHECK2: call void @__sanitizer_cov
+; CHECK2: call void @__sanitizer_cov
+; CHECK2-NOT: call void @__sanitizer_cov
+; CHECK2: ret void
diff --git a/test/Instrumentation/AddressSanitizer/different_scale_and_offset.ll b/test/Instrumentation/AddressSanitizer/different_scale_and_offset.ll
deleted file mode 100644
index b037176..0000000
--- a/test/Instrumentation/AddressSanitizer/different_scale_and_offset.ll
+++ /dev/null
@@ -1,41 +0,0 @@
-; Test non-default shadow mapping scale and offset.
-;
-; RUN: opt < %s -asan -asan-mapping-scale=2 -asan-mapping-offset-log=0 -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"
-target triple = "x86_64-unknown-linux-gnu"
-
-; Test that ASan tells scale and offset to runtime.
-; CHECK: @__asan_mapping_offset = linkonce_odr constant i64 0
-; CHECK: @__asan_mapping_scale = linkonce_odr constant i64 2
-
-define i32 @test_load(i32* %a) sanitize_address {
-; CHECK: @test_load
-; CHECK-NOT: load
-; CHECK: %[[LOAD_ADDR:[^ ]*]] = ptrtoint i32* %a to i64
-; CHECK: lshr i64 %[[LOAD_ADDR]], 2
-
-; No need in shift for zero offset.
-; CHECK-NOT: or i64
-
-; CHECK: %[[LOAD_SHADOW_PTR:[^ ]*]] = inttoptr
-; CHECK: %[[LOAD_SHADOW:[^ ]*]] = load i8* %[[LOAD_SHADOW_PTR]]
-; CHECK: icmp ne i8
-; CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
-
-; No need in slow path for i32 and mapping scale equal to 2.
-; CHECK-NOT: and i64 %[[LOAD_ADDR]]
-;
-; The crash block reports the error.
-; CHECK: call void @__asan_report_load4(i64 %[[LOAD_ADDR]])
-; CHECK: unreachable
-;
-; The actual load.
-; CHECK: %tmp1 = load i32* %a
-; CHECK: ret i32 %tmp1
-
-entry:
- %tmp1 = load i32* %a
- ret i32 %tmp1
-}
-
diff --git a/test/Instrumentation/AddressSanitizer/do-not-instrument-internal-globals.ll b/test/Instrumentation/AddressSanitizer/do-not-instrument-internal-globals.ll
index d4fd93c..cff83ab 100644
--- a/test/Instrumentation/AddressSanitizer/do-not-instrument-internal-globals.ll
+++ b/test/Instrumentation/AddressSanitizer/do-not-instrument-internal-globals.ll
@@ -1,6 +1,6 @@
; This test checks that we are not instrumenting globals
; that we created ourselves.
-; RUN: opt < %s -asan -S | FileCheck %s
+; RUN: opt < %s -asan -asan-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"
target triple = "x86_64-unknown-linux-gnu"
@@ -16,5 +16,5 @@ declare void @_Z3fooPi(i32*)
; We create one global string constant for the stack frame above.
; It should have unnamed_addr and align 1.
; Make sure we don't create any other global constants.
-; CHECK: = internal unnamed_addr constant{{.*}}align 1
-; CHECK-NOT: = internal unnamed_addr constant
+; CHECK: = private unnamed_addr constant{{.*}}align 1
+; CHECK-NOT: = private unnamed_addr constant
diff --git a/test/Instrumentation/AddressSanitizer/do-not-instrument-llvm-metadata.ll b/test/Instrumentation/AddressSanitizer/do-not-instrument-llvm-metadata.ll
new file mode 100644
index 0000000..fbfc096
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/do-not-instrument-llvm-metadata.ll
@@ -0,0 +1,12 @@
+; This test checks that we are not instrumenting globals in llvm.metadata.
+; RUN: opt < %s -asan -asan-module -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@.str_noinst = private unnamed_addr constant [4 x i8] c"aaa\00", section "llvm.metadata"
+@.str_inst = private unnamed_addr constant [4 x i8] c"aaa\00",
+
+; CHECK-NOT: {{asan_gen.*str_noinst}}
+; CHECK: {{asan_gen.*str_inst}}
+; CHECK: @asan.module_ctor
diff --git a/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll b/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll
index 1687877..9775261 100644
--- a/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll
+++ b/test/Instrumentation/AddressSanitizer/do-not-touch-odr-global.ll
@@ -1,6 +1,11 @@
-; RUN: opt < %s -asan -S | FileCheck %s
+; This test checks that we instrument regular globals, but do not touch
+; the linkonce_odr ones.
+; RUN: opt < %s -asan -asan-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"
target triple = "x86_64-unknown-linux-gnu"
; no action should be taken for these globals
-@v1 = linkonce_odr constant i8 1
-; CHECK-NOT: __asan_register_globals
+@global_noinst = linkonce_odr constant [2 x i8] [i8 1, i8 2]
+@global_inst = private constant [2 x i8] [i8 1, i8 2]
+; CHECK-NOT: {{asan_gen.*global_noinst}}
+; CHECK: {{asan_gen.*global_inst}}
+; CHECK: @asan.module_ctor
diff --git a/test/Instrumentation/AddressSanitizer/do-not-touch-threadlocal.ll b/test/Instrumentation/AddressSanitizer/do-not-touch-threadlocal.ll
index 89644d4..f863f44 100644
--- a/test/Instrumentation/AddressSanitizer/do-not-touch-threadlocal.ll
+++ b/test/Instrumentation/AddressSanitizer/do-not-touch-threadlocal.ll
@@ -1,6 +1,6 @@
-; RUN: opt < %s -asan -S | FileCheck %s
+; RUN: opt < %s -asan -asan-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"
target triple = "x86_64-unknown-linux-gnu"
; no action should be taken for thread locals
@xxx = thread_local global i32 0, align 4
-; CHECK-NOT: __asan_register_globals
+; CHECK-NOT: {{call.*__asan_register_globals}}
diff --git a/test/Instrumentation/AddressSanitizer/freebsd.ll b/test/Instrumentation/AddressSanitizer/freebsd.ll
new file mode 100644
index 0000000..359529f
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/freebsd.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -asan -asan-module -S \
+; RUN: -mtriple=i386-unknown-freebsd \
+; RUN: -default-data-layout="e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" | \
+; RUN: FileCheck --check-prefix=CHECK-32 %s
+
+; RUN: opt < %s -asan -asan-module -S \
+; RUN: -mtriple=x86_64-unknown-freebsd \
+; RUN: -default-data-layout="e-m:e-i64:64-f80:128-n8:16:32:64-S128" | \
+; RUN: FileCheck --check-prefix=CHECK-64 %s
+
+define i32 @read_4_bytes(i32* %a) sanitize_address {
+entry:
+ %tmp1 = load i32* %a, align 4
+ ret i32 %tmp1
+}
+
+; CHECK-32: @read_4_bytes
+; CHECK-32-NOT: ret
+; Check for ASAN's Offset for 32-bit (2^30 or 0x40000000)
+; CHECK-32: lshr {{.*}} 3
+; CHECK-32-NEXT: {{1073741824}}
+; CHECK-32: ret
+
+; CHECK-64: @read_4_bytes
+; CHECK-64-NOT: ret
+; Check for ASAN's Offset for 64-bit (2^46 or 0x400000000000)
+; CHECK-64: lshr {{.*}} 3
+; CHECK-64-NEXT: {{70368744177664}}
+; CHECK-64: ret
diff --git a/test/Instrumentation/AddressSanitizer/instrument-no-return.ll b/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
index 2d835a3..5d5c592 100644
--- a/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
+++ b/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -asan -S | FileCheck %s
+; RUN: opt < %s -asan -asan-module -S | FileCheck %s
; AddressSanitizer must insert __asan_handle_no_return
; before every noreturn call or invoke.
diff --git a/test/Instrumentation/AddressSanitizer/instrument_global.ll b/test/Instrumentation/AddressSanitizer/instrument_global.ll
index 4717277..7945e81 100644
--- a/test/Instrumentation/AddressSanitizer/instrument_global.ll
+++ b/test/Instrumentation/AddressSanitizer/instrument_global.ll
@@ -7,6 +7,7 @@ target triple = "x86_64-unknown-linux-gnu"
; module ctor/dtor
; CHECK: llvm.global_ctors
+; CHECK: @__asan_gen_ = private constant [8 x i8] c"<stdin>\00", align 1
; CHECK: llvm.global_dtors
; Test that we don't instrument global arrays with static initializer
diff --git a/test/Instrumentation/AddressSanitizer/instrument_load_then_store.ll b/test/Instrumentation/AddressSanitizer/instrument_load_then_store.ll
index 23cf6d2..195785f 100644
--- a/test/Instrumentation/AddressSanitizer/instrument_load_then_store.ll
+++ b/test/Instrumentation/AddressSanitizer/instrument_load_then_store.ll
@@ -1,6 +1,6 @@
; Test that AddressSanitizer instruments "(*a)++" only once.
-; RUN: opt < %s -asan -S -asan-opt=1 | FileCheck %s -check-prefix=OPT1
-; RUN: opt < %s -asan -S -asan-opt=0 | FileCheck %s -check-prefix=OPT0
+; RUN: opt < %s -asan -asan-module -S -asan-opt=1 | FileCheck %s -check-prefix=OPT1
+; RUN: opt < %s -asan -asan-module -S -asan-opt=0 | FileCheck %s -check-prefix=OPT0
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"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/Instrumentation/AddressSanitizer/keep-instrumented_functions.ll b/test/Instrumentation/AddressSanitizer/keep-instrumented_functions.ll
index ff3bbb0..8726b8e 100644
--- a/test/Instrumentation/AddressSanitizer/keep-instrumented_functions.ll
+++ b/test/Instrumentation/AddressSanitizer/keep-instrumented_functions.ll
@@ -1,5 +1,5 @@
; Test the -asan-keep-uninstrumented-functions flag: FOO should get cloned
-; RUN: opt < %s -asan -asan-keep-uninstrumented-functions -S | FileCheck %s
+; RUN: opt < %s -asan -asan-module -asan-keep-uninstrumented-functions -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"
diff --git a/test/Instrumentation/AddressSanitizer/lifetime-uar.ll b/test/Instrumentation/AddressSanitizer/lifetime-uar.ll
index 21eaf7f..25577de 100644
--- a/test/Instrumentation/AddressSanitizer/lifetime-uar.ll
+++ b/test/Instrumentation/AddressSanitizer/lifetime-uar.ll
@@ -1,5 +1,5 @@
; Test handling of llvm.lifetime intrinsics in UAR mode.
-; RUN: opt < %s -asan -asan-use-after-return -asan-check-lifetime -S | FileCheck %s
+; RUN: opt < %s -asan -asan-module -asan-use-after-return -asan-check-lifetime -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"
diff --git a/test/Instrumentation/AddressSanitizer/lifetime.ll b/test/Instrumentation/AddressSanitizer/lifetime.ll
index d80331e..1961997 100644
--- a/test/Instrumentation/AddressSanitizer/lifetime.ll
+++ b/test/Instrumentation/AddressSanitizer/lifetime.ll
@@ -1,5 +1,5 @@
; Test hanlding of llvm.lifetime intrinsics.
-; RUN: opt < %s -asan -asan-check-lifetime -S | FileCheck %s
+; RUN: opt < %s -asan -asan-module -asan-check-lifetime -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"
diff --git a/test/Instrumentation/AddressSanitizer/stack-poisoning.ll b/test/Instrumentation/AddressSanitizer/stack-poisoning.ll
new file mode 100644
index 0000000..6919e53
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/stack-poisoning.ll
@@ -0,0 +1,43 @@
+; RUN: opt < %s -asan -asan-module -asan-use-after-return -S | FileCheck --check-prefix=CHECK-UAR %s
+; RUN: opt < %s -asan -asan-module -S | FileCheck --check-prefix=CHECK-PLAIN %s
+target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @Foo(i8*)
+
+define void @Bar() uwtable sanitize_address {
+entry:
+; CHECK-PLAIN-LABEL: Bar
+; CHECK-PLAIN-NOT: label
+; CHECK-PLAIN: ret void
+
+; CHECK-UAR-LABEL: Bar
+; CHECK-UAR: load i32* @__asan_option_detect_stack_use_after_return
+; CHECK-UAR: label
+; CHECK-UAR: call i64 @__asan_stack_malloc_1
+; CHECK-UAR: label
+; CHECK-UAR: call void @Foo
+; If LocalStackBase != OrigStackBase
+; CHECK-UAR: label
+; Then Block: poison the entire frame.
+ ; CHECK-UAR: store i64 -723401728380766731
+ ; CHECK-UAR: store i64 -723401728380766731
+ ; CHECK-UAR: store i8 0
+ ; CHECK-UAR-NOT: store
+ ; CHECK-UAR: label
+; Else Block: no UAR frame. Only unpoison the redzones.
+ ; CHECK-UAR: store i64 0
+ ; CHECK-UAR: store i32 0
+ ; CHECK-UAR-NOT: store
+ ; CHECK-UAR: label
+; Done, no more stores.
+; CHECK-UAR-NOT: store
+; CHECK-UAR: ret void
+
+ %x = alloca [20 x i8], align 16
+ %arraydecay = getelementptr inbounds [20 x i8]* %x, i64 0, i64 0
+ call void @Foo(i8* %arraydecay)
+ ret void
+}
+
+
diff --git a/test/Instrumentation/AddressSanitizer/stack_layout.ll b/test/Instrumentation/AddressSanitizer/stack_layout.ll
new file mode 100644
index 0000000..c027acf
--- /dev/null
+++ b/test/Instrumentation/AddressSanitizer/stack_layout.ll
@@ -0,0 +1,49 @@
+; Test the ASan's stack layout.
+; More tests in tests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
+; RUN: opt < %s -asan -asan-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"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @Use(i8*)
+
+; CHECK: private unnamed_addr constant{{.*}}3 32 10 3 XXX 64 20 3 YYY 128 30 3 ZZZ
+; CHECK: private unnamed_addr constant{{.*}}3 32 5 3 AAA 64 55 3 BBB 160 555 3 CCC
+; CHECK: private unnamed_addr constant{{.*}}3 256 128 3 CCC 448 128 3 BBB 608 128 3 AAA
+
+define void @Func1() sanitize_address {
+entry:
+; CHECK-LABEL: Func1
+; CHECK: alloca [192 x i8]
+; CHECK-NOT: alloca
+; CHECK: ret void
+ %XXX = alloca [10 x i8], align 1
+ %YYY = alloca [20 x i8], align 1
+ %ZZZ = alloca [30 x i8], align 1
+ ret void
+}
+
+define void @Func2() sanitize_address {
+entry:
+; CHECK-LABEL: Func2
+; CHECK: alloca [864 x i8]
+; CHECK-NOT: alloca
+; CHECK: ret void
+ %AAA = alloca [5 x i8], align 1
+ %BBB = alloca [55 x i8], align 1
+ %CCC = alloca [555 x i8], align 1
+ ret void
+}
+
+; Check that we reorder vars according to alignment and handle large alignments.
+define void @Func3() sanitize_address {
+entry:
+; CHECK-LABEL: Func3
+; CHECK: alloca [768 x i8]
+; CHECK-NOT: alloca
+; CHECK: ret void
+ %AAA = alloca [128 x i8], align 16
+ %BBB = alloca [128 x i8], align 64
+ %CCC = alloca [128 x i8], align 256
+ ret void
+}
diff --git a/test/Instrumentation/AddressSanitizer/test64.ll b/test/Instrumentation/AddressSanitizer/test64.ll
index 6aa5c28..4f3ed5b 100644
--- a/test/Instrumentation/AddressSanitizer/test64.ll
+++ b/test/Instrumentation/AddressSanitizer/test64.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -asan -S | FileCheck %s
+; RUN: opt < %s -asan -asan-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"
target triple = "x86_64-unknown-linux-gnu"
define i32 @read_4_bytes(i32* %a) sanitize_address {
@@ -9,8 +9,8 @@ entry:
; CHECK: @read_4_bytes
; CHECK-NOT: ret
; CHECK: lshr {{.*}} 3
-; Check for ASAN's Offset for 64-bit (2^44 or 7fff8000)
-; CHECK-NEXT: {{17592186044416|2147450880}}
+; Check for ASAN's Offset for 64-bit (7fff8000)
+; CHECK-NEXT: add{{.*}}2147450880
; CHECK: ret
define void @example_atomicrmw(i64* %ptr) nounwind uwtable sanitize_address {
@@ -26,7 +26,7 @@ entry:
define void @example_cmpxchg(i64* %ptr, i64 %compare_to, i64 %new_value) nounwind uwtable sanitize_address {
entry:
- %0 = cmpxchg i64* %ptr, i64 %compare_to, i64 %new_value seq_cst
+ %0 = cmpxchg i64* %ptr, i64 %compare_to, i64 %new_value seq_cst seq_cst
ret void
}
diff --git a/test/Instrumentation/BoundsChecking/phi.ll b/test/Instrumentation/BoundsChecking/phi.ll
index 86b5922..0f9d1b0 100644
--- a/test/Instrumentation/BoundsChecking/phi.ll
+++ b/test/Instrumentation/BoundsChecking/phi.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -bounds-checking -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 datalayout = "e-p:64:64:64-p1:16:16:16-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"
@global = private unnamed_addr constant [10 x i8] c"ola\00mundo\00", align 1
@@ -50,3 +50,56 @@ while.body.i:
fn.exit:
ret void
}
+
+
+@global_as1 = private addrspace(1) unnamed_addr constant [10 x i8] c"ola\00mundo\00", align 1
+
+define void @f1_as1(i8 addrspace(1)* nocapture %c) {
+; CHECK: @f1_as1
+; no checks are possible here
+; CHECK-NOT: trap
+; CHECK: add i16 undef, -1
+; CHECK-NOT: trap
+entry:
+ %0 = load i8 addrspace(1)* %c, align 1
+ %tobool1 = icmp eq i8 %0, 0
+ br i1 %tobool1, label %while.end, label %while.body
+
+while.body:
+ %c.addr.02 = phi i8 addrspace(1)* [ %incdec.ptr, %while.body ], [ %c, %entry ]
+ %incdec.ptr = getelementptr inbounds i8 addrspace(1)* %c.addr.02, i64 -1
+ store i8 100, i8 addrspace(1)* %c.addr.02, align 1
+ %1 = load i8 addrspace(1)* %incdec.ptr, align 1
+ %tobool = icmp eq i8 %1, 0
+ br i1 %tobool, label %while.end, label %while.body
+
+while.end:
+ ret void
+}
+
+
+define void @f2_as1() {
+; CHECK: @f2_as1
+while.body.i.preheader:
+ %addr = getelementptr inbounds [10 x i8] addrspace(1)* @global_as1, i16 0, i16 9
+ br label %while.body.i
+
+while.body.i:
+; CHECK: phi
+; CHECK-NEXT: phi
+; CHECK-NOT: phi
+ %c.addr.02.i = phi i8 addrspace(1)* [ %incdec.ptr.i, %while.body.i ], [ %addr, %while.body.i.preheader ]
+ %incdec.ptr.i = getelementptr inbounds i8 addrspace(1)* %c.addr.02.i, i16 -1
+; CHECK: sub i16 10, %0
+; CHECK-NEXT: icmp ult i16 10, %0
+; CHECK-NEXT: icmp ult i16 {{.*}}, 1
+; CHECK-NEXT: or i1
+; CHECK-NEXT: br {{.*}}, label %trap
+ store i8 100, i8 addrspace(1)* %c.addr.02.i, align 1
+ %0 = load i8 addrspace(1)* %incdec.ptr.i, align 1
+ %tobool.i = icmp eq i8 %0, 0
+ br i1 %tobool.i, label %fn.exit, label %while.body.i
+
+fn.exit:
+ ret void
+}
diff --git a/test/Instrumentation/BoundsChecking/simple.ll b/test/Instrumentation/BoundsChecking/simple.ll
index 72b58f4..ddacf6d 100644
--- a/test/Instrumentation/BoundsChecking/simple.ll
+++ b/test/Instrumentation/BoundsChecking/simple.ll
@@ -1,8 +1,11 @@
; RUN: opt < %s -bounds-checking -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 datalayout = "e-p:64:64:64-p1:16:16:16-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"
@.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*>
+@.str_as1 = private addrspace(1) constant [8 x i8] c"abcdefg\00" ; <[8 x i8] addrspace(1)*>
+
+
declare noalias i8* @malloc(i64) nounwind
declare noalias i8* @calloc(i64, i64) nounwind
declare noalias i8* @realloc(i8* nocapture, i64) nounwind
@@ -60,6 +63,16 @@ define void @f5(i64 %x) nounwind {
ret void
}
+define void @f5_as1(i64 %x) nounwind {
+; CHECK: @f5_as1
+ %idx = getelementptr inbounds [8 x i8] addrspace(1)* @.str_as1, i64 0, i64 %x
+ ; CHECK: sub i16
+ ; CHECK icmp ult i16
+; CHECK: trap
+ %1 = load i8 addrspace(1)* %idx, align 4
+ ret void
+}
+
; CHECK: @f6
define void @f6(i64 %x) nounwind {
%1 = alloca i128
@@ -117,6 +130,15 @@ define void @f11(i128* byval %x) nounwind {
ret void
}
+; CHECK: @f11_as1
+define void @f11_as1(i128 addrspace(1)* byval %x) nounwind {
+ %1 = bitcast i128 addrspace(1)* %x to i8 addrspace(1)*
+ %2 = getelementptr inbounds i8 addrspace(1)* %1, i16 16
+; CHECK: br label
+ %3 = load i8 addrspace(1)* %2, align 4
+ ret void
+}
+
; CHECK: @f12
define i64 @f12(i64 %x, i64 %y) nounwind {
%1 = tail call i8* @calloc(i64 1, i64 %x)
diff --git a/test/Instrumentation/DataFlowSanitizer/load.ll b/test/Instrumentation/DataFlowSanitizer/load.ll
index 6431213..6cd5151 100644
--- a/test/Instrumentation/DataFlowSanitizer/load.ll
+++ b/test/Instrumentation/DataFlowSanitizer/load.ll
@@ -1,81 +1,155 @@
-; RUN: opt < %s -dfsan -S | FileCheck %s
+; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=1 -S | FileCheck %s --check-prefix=COMBINE_PTR_LABEL
+; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=0 -S | FileCheck %s --check-prefix=NO_COMBINE_PTR_LABEL
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 i8 @load8(i8* %p) {
- ; CHECK: @"dfs$load8"
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: load
- ; CHECK: store{{.*}}__dfsan_retval_tls
- ; CHECK: ret i8
+ ; COMBINE_PTR_LABEL: @"dfs$load8"
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: ptrtoint i8* {{.*}} to i64
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call zeroext i16 @__dfsan_union
+ ; COMBINE_PTR_LABEL: load i8*
+ ; COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; COMBINE_PTR_LABEL: ret i8
+
+ ; NO_COMBINE_PTR_LABEL: @"dfs$load8"
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i8*
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} to i16*
+ ; NO_COMBINE_PTR_LABEL: load i16*
+ ; NO_COMBINE_PTR_LABEL: load i8*
+ ; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; NO_COMBINE_PTR_LABEL: ret i8
+
%a = load i8* %p
ret i8 %a
}
define i16 @load16(i16* %p) {
- ; CHECK: @"dfs$load16"
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: load
- ; CHECK: load
- ; CHECK: icmp ne
- ; CHECK: call{{.*}}__dfsan_union
- ; CHECK: store{{.*}}__dfsan_retval_tls
- ; CHECK: ret i16
+ ; COMBINE_PTR_LABEL: @"dfs$load16"
+ ; COMBINE_PTR_LABEL: ptrtoint i16*
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: getelementptr i16
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: icmp ne
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: store {{.*}} @__dfsan_retval_tls
+ ; COMBINE_PTR_LABEL: ret i16
+
+ ; NO_COMBINE_PTR_LABEL: @"dfs$load16"
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i16*
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: load i16*
+ ; NO_COMBINE_PTR_LABEL: load i16*
+ ; NO_COMBINE_PTR_LABEL: icmp ne i16
+ ; NO_COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; NO_COMBINE_PTR_LABEL: load i16*
+ ; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; NO_COMBINE_PTR_LABEL: ret i16
+
%a = load i16* %p
ret i16 %a
}
define i32 @load32(i32* %p) {
- ; CHECK: @"dfs$load32"
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: bitcast
- ; CHECK: load
- ; CHECK: trunc
- ; CHECK: shl
- ; CHECK: lshr
- ; CHECK: or
- ; CHECK: icmp eq
+ ; COMBINE_PTR_LABEL: @"dfs$load32"
+ ; COMBINE_PTR_LABEL: ptrtoint i32*
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
+ ; COMBINE_PTR_LABEL: load i64*
+ ; COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
+ ; COMBINE_PTR_LABEL: shl i64
+ ; COMBINE_PTR_LABEL: lshr i64
+ ; COMBINE_PTR_LABEL: or i64
+ ; COMBINE_PTR_LABEL: icmp eq i64
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: load i32*
+ ; COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; COMBINE_PTR_LABEL: ret i32
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
- ; CHECK: store{{.*}}__dfsan_retval_tls
- ; CHECK: ret i32
-
- ; CHECK: call{{.*}}__dfsan_union_load
+ ; NO_COMBINE_PTR_LABEL: @"dfs$load32"
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i32*
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
+ ; NO_COMBINE_PTR_LABEL: load i64*
+ ; NO_COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: shl i64
+ ; NO_COMBINE_PTR_LABEL: lshr i64
+ ; NO_COMBINE_PTR_LABEL: or i64
+ ; NO_COMBINE_PTR_LABEL: icmp eq i64
+ ; NO_COMBINE_PTR_LABEL: load i32*
+ ; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; NO_COMBINE_PTR_LABEL: ret i32
+ ; NO_COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
+
%a = load i32* %p
ret i32 %a
}
define i64 @load64(i64* %p) {
- ; CHECK: @"dfs$load64"
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: bitcast
- ; CHECK: load
- ; CHECK: trunc
- ; CHECK: shl
- ; CHECK: lshr
- ; CHECK: or
- ; CHECK: icmp eq
-
- ; CHECK: store{{.*}}__dfsan_retval_tls
- ; CHECK: ret i64
+ ; COMBINE_PTR_LABEL: @"dfs$load64"
+ ; COMBINE_PTR_LABEL: ptrtoint i64*
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
+ ; COMBINE_PTR_LABEL: load i64*
+ ; COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
+ ; COMBINE_PTR_LABEL: shl i64
+ ; COMBINE_PTR_LABEL: lshr i64
+ ; COMBINE_PTR_LABEL: or i64
+ ; COMBINE_PTR_LABEL: icmp eq i64
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: load i64*
+ ; COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; COMBINE_PTR_LABEL: ret i64
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
+ ; COMBINE_PTR_LABEL: getelementptr i64* {{.*}} i64
+ ; COMBINE_PTR_LABEL: load i64*
+ ; COMBINE_PTR_LABEL: icmp eq i64
- ; CHECK: call{{.*}}__dfsan_union_load
-
- ; CHECK: getelementptr
- ; CHECK: load
- ; CHECK: icmp eq
+ ; NO_COMBINE_PTR_LABEL: @"dfs$load64"
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i64*
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
+ ; NO_COMBINE_PTR_LABEL: load i64*
+ ; NO_COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: shl i64
+ ; NO_COMBINE_PTR_LABEL: lshr i64
+ ; NO_COMBINE_PTR_LABEL: or i64
+ ; NO_COMBINE_PTR_LABEL: icmp eq i64
+ ; NO_COMBINE_PTR_LABEL: load i64*
+ ; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
+ ; NO_COMBINE_PTR_LABEL: ret i64
+ ; NO_COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
+ ; NO_COMBINE_PTR_LABEL: getelementptr i64* {{.*}} i64
+ ; NO_COMBINE_PTR_LABEL: load i64*
+ ; NO_COMBINE_PTR_LABEL: icmp eq i64
%a = load i64* %p
ret i64 %a
-}
+} \ No newline at end of file
diff --git a/test/Instrumentation/DataFlowSanitizer/store.ll b/test/Instrumentation/DataFlowSanitizer/store.ll
index 9509177..8060537 100644
--- a/test/Instrumentation/DataFlowSanitizer/store.ll
+++ b/test/Instrumentation/DataFlowSanitizer/store.ll
@@ -1,75 +1,146 @@
-; RUN: opt < %s -dfsan -S | FileCheck %s
+; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=1 -S | FileCheck %s --check-prefix=COMBINE_PTR_LABEL
+; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=0 -S | FileCheck %s --check-prefix=NO_COMBINE_PTR_LABEL
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 void @store8(i8 %v, i8* %p) {
- ; CHECK: @"dfs$store8"
- ; CHECK: load{{.*}}__dfsan_arg_tls
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: store
+ ; NO_COMBINE_PTR_LABEL: @"dfs$store8"
+ ; NO_COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i8* {{.*}} i64
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: store i8
+
+ ; COMBINE_PTR_LABEL: @"dfs$store8"
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: load i16*
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: ptrtoint i8* {{.*}} i64
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: store i8
+
store i8 %v, i8* %p
ret void
}
define void @store16(i16 %v, i16* %p) {
- ; CHECK: @"dfs$store16"
- ; CHECK: load{{.*}}__dfsan_arg_tls
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: store
+ ; NO_COMBINE_PTR_LABEL: @"dfs$store16"
+ ; NO_COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i16* {{.*}} i64
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: store i16
+
+ ; COMBINE_PTR_LABEL: @"dfs$store16"
+ ; COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: ptrtoint i16* {{.*}} i64
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: store i16
+
store i16 %v, i16* %p
ret void
}
define void @store32(i32 %v, i32* %p) {
- ; CHECK: @"dfs$store32"
- ; CHECK: load{{.*}}__dfsan_arg_tls
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: store
+ ; NO_COMBINE_PTR_LABEL: @"dfs$store32"
+ ; NO_COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i32* {{.*}} i64
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: getelementptr i16*
+ ; NO_COMBINE_PTR_LABEL: store i16
+ ; NO_COMBINE_PTR_LABEL: store i32
+
+ ; COMBINE_PTR_LABEL: @"dfs$store32"
+ ; COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: ptrtoint i32* {{.*}} i64
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: getelementptr i16*
+ ; COMBINE_PTR_LABEL: store i16
+ ; COMBINE_PTR_LABEL: store i32
+
store i32 %v, i32* %p
ret void
}
define void @store64(i64 %v, i64* %p) {
- ; CHECK: @"dfs$store64"
- ; CHECK: load{{.*}}__dfsan_arg_tls
- ; CHECK: ptrtoint
- ; CHECK: and
- ; CHECK: mul
- ; CHECK: inttoptr
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: insertelement
- ; CHECK: bitcast
- ; CHECK: getelementptr
- ; CHECK: store
- ; CHECK: store
+ ; NO_COMBINE_PTR_LABEL: @"dfs$store64"
+ ; NO_COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; NO_COMBINE_PTR_LABEL: ptrtoint i64* {{.*}} i64
+ ; NO_COMBINE_PTR_LABEL: and i64
+ ; NO_COMBINE_PTR_LABEL: mul i64
+ ; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; NO_COMBINE_PTR_LABEL: bitcast i16* {{.*}} <8 x i16>*
+ ; NO_COMBINE_PTR_LABEL: store i64
+
+ ; COMBINE_PTR_LABEL: @"dfs$store64"
+ ; COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; COMBINE_PTR_LABEL: load i16* {{.*}} @__dfsan_arg_tls
+ ; COMBINE_PTR_LABEL: icmp ne i16
+ ; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
+ ; COMBINE_PTR_LABEL: ptrtoint i64* {{.*}} i64
+ ; COMBINE_PTR_LABEL: and i64
+ ; COMBINE_PTR_LABEL: mul i64
+ ; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: insertelement {{.*}} i16
+ ; COMBINE_PTR_LABEL: bitcast i16* {{.*}} <8 x i16>*
+ ; COMBINE_PTR_LABEL: store <8 x i16>
+ ; COMBINE_PTR_LABEL: store i64
+
store i64 %v, i64* %p
ret void
}
diff --git a/test/Instrumentation/MemorySanitizer/atomics.ll b/test/Instrumentation/MemorySanitizer/atomics.ll
index ff02452..98697d7 100644
--- a/test/Instrumentation/MemorySanitizer/atomics.ll
+++ b/test/Instrumentation/MemorySanitizer/atomics.ll
@@ -37,7 +37,7 @@ entry:
define i32 @Cmpxchg(i32* %p, i32 %a, i32 %b) sanitize_memory {
entry:
- %0 = cmpxchg i32* %p, i32 %a, i32 %b seq_cst
+ %0 = cmpxchg i32* %p, i32 %a, i32 %b seq_cst seq_cst
ret i32 %0
}
@@ -46,16 +46,16 @@ entry:
; CHECK: icmp
; CHECK: br
; CHECK: @__msan_warning
-; CHECK: cmpxchg {{.*}} seq_cst
+; CHECK: cmpxchg {{.*}} seq_cst seq_cst
; CHECK: store i32 0, {{.*}} @__msan_retval_tls
; CHECK: ret i32
-; relaxed cmpxchg: bump up to "release"
+; relaxed cmpxchg: bump up to "release monotonic"
define i32 @CmpxchgMonotonic(i32* %p, i32 %a, i32 %b) sanitize_memory {
entry:
- %0 = cmpxchg i32* %p, i32 %a, i32 %b monotonic
+ %0 = cmpxchg i32* %p, i32 %a, i32 %b monotonic monotonic
ret i32 %0
}
@@ -64,7 +64,7 @@ entry:
; CHECK: icmp
; CHECK: br
; CHECK: @__msan_warning
-; CHECK: cmpxchg {{.*}} release
+; CHECK: cmpxchg {{.*}} release monotonic
; CHECK: store i32 0, {{.*}} @__msan_retval_tls
; CHECK: ret i32
diff --git a/test/Instrumentation/MemorySanitizer/check_access_address.ll b/test/Instrumentation/MemorySanitizer/check_access_address.ll
new file mode 100644
index 0000000..5660226
--- /dev/null
+++ b/test/Instrumentation/MemorySanitizer/check_access_address.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -msan -msan-check-access-address=1 -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"
+
+
+; Test byval argument shadow alignment
+
+define <2 x i64> @ByValArgumentShadowLargeAlignment(<2 x i64>* byval %p) sanitize_memory {
+entry:
+ %x = load <2 x i64>* %p
+ ret <2 x i64> %x
+}
+
+; CHECK: @ByValArgumentShadowLargeAlignment
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 16, i32 8, i1 false)
+; CHECK: ret <2 x i64>
+
+
+define i16 @ByValArgumentShadowSmallAlignment(i16* byval %p) sanitize_memory {
+entry:
+ %x = load i16* %p
+ ret i16 %x
+}
+
+; CHECK: @ByValArgumentShadowSmallAlignment
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 2, i32 2, i1 false)
+; CHECK: ret i16
diff --git a/test/Instrumentation/MemorySanitizer/msan_basic.ll b/test/Instrumentation/MemorySanitizer/msan_basic.ll
index 72a992d..6b71310 100644
--- a/test/Instrumentation/MemorySanitizer/msan_basic.ll
+++ b/test/Instrumentation/MemorySanitizer/msan_basic.ll
@@ -1,6 +1,5 @@
; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s
-; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK-ORIGINS %s
-; RUN: opt < %s -msan -msan-check-access-address=1 -S | FileCheck %s -check-prefix=CHECK-AA
+; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %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"
@@ -32,20 +31,16 @@ entry:
; CHECK: @Store
; CHECK: load {{.*}} @__msan_param_tls
+; CHECK-ORIGINS: load {{.*}} @__msan_param_origin_tls
; CHECK: store
-; CHECK: store
-; CHECK: ret void
-; CHECK-ORIGINS: @Store
-; CHECK-ORIGINS: load {{.*}} @__msan_param_tls
-; CHECK-ORIGINS: store
; CHECK-ORIGINS: icmp
; CHECK-ORIGINS: br i1
; CHECK-ORIGINS: <label>
; CHECK-ORIGINS: store
; CHECK-ORIGINS: br label
; CHECK-ORIGINS: <label>
-; CHECK-ORIGINS: store
-; CHECK-ORIGINS: ret void
+; CHECK: store
+; CHECK: ret void
; Check instrumentation of aligned stores
@@ -60,20 +55,16 @@ entry:
; CHECK: @AlignedStore
; CHECK: load {{.*}} @__msan_param_tls
+; CHECK-ORIGINS: load {{.*}} @__msan_param_origin_tls
; CHECK: store {{.*}} align 32
-; CHECK: store {{.*}} align 32
-; CHECK: ret void
-; CHECK-ORIGINS: @AlignedStore
-; CHECK-ORIGINS: load {{.*}} @__msan_param_tls
-; CHECK-ORIGINS: store {{.*}} align 32
; CHECK-ORIGINS: icmp
; CHECK-ORIGINS: br i1
; CHECK-ORIGINS: <label>
; CHECK-ORIGINS: store {{.*}} align 32
; CHECK-ORIGINS: br label
; CHECK-ORIGINS: <label>
-; CHECK-ORIGINS: store {{.*}} align 32
-; CHECK-ORIGINS: ret void
+; CHECK: store {{.*}} align 32
+; CHECK: ret void
; load followed by cmp: check that we load the shadow and call __msan_warning.
@@ -251,18 +242,23 @@ declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32,
; Check that we propagate shadow for "select"
-define i32 @Select(i32 %a, i32 %b, i32 %c) nounwind uwtable readnone sanitize_memory {
+define i32 @Select(i32 %a, i32 %b, i1 %c) nounwind uwtable readnone sanitize_memory {
entry:
- %tobool = icmp ne i32 %c, 0
- %cond = select i1 %tobool, i32 %a, i32 %b
+ %cond = select i1 %c, i32 %a, i32 %b
ret i32 %cond
}
; CHECK: @Select
-; CHECK: select
-; CHECK-NEXT: sext i1 {{.*}} to i32
-; CHECK-NEXT: or i32
-; CHECK-NEXT: select
+; CHECK: select i1
+; CHECK-DAG: or i32
+; CHECK-DAG: xor i32
+; CHECK: or i32
+; CHECK-DAG: select i1
+; CHECK-ORIGINS-DAG: select
+; CHECK-ORIGINS-DAG: select
+; CHECK-DAG: select i1
+; CHECK: store i32{{.*}}@__msan_retval_tls
+; CHECK-ORIGINS: store i32{{.*}}@__msan_retval_origin_tls
; CHECK: ret i32
@@ -278,17 +274,17 @@ entry:
; CHECK: @SelectVector
; CHECK: select <8 x i1>
-; CHECK-NEXT: sext <8 x i1> {{.*}} to <8 x i16>
-; CHECK-NEXT: or <8 x i16>
-; CHECK-NEXT: select <8 x i1>
+; CHECK-DAG: or <8 x i16>
+; CHECK-DAG: xor <8 x i16>
+; CHECK: or <8 x i16>
+; CHECK-DAG: select <8 x i1>
+; CHECK-ORIGINS-DAG: select
+; CHECK-ORIGINS-DAG: select
+; CHECK-DAG: select <8 x i1>
+; CHECK: store <8 x i16>{{.*}}@__msan_retval_tls
+; CHECK-ORIGINS: store i32{{.*}}@__msan_retval_origin_tls
; CHECK: ret <8 x i16>
-; CHECK-ORIGINS: @SelectVector
-; CHECK-ORIGINS: bitcast <8 x i1> {{.*}} to i8
-; CHECK-ORIGINS: icmp ne i8
-; CHECK-ORIGINS: select i1
-; CHECK-ORIGINS: ret <8 x i16>
-
; Check that we propagate origin for "select" with scalar condition and vector
; arguments. Select condition shadow is sign-extended to the vector type and
@@ -302,10 +298,13 @@ entry:
; CHECK: @SelectVector2
; CHECK: select i1
-; CHECK: sext i1 {{.*}} to i128
-; CHECK: bitcast i128 {{.*}} to <8 x i16>
+; CHECK-DAG: or <8 x i16>
+; CHECK-DAG: xor <8 x i16>
; CHECK: or <8 x i16>
-; CHECK: select i1
+; CHECK-DAG: select i1
+; CHECK-ORIGINS-DAG: select i1
+; CHECK-ORIGINS-DAG: select i1
+; CHECK-DAG: select i1
; CHECK: ret <8 x i16>
@@ -318,10 +317,27 @@ entry:
; CHECK: @SelectStruct
; CHECK: select i1 {{.*}}, { i64, i64 }
; CHECK-NEXT: select i1 {{.*}}, { i64, i64 } { i64 -1, i64 -1 }, { i64, i64 }
+; CHECK-ORIGINS: select i1
+; CHECK-ORIGINS: select i1
; CHECK-NEXT: select i1 {{.*}}, { i64, i64 }
; CHECK: ret { i64, i64 }
+define { i64*, double } @SelectStruct2(i1 zeroext %x, { i64*, double } %a, { i64*, double } %b) readnone sanitize_memory {
+entry:
+ %c = select i1 %x, { i64*, double } %a, { i64*, double } %b
+ ret { i64*, double } %c
+}
+
+; CHECK: @SelectStruct2
+; CHECK: select i1 {{.*}}, { i64, i64 }
+; CHECK-NEXT: select i1 {{.*}}, { i64, i64 } { i64 -1, i64 -1 }, { i64, i64 }
+; CHECK-ORIGINS: select i1
+; CHECK-ORIGINS: select i1
+; CHECK-NEXT: select i1 {{.*}}, { i64*, double }
+; CHECK: ret { i64*, double }
+
+
define i8* @IntToPtr(i64 %x) nounwind uwtable readnone sanitize_memory {
entry:
%0 = inttoptr i64 %x to i8*
@@ -330,9 +346,10 @@ entry:
; CHECK: @IntToPtr
; CHECK: load i64*{{.*}}__msan_param_tls
+; CHECK-ORIGINS-NEXT: load i32*{{.*}}__msan_param_origin_tls
; CHECK-NEXT: inttoptr
; CHECK-NEXT: store i64{{.*}}__msan_retval_tls
-; CHECK: ret i8
+; CHECK: ret i8*
define i8* @IntToPtr_ZExt(i16 %x) nounwind uwtable readnone sanitize_memory {
@@ -342,9 +359,11 @@ entry:
}
; CHECK: @IntToPtr_ZExt
+; CHECK: load i16*{{.*}}__msan_param_tls
; CHECK: zext
; CHECK-NEXT: inttoptr
-; CHECK: ret i8
+; CHECK-NEXT: store i64{{.*}}__msan_retval_tls
+; CHECK: ret i8*
; Check that we insert exactly one check on udiv
@@ -474,13 +493,8 @@ define i32 @ShadowLoadAlignmentSmall() nounwind uwtable sanitize_memory {
; CHECK: @ShadowLoadAlignmentSmall
; CHECK: load volatile i32* {{.*}} align 2
; CHECK: load i32* {{.*}} align 2
-; CHECK: ret i32
-
-; CHECK-ORIGINS: @ShadowLoadAlignmentSmall
-; CHECK-ORIGINS: load volatile i32* {{.*}} align 2
-; CHECK-ORIGINS: load i32* {{.*}} align 2
; CHECK-ORIGINS: load i32* {{.*}} align 4
-; CHECK-ORIGINS: ret i32
+; CHECK: ret i32
; Test vector manipulation instructions.
@@ -567,17 +581,13 @@ declare <16 x i8> @llvm.x86.sse3.ldu.dq(i8* %p) nounwind
; CHECK: @LoadIntrinsic
; CHECK: load <16 x i8>* {{.*}} align 1
+; CHECK-ORIGINS: [[ORIGIN:%[01-9a-z]+]] = load i32* {{.*}}
; CHECK-NOT: br
; CHECK-NOT: = or
; CHECK: call <16 x i8> @llvm.x86.sse3.ldu.dq
; CHECK: store <16 x i8> {{.*}} @__msan_retval_tls
-; CHECK: ret <16 x i8>
-
-; CHECK-ORIGINS: @LoadIntrinsic
-; CHECK-ORIGINS: [[ORIGIN:%[01-9a-z]+]] = load i32* {{.*}}
-; CHECK-ORIGINS: call <16 x i8> @llvm.x86.sse3.ldu.dq
; CHECK-ORIGINS: store i32 {{.*}}[[ORIGIN]], i32* @__msan_retval_origin_tls
-; CHECK-ORIGINS: ret <16 x i8>
+; CHECK: ret <16 x i8>
; Simple NoMem intrinsic
@@ -593,21 +603,17 @@ declare <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %a, <8 x i16> %b) nounwind
; CHECK: @Paddsw128
; CHECK-NEXT: load <8 x i16>* {{.*}} @__msan_param_tls
-; CHECK-NEXT: load <8 x i16>* {{.*}} @__msan_param_tls
-; CHECK-NEXT: = or <8 x i16>
-; CHECK-NEXT: call <8 x i16> @llvm.x86.sse2.padds.w
-; CHECK-NEXT: store <8 x i16> {{.*}} @__msan_retval_tls
-; CHECK-NEXT: ret <8 x i16>
-
-; CHECK-ORIGINS: @Paddsw128
; CHECK-ORIGINS: load i32* {{.*}} @__msan_param_origin_tls
+; CHECK-NEXT: load <8 x i16>* {{.*}} @__msan_param_tls
; CHECK-ORIGINS: load i32* {{.*}} @__msan_param_origin_tls
+; CHECK-NEXT: = or <8 x i16>
; CHECK-ORIGINS: = bitcast <8 x i16> {{.*}} to i128
; CHECK-ORIGINS-NEXT: = icmp ne i128 {{.*}}, 0
; CHECK-ORIGINS-NEXT: = select i1 {{.*}}, i32 {{.*}}, i32
-; CHECK-ORIGINS: call <8 x i16> @llvm.x86.sse2.padds.w
+; CHECK-NEXT: call <8 x i16> @llvm.x86.sse2.padds.w
+; CHECK-NEXT: store <8 x i16> {{.*}} @__msan_retval_tls
; CHECK-ORIGINS: store i32 {{.*}} @__msan_retval_origin_tls
-; CHECK-ORIGINS: ret <8 x i16>
+; CHECK-NEXT: ret <8 x i16>
; Test handling of vectors of pointers.
@@ -752,30 +758,6 @@ entry:
; CHECK: ret <2 x i64>
-; Test byval argument shadow alignment
-
-define <2 x i64> @ByValArgumentShadowLargeAlignment(<2 x i64>* byval %p) sanitize_memory {
-entry:
- %x = load <2 x i64>* %p
- ret <2 x i64> %x
-}
-
-; CHECK-AA: @ByValArgumentShadowLargeAlignment
-; CHECK-AA: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 16, i32 8, i1 false)
-; CHECK-AA: ret <2 x i64>
-
-
-define i16 @ByValArgumentShadowSmallAlignment(i16* byval %p) sanitize_memory {
-entry:
- %x = load i16* %p
- ret i16 %x
-}
-
-; CHECK-AA: @ByValArgumentShadowSmallAlignment
-; CHECK-AA: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 2, i32 2, i1 false)
-; CHECK-AA: ret i16
-
-
; Test origin propagation for insertvalue
define { i64, i32 } @make_pair_64_32(i64 %x, i32 %y) sanitize_memory {
@@ -801,3 +783,45 @@ entry:
; Second element app value
; CHECK-ORIGINS: insertvalue { i64, i32 } {{.*}}, i32 {{.*}}, 1
; CHECK-ORIGINS: ret { i64, i32 }
+
+
+; Test shadow propagation for aggregates passed through ellipsis.
+
+%struct.StructByVal = type { i32, i32, i32, i32 }
+
+declare void @VAArgStructFn(i32 %guard, ...)
+
+define void @VAArgStruct(%struct.StructByVal* nocapture %s) sanitize_memory {
+entry:
+ %agg.tmp2 = alloca %struct.StructByVal, align 8
+ %0 = bitcast %struct.StructByVal* %s to i8*
+ %agg.tmp.sroa.0.0..sroa_cast = bitcast %struct.StructByVal* %s to i64*
+ %agg.tmp.sroa.0.0.copyload = load i64* %agg.tmp.sroa.0.0..sroa_cast, align 4
+ %agg.tmp.sroa.2.0..sroa_idx = getelementptr inbounds %struct.StructByVal* %s, i64 0, i32 2
+ %agg.tmp.sroa.2.0..sroa_cast = bitcast i32* %agg.tmp.sroa.2.0..sroa_idx to i64*
+ %agg.tmp.sroa.2.0.copyload = load i64* %agg.tmp.sroa.2.0..sroa_cast, align 4
+ %1 = bitcast %struct.StructByVal* %agg.tmp2 to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %0, i64 16, i32 4, i1 false)
+ call void (i32, ...)* @VAArgStructFn(i32 undef, i64 %agg.tmp.sroa.0.0.copyload, i64 %agg.tmp.sroa.2.0.copyload, i64 %agg.tmp.sroa.0.0.copyload, i64 %agg.tmp.sroa.2.0.copyload, %struct.StructByVal* byval align 8 %agg.tmp2)
+ ret void
+}
+
+; "undef" and the first 2 structs go to general purpose registers;
+; the third struct goes to the overflow area byval
+
+; CHECK: @VAArgStruct
+; undef
+; CHECK: store i32 -1, i32* {{.*}}@__msan_va_arg_tls {{.*}}, align 8
+; first struct through general purpose registers
+; CHECK: store i64 {{.*}}, i64* {{.*}}@__msan_va_arg_tls{{.*}}, i64 8){{.*}}, align 8
+; CHECK: store i64 {{.*}}, i64* {{.*}}@__msan_va_arg_tls{{.*}}, i64 16){{.*}}, align 8
+; second struct through general purpose registers
+; CHECK: store i64 {{.*}}, i64* {{.*}}@__msan_va_arg_tls{{.*}}, i64 24){{.*}}, align 8
+; CHECK: store i64 {{.*}}, i64* {{.*}}@__msan_va_arg_tls{{.*}}, i64 32){{.*}}, align 8
+; third struct through the overflow area byval
+; CHECK: ptrtoint %struct.StructByVal* {{.*}} to i64
+; CHECK: bitcast { i32, i32, i32, i32 }* {{.*}}@__msan_va_arg_tls {{.*}}, i64 176
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+; CHECK: store i64 16, i64* @__msan_va_arg_overflow_size_tls
+; CHECK: call void (i32, ...)* @VAArgStructFn
+; CHECK: ret void
diff --git a/test/Instrumentation/MemorySanitizer/store-origin.ll b/test/Instrumentation/MemorySanitizer/store-origin.ll
new file mode 100644
index 0000000..024a10a
--- /dev/null
+++ b/test/Instrumentation/MemorySanitizer/store-origin.ll
@@ -0,0 +1,73 @@
+; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS1 %s
+; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS2 %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 origin instrumentation of stores.
+; Check that debug info for origin propagation code is set correctly.
+
+; Function Attrs: nounwind
+define void @Store(i32* nocapture %p, i32 %x) #0 {
+entry:
+ tail call void @llvm.dbg.value(metadata !{i32* %p}, i64 0, metadata !11), !dbg !16
+ tail call void @llvm.dbg.value(metadata !{i32 %x}, i64 0, metadata !12), !dbg !16
+ store i32 %x, i32* %p, align 4, !dbg !17, !tbaa !18
+ ret void, !dbg !22
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata) #1
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!13, !14}
+!llvm.ident = !{!15}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5.0 (204220)", i1 true, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit ] [/tmp/build0/../2.cc] [DW_LANG_C99]
+!1 = metadata !{metadata !"../2.cc", metadata !"/tmp/build0"}
+!2 = metadata !{}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"Store", metadata !"Store", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void (i32*, i32)* @Store, null, null, metadata !10, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [Store]
+!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/tmp/build0/../2.cc]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{null, metadata !8, metadata !9}
+!8 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
+!9 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!10 = metadata !{metadata !11, metadata !12}
+!11 = metadata !{i32 786689, metadata !4, metadata !"p", metadata !5, i32 16777217, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [p] [line 1]
+!12 = metadata !{i32 786689, metadata !4, metadata !"x", metadata !5, i32 33554433, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [x] [line 1]
+!13 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!14 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
+!15 = metadata !{metadata !"clang version 3.5.0 (204220)"}
+!16 = metadata !{i32 1, i32 0, metadata !4, null}
+!17 = metadata !{i32 2, i32 0, metadata !4, null}
+!18 = metadata !{metadata !19, metadata !19, i64 0}
+!19 = metadata !{metadata !"int", metadata !20, i64 0}
+!20 = metadata !{metadata !"omnipotent char", metadata !21, i64 0}
+!21 = metadata !{metadata !"Simple C/C++ TBAA"}
+!22 = metadata !{i32 3, i32 0, metadata !4, null}
+
+
+; CHECK: @Store
+; CHECK: load {{.*}} @__msan_param_tls
+; CHECK: [[ORIGIN:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls
+; CHECK: store {{.*}}!dbg ![[DBG:[01-9]+]]
+; CHECK: icmp
+; CHECK: br i1
+; CHECK: <label>
+
+; Origin tracking level 1: simply store the origin value
+; CHECK-ORIGINS1: store i32 {{.*}}[[ORIGIN]],{{.*}}!dbg !{{.*}}[[DBG]]
+
+; Origin tracking level 2: pass origin value through __msan_chain_origin and store the result.
+; CHECK-ORIGINS2: [[ORIGIN2:%[01-9a-z]+]] = call i32 @__msan_chain_origin(i32 {{.*}}[[ORIGIN]])
+; CHECK-ORIGINS2: store i32 {{.*}}[[ORIGIN2]],{{.*}}!dbg !{{.*}}[[DBG]]
+
+; CHECK: br label{{.*}}!dbg !{{.*}}[[DBG]]
+; CHECK: <label>
+; CHECK: store{{.*}}!dbg !{{.*}}[[DBG]]
+; CHECK: ret void
diff --git a/test/Instrumentation/MemorySanitizer/vector_shift.ll b/test/Instrumentation/MemorySanitizer/vector_shift.ll
new file mode 100644
index 0000000..d32f51b
--- /dev/null
+++ b/test/Instrumentation/MemorySanitizer/vector_shift.ll
@@ -0,0 +1,100 @@
+; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s
+
+; Test instrumentation of vector shift instructions.
+
+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"
+
+declare x86_mmx @llvm.x86.mmx.psll.d(x86_mmx, x86_mmx)
+declare <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32>, <8 x i32>)
+declare <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32>, <4 x i32>)
+declare <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16>, <8 x i16>)
+declare <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16>, i32)
+declare <2 x i64> @llvm.x86.sse2.psll.dq(<2 x i64>, i32)
+declare <2 x i64> @llvm.x86.sse2.psll.dq.bs(<2 x i64>, i32)
+
+define i64 @test_mmx(i64 %x.coerce, i64 %y.coerce) {
+entry:
+ %0 = bitcast i64 %x.coerce to <2 x i32>
+ %1 = bitcast <2 x i32> %0 to x86_mmx
+ %2 = bitcast i64 %y.coerce to x86_mmx
+ %3 = tail call x86_mmx @llvm.x86.mmx.psll.d(x86_mmx %1, x86_mmx %2)
+ %4 = bitcast x86_mmx %3 to <2 x i32>
+ %5 = bitcast <2 x i32> %4 to <1 x i64>
+ %6 = extractelement <1 x i64> %5, i32 0
+ ret i64 %6
+}
+
+; CHECK: @test_mmx
+; CHECK: = icmp ne i64 {{.*}}, 0
+; CHECK: [[C:%.*]] = sext i1 {{.*}} to i64
+; CHECK: [[A:%.*]] = call x86_mmx @llvm.x86.mmx.psll.d(
+; CHECK: [[B:%.*]] = bitcast x86_mmx {{.*}}[[A]] to i64
+; CHECK: = or i64 {{.*}}[[B]], {{.*}}[[C]]
+; CHECK: call x86_mmx @llvm.x86.mmx.psll.d(
+; CHECK: ret i64
+
+
+define <8 x i16> @test_sse2_scalar(<8 x i16> %x, i32 %y) {
+entry:
+ %0 = tail call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %x, i32 %y)
+ ret <8 x i16> %0
+}
+
+; CHECK: @test_sse2_scalar
+; CHECK: = icmp ne i32 {{.*}}, 0
+; CHECK: = sext i1 {{.*}} to i128
+; CHECK: = bitcast i128 {{.*}} to <8 x i16>
+; CHECK: = call <8 x i16> @llvm.x86.sse2.pslli.w(
+; CHECK: = or <8 x i16>
+; CHECK: call <8 x i16> @llvm.x86.sse2.pslli.w(
+; CHECK: ret <8 x i16>
+
+
+define <8 x i16> @test_sse2(<8 x i16> %x, <8 x i16> %y) {
+entry:
+ %0 = tail call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> %x, <8 x i16> %y)
+ ret <8 x i16> %0
+}
+
+; CHECK: @test_sse2
+; CHECK: = bitcast <8 x i16> {{.*}} to i128
+; CHECK: = trunc i128 {{.*}} to i64
+; CHECK: = icmp ne i64 {{.*}}, 0
+; CHECK: = sext i1 {{.*}} to i128
+; CHECK: = bitcast i128 {{.*}} to <8 x i16>
+; CHECK: = call <8 x i16> @llvm.x86.sse2.psrl.w(
+; CHECK: = or <8 x i16>
+; CHECK: call <8 x i16> @llvm.x86.sse2.psrl.w(
+; CHECK: ret <8 x i16>
+
+
+; Test variable shift (i.e. vector by vector).
+
+define <4 x i32> @test_avx2(<4 x i32> %x, <4 x i32> %y) {
+entry:
+ %0 = tail call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> %x, <4 x i32> %y)
+ ret <4 x i32> %0
+}
+
+; CHECK: @test_avx2
+; CHECK: = icmp ne <4 x i32> {{.*}}, zeroinitializer
+; CHECK: = sext <4 x i1> {{.*}} to <4 x i32>
+; CHECK: = call <4 x i32> @llvm.x86.avx2.psllv.d(
+; CHECK: = or <4 x i32>
+; CHECK: = tail call <4 x i32> @llvm.x86.avx2.psllv.d(
+; CHECK: ret <4 x i32>
+
+define <8 x i32> @test_avx2_256(<8 x i32> %x, <8 x i32> %y) {
+entry:
+ %0 = tail call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> %x, <8 x i32> %y)
+ ret <8 x i32> %0
+}
+
+; CHECK: @test_avx2_256
+; CHECK: = icmp ne <8 x i32> {{.*}}, zeroinitializer
+; CHECK: = sext <8 x i1> {{.*}} to <8 x i32>
+; CHECK: = call <8 x i32> @llvm.x86.avx2.psllv.d.256(
+; CHECK: = or <8 x i32>
+; CHECK: = tail call <8 x i32> @llvm.x86.avx2.psllv.d.256(
+; CHECK: ret <8 x i32>
diff --git a/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll b/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll
index 555695d..65037cb 100644
--- a/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll
+++ b/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll
@@ -8,20 +8,20 @@ target triple = "x86_64-unknown-linux-gnu"
; wrapper function.
; This does not depend on the sanitize_memory attribute.
-define i32 @func(i32 (i32, i32)* nocapture %f, i32 %x, i32 %y) {
+define i32 @func1(i32 (i32, i32)* nocapture %f, i32 %x, i32 %y) {
entry:
%call = tail call i32 %f(i32 %x, i32 %y)
ret i32 %call
}
-; CHECK: @func
+; CHECK: @func1
; CHECK: bitcast i32 (i32, i32)* %f to void ()*
; CHECK: call void ()* (void ()*)* @zzz(void ()*
; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i32 (i32, i32)*
; CHECK: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}})
; CHECK: ret i32
-; CHECK-FAST: @func
+; CHECK-FAST: @func1
; CHECK-FAST: bitcast i32 (i32, i32)* %f to void ()*
; CHECK-FAST-DAG: icmp ult void ()* {{.*}}, bitcast (i32* @__executable_start to void ()*)
; CHECK-FAST-DAG: icmp uge void ()* {{.*}}, bitcast (i32* @_end to void ()*)
@@ -32,3 +32,29 @@ entry:
; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i32 (i32, i32)* [ %f, %entry ], [ {{.*}} ]
; CHECK-FAST: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}})
; CHECK-FAST: ret i32
+
+
+; The same test, but with a complex expression as the call target.
+
+declare i8* @callee(i32)
+
+define i8* @func2(i64 %x) #1 {
+entry:
+ %call = tail call i8* bitcast (i8* (i32)* @callee to i8* (i64)*)(i64 %x)
+ ret i8* %call
+}
+
+; CHECK: @func2
+; CHECK: call {{.*}} @zzz
+; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i8* (i64)*
+; CHECK: call i8* {{.*}}[[A]](i64 {{.*}})
+; CHECK: ret i8*
+
+; CHECK-FAST: @func2
+; CHECK-FAST: {{br i1 or .* icmp ult .* bitcast .* @callee .* @__executable_start.* icmp uge .* bitcast .* @callee .* @_end}}
+; CHECK-FAST: {{call .* @zzz.* bitcast .*@callee}}
+; CHECK-FAST: bitcast void ()* {{.*}} to i8* (i64)*
+; CHECK-FAST: br label
+; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i8* (i64)* [{{.*bitcast .* @callee.*, %entry.*}}], [ {{.*}} ]
+; CHECK-FAST: call i8* {{.*}}[[A]](i64 {{.*}})
+; CHECK-FAST: ret i8*
diff --git a/test/Instrumentation/ThreadSanitizer/atomic.ll b/test/Instrumentation/ThreadSanitizer/atomic.ll
index 70b6cbb..e40268f 100644
--- a/test/Instrumentation/ThreadSanitizer/atomic.ll
+++ b/test/Instrumentation/ThreadSanitizer/atomic.ll
@@ -348,7 +348,7 @@ entry:
define void @atomic8_cas_monotonic(i8* %a) nounwind uwtable {
entry:
- cmpxchg i8* %a, i8 0, i8 1 monotonic
+ cmpxchg i8* %a, i8 0, i8 1 monotonic monotonic
ret void
}
; CHECK: atomic8_cas_monotonic
@@ -356,7 +356,7 @@ entry:
define void @atomic8_cas_acquire(i8* %a) nounwind uwtable {
entry:
- cmpxchg i8* %a, i8 0, i8 1 acquire
+ cmpxchg i8* %a, i8 0, i8 1 acquire acquire
ret void
}
; CHECK: atomic8_cas_acquire
@@ -364,7 +364,7 @@ entry:
define void @atomic8_cas_release(i8* %a) nounwind uwtable {
entry:
- cmpxchg i8* %a, i8 0, i8 1 release
+ cmpxchg i8* %a, i8 0, i8 1 release monotonic
ret void
}
; CHECK: atomic8_cas_release
@@ -372,7 +372,7 @@ entry:
define void @atomic8_cas_acq_rel(i8* %a) nounwind uwtable {
entry:
- cmpxchg i8* %a, i8 0, i8 1 acq_rel
+ cmpxchg i8* %a, i8 0, i8 1 acq_rel acquire
ret void
}
; CHECK: atomic8_cas_acq_rel
@@ -380,7 +380,7 @@ entry:
define void @atomic8_cas_seq_cst(i8* %a) nounwind uwtable {
entry:
- cmpxchg i8* %a, i8 0, i8 1 seq_cst
+ cmpxchg i8* %a, i8 0, i8 1 seq_cst seq_cst
ret void
}
; CHECK: atomic8_cas_seq_cst
@@ -732,7 +732,7 @@ entry:
define void @atomic16_cas_monotonic(i16* %a) nounwind uwtable {
entry:
- cmpxchg i16* %a, i16 0, i16 1 monotonic
+ cmpxchg i16* %a, i16 0, i16 1 monotonic monotonic
ret void
}
; CHECK: atomic16_cas_monotonic
@@ -740,7 +740,7 @@ entry:
define void @atomic16_cas_acquire(i16* %a) nounwind uwtable {
entry:
- cmpxchg i16* %a, i16 0, i16 1 acquire
+ cmpxchg i16* %a, i16 0, i16 1 acquire acquire
ret void
}
; CHECK: atomic16_cas_acquire
@@ -748,7 +748,7 @@ entry:
define void @atomic16_cas_release(i16* %a) nounwind uwtable {
entry:
- cmpxchg i16* %a, i16 0, i16 1 release
+ cmpxchg i16* %a, i16 0, i16 1 release monotonic
ret void
}
; CHECK: atomic16_cas_release
@@ -756,7 +756,7 @@ entry:
define void @atomic16_cas_acq_rel(i16* %a) nounwind uwtable {
entry:
- cmpxchg i16* %a, i16 0, i16 1 acq_rel
+ cmpxchg i16* %a, i16 0, i16 1 acq_rel acquire
ret void
}
; CHECK: atomic16_cas_acq_rel
@@ -764,7 +764,7 @@ entry:
define void @atomic16_cas_seq_cst(i16* %a) nounwind uwtable {
entry:
- cmpxchg i16* %a, i16 0, i16 1 seq_cst
+ cmpxchg i16* %a, i16 0, i16 1 seq_cst seq_cst
ret void
}
; CHECK: atomic16_cas_seq_cst
@@ -1116,7 +1116,7 @@ entry:
define void @atomic32_cas_monotonic(i32* %a) nounwind uwtable {
entry:
- cmpxchg i32* %a, i32 0, i32 1 monotonic
+ cmpxchg i32* %a, i32 0, i32 1 monotonic monotonic
ret void
}
; CHECK: atomic32_cas_monotonic
@@ -1124,7 +1124,7 @@ entry:
define void @atomic32_cas_acquire(i32* %a) nounwind uwtable {
entry:
- cmpxchg i32* %a, i32 0, i32 1 acquire
+ cmpxchg i32* %a, i32 0, i32 1 acquire acquire
ret void
}
; CHECK: atomic32_cas_acquire
@@ -1132,7 +1132,7 @@ entry:
define void @atomic32_cas_release(i32* %a) nounwind uwtable {
entry:
- cmpxchg i32* %a, i32 0, i32 1 release
+ cmpxchg i32* %a, i32 0, i32 1 release monotonic
ret void
}
; CHECK: atomic32_cas_release
@@ -1140,7 +1140,7 @@ entry:
define void @atomic32_cas_acq_rel(i32* %a) nounwind uwtable {
entry:
- cmpxchg i32* %a, i32 0, i32 1 acq_rel
+ cmpxchg i32* %a, i32 0, i32 1 acq_rel acquire
ret void
}
; CHECK: atomic32_cas_acq_rel
@@ -1148,7 +1148,7 @@ entry:
define void @atomic32_cas_seq_cst(i32* %a) nounwind uwtable {
entry:
- cmpxchg i32* %a, i32 0, i32 1 seq_cst
+ cmpxchg i32* %a, i32 0, i32 1 seq_cst seq_cst
ret void
}
; CHECK: atomic32_cas_seq_cst
@@ -1500,7 +1500,7 @@ entry:
define void @atomic64_cas_monotonic(i64* %a) nounwind uwtable {
entry:
- cmpxchg i64* %a, i64 0, i64 1 monotonic
+ cmpxchg i64* %a, i64 0, i64 1 monotonic monotonic
ret void
}
; CHECK: atomic64_cas_monotonic
@@ -1508,7 +1508,7 @@ entry:
define void @atomic64_cas_acquire(i64* %a) nounwind uwtable {
entry:
- cmpxchg i64* %a, i64 0, i64 1 acquire
+ cmpxchg i64* %a, i64 0, i64 1 acquire acquire
ret void
}
; CHECK: atomic64_cas_acquire
@@ -1516,7 +1516,7 @@ entry:
define void @atomic64_cas_release(i64* %a) nounwind uwtable {
entry:
- cmpxchg i64* %a, i64 0, i64 1 release
+ cmpxchg i64* %a, i64 0, i64 1 release monotonic
ret void
}
; CHECK: atomic64_cas_release
@@ -1524,7 +1524,7 @@ entry:
define void @atomic64_cas_acq_rel(i64* %a) nounwind uwtable {
entry:
- cmpxchg i64* %a, i64 0, i64 1 acq_rel
+ cmpxchg i64* %a, i64 0, i64 1 acq_rel acquire
ret void
}
; CHECK: atomic64_cas_acq_rel
@@ -1532,7 +1532,7 @@ entry:
define void @atomic64_cas_seq_cst(i64* %a) nounwind uwtable {
entry:
- cmpxchg i64* %a, i64 0, i64 1 seq_cst
+ cmpxchg i64* %a, i64 0, i64 1 seq_cst seq_cst
ret void
}
; CHECK: atomic64_cas_seq_cst
@@ -1884,7 +1884,7 @@ entry:
define void @atomic128_cas_monotonic(i128* %a) nounwind uwtable {
entry:
- cmpxchg i128* %a, i128 0, i128 1 monotonic
+ cmpxchg i128* %a, i128 0, i128 1 monotonic monotonic
ret void
}
; CHECK: atomic128_cas_monotonic
@@ -1892,7 +1892,7 @@ entry:
define void @atomic128_cas_acquire(i128* %a) nounwind uwtable {
entry:
- cmpxchg i128* %a, i128 0, i128 1 acquire
+ cmpxchg i128* %a, i128 0, i128 1 acquire acquire
ret void
}
; CHECK: atomic128_cas_acquire
@@ -1900,7 +1900,7 @@ entry:
define void @atomic128_cas_release(i128* %a) nounwind uwtable {
entry:
- cmpxchg i128* %a, i128 0, i128 1 release
+ cmpxchg i128* %a, i128 0, i128 1 release monotonic
ret void
}
; CHECK: atomic128_cas_release
@@ -1908,7 +1908,7 @@ entry:
define void @atomic128_cas_acq_rel(i128* %a) nounwind uwtable {
entry:
- cmpxchg i128* %a, i128 0, i128 1 acq_rel
+ cmpxchg i128* %a, i128 0, i128 1 acq_rel acquire
ret void
}
; CHECK: atomic128_cas_acq_rel
@@ -1916,7 +1916,7 @@ entry:
define void @atomic128_cas_seq_cst(i128* %a) nounwind uwtable {
entry:
- cmpxchg i128* %a, i128 0, i128 1 seq_cst
+ cmpxchg i128* %a, i128 0, i128 1 seq_cst seq_cst
ret void
}
; CHECK: atomic128_cas_seq_cst
diff --git a/test/Instrumentation/ThreadSanitizer/vptr_update.ll b/test/Instrumentation/ThreadSanitizer/vptr_update.ll
index 95c7bb0..83d28b6 100644
--- a/test/Instrumentation/ThreadSanitizer/vptr_update.ll
+++ b/test/Instrumentation/ThreadSanitizer/vptr_update.ll
@@ -4,10 +4,37 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
define void @Foo(i8** nocapture %a, i8* %b) nounwind uwtable sanitize_thread {
entry:
+; CHECK-LABEL: @Foo
; CHECK: call void @__tsan_vptr_update
+; CHECK: ret void
store i8* %b, i8** %a, align 8, !tbaa !0
ret void
}
+
+define void @FooInt(i64* nocapture %a, i64 %b) nounwind uwtable sanitize_thread {
+entry:
+; CHECK-LABEL: @FooInt
+; CHECK: call void @__tsan_vptr_update
+; CHECK: ret void
+ store i64 %b, i64* %a, align 8, !tbaa !0
+ ret void
+}
+
+
+declare i32 @Func1()
+declare i32 @Func2()
+
+; Test that we properly handle vector stores marked as vtable updates.
+define void @VectorVptrUpdate(<2 x i8*>* nocapture %a, i8* %b) nounwind uwtable sanitize_thread {
+entry:
+; CHECK-LABEL: @VectorVptrUpdate
+; CHECK: call void @__tsan_vptr_update{{.*}}Func1
+; CHECK-NOT: call void @__tsan_vptr_update
+; CHECK: ret void
+ store <2 x i8 *> <i8* bitcast(i32 ()* @Func1 to i8 *), i8* bitcast(i32 ()* @Func2 to i8 *)>, <2 x i8 *>* %a, align 8, !tbaa !0
+ ret void
+}
+
!0 = metadata !{metadata !2, metadata !2, i64 0}
!1 = metadata !{metadata !"Simple C/C++ TBAA", null}
!2 = metadata !{metadata !"vtable pointer", metadata !1}