Skip to content

Commit 560b83c

Browse files
authored
[TySan][Clang] Add clang flag to use tysan outlined instrumentation a… (#166170)
…nd update docs
1 parent 2a3e745 commit 560b83c

File tree

23 files changed

+1565
-159
lines changed

23 files changed

+1565
-159
lines changed

clang/docs/TypeSanitizer.rst

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ code is build with ``-fno-strict-aliasing``, sacrificing performance.
2020
TypeSanitizer is built to catch when these strict aliasing rules have been violated, helping
2121
users find where such bugs originate in their code despite the code looking valid at first glance.
2222

23-
As TypeSanitizer is still experimental, it can currently have a large impact on runtime speed,
24-
memory use, and code size. It also has a large compile-time overhead. Work is being done to
25-
reduce these impacts.
23+
Typical memory overhead introduced by TypeSanitizer is about **8x**. Runtime slowdown varies greatly
24+
depending on how often the instrumented code relies on type aliasing. In the best case slowdown is
25+
**2x-3x**.
2626

2727
The TypeSanitizer Algorithm
2828
===========================
@@ -128,6 +128,14 @@ references to LLVM IR specific terms.
128128
Sanitizer features
129129
==================
130130

131+
Instrumentation code inlining
132+
------------------------------
133+
134+
By default TypeSanitizer inserts instrumentation through function calls. This may lead to a reduction in
135+
runtime performance. ``-fno-sanitize-type-outline-instrumentation`` (default: ``false``) forces all
136+
code instrumentation to be inlined. This will increase the size of the generated code and compiler
137+
overhead, but may improve the runtime performance of the resulting code.
138+
131139
``__has_feature(type_sanitizer)``
132140
------------------------------------
133141

@@ -179,10 +187,6 @@ Limitations
179187
shadow memory for each byte of user memory.
180188
* There are transformation passes which run before TypeSanitizer. If these
181189
passes optimize out an aliasing violation, TypeSanitizer cannot catch it.
182-
* Currently, all instrumentation is inlined. This can result in a **15x**
183-
(on average) increase in generated file size, and **3x** to **7x** increase
184-
in compile time. In some documented cases this can cause the compiler to hang.
185-
There are plans to improve this in the future.
186190
* Codebases that use unions and struct-initialized variables can see incorrect
187191
results, as TypeSanitizer doesn't yet instrument these reliably.
188192
* Since Clang & LLVM's TBAA system is used to generate the checks used by the

clang/docs/UsersManual.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,15 @@ are listed below.
22772277

22782278
See :doc: `AddressSanitizer` for more details.
22792279

2280+
.. option:: -f[no-]sanitize-type-outline-instrumentation
2281+
2282+
Controls how type sanitizer code is generated. If enabled will always use
2283+
a function call instead of inlining the code. Turning this option off may
2284+
result in better run-time performance, but will increase binary size and
2285+
compilation overhead.
2286+
2287+
See :doc: `TypeSanitizer` for more details.
2288+
22802289
.. option:: -f[no-]sanitize-stats
22812290

22822291
Enable simple statistics gathering for the enabled sanitizers.

clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class SanitizerArgs {
6767
bool TsanFuncEntryExit = true;
6868
bool TsanAtomics = true;
6969
bool MinimalRuntime = false;
70+
bool TysanOutlineInstrumentation = true;
7071
// True if cross-dso CFI support if provided by the system (i.e. Android).
7172
bool ImplicitCfiRuntime = false;
7273
bool NeedsMemProfRt = false;

clang/include/clang/Options/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,6 +2463,12 @@ def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-o
24632463
def fno_sanitize_address_outline_instrumentation : Flag<["-"], "fno-sanitize-address-outline-instrumentation">,
24642464
Group<f_clang_Group>,
24652465
HelpText<"Use default code inlining logic for the address sanitizer">;
2466+
def fsanitize_type_outline_instrumentation : Flag<["-"], "fsanitize-type-outline-instrumentation">,
2467+
Group<f_clang_Group>,
2468+
HelpText<"Always generate function calls for type sanitizer instrumentation">;
2469+
def fno_sanitize_type_outline_instrumentation : Flag<["-"], "fno-sanitize-type-outline-instrumentation">,
2470+
Group<f_clang_Group>,
2471+
HelpText<"Use code inlining logic for the type sanitizer">;
24662472
defm sanitize_stable_abi
24672473
: OptInCC1FFlag<"sanitize-stable-abi", "Stable ", "Conventional ",
24682474
"ABI instrumentation for sanitizer runtime. Default: Conventional">;

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,13 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
11761176
options::OPT_fno_sanitize_alloc_token_extended, AllocTokenExtended);
11771177
}
11781178

1179+
if (AllAddedKinds & SanitizerKind::Type) {
1180+
TysanOutlineInstrumentation =
1181+
Args.hasFlag(options::OPT_fsanitize_type_outline_instrumentation,
1182+
options::OPT_fno_sanitize_type_outline_instrumentation,
1183+
TysanOutlineInstrumentation);
1184+
}
1185+
11791186
LinkRuntimes = Args.hasFlag(options::OPT_fsanitize_link_runtime,
11801187
options::OPT_fno_sanitize_link_runtime,
11811188
!Args.hasArg(options::OPT_r));
@@ -1500,6 +1507,11 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
15001507
CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
15011508
}
15021509

1510+
if (!TysanOutlineInstrumentation) {
1511+
CmdArgs.push_back("-mllvm");
1512+
CmdArgs.push_back("-tysan-outline-instrumentation=false");
1513+
}
1514+
15031515
// When emitting Stable ABI instrumentation, force outlining calls and avoid
15041516
// inlining shadow memory poisoning. While this is a big performance burden
15051517
// for now it allows full abstraction from implementation details.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// UNSUPPORTED: target={{.*}}-windows-{{.*}}
2+
3+
// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \
4+
// RUN: -fno-sanitize-type-outline-instrumentation \
5+
// RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE
6+
// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \
7+
// RUN: -fsanitize-type-outline-instrumentation \
8+
// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE
9+
10+
// CHECK-LABEL: @alias
11+
// CHECK: __tysan_app_memory_mask
12+
// CHECK: __tysan_shadow_memory_address
13+
// CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_mem_inst
14+
// CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_with_shadow_update
15+
// CHECK-OUTLINE: call{{.*}}@__tysan_instrument_mem_inst
16+
// CHECK-OUTLINE: call{{.*}}@__tysan_instrument_with_shadow_update
17+
18+
float alias(int *ptr){
19+
float *aliasedPtr = (float *)ptr;
20+
*aliasedPtr *= 2.0f;
21+
return *aliasedPtr;
22+
}

llvm/docs/ReleaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ Changes to BOLT
222222
Changes to Sanitizers
223223
---------------------
224224

225+
* TypeSanitizer no longer inlines all instrumentation by default. Added the
226+
`-f[no-]sanitize-type-outline-instrumentation` flags to give users control
227+
over this behaviour.
228+
225229
Other Changes
226230
-------------
227231

llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static cl::opt<bool> ClOutlineInstrumentation(
6262
"tysan-outline-instrumentation",
6363
cl::desc("Uses function calls for all TySan instrumentation, reducing "
6464
"ELF size"),
65-
cl::Hidden, cl::init(false));
65+
cl::Hidden, cl::init(true));
6666

6767
static cl::opt<bool> ClVerifyOutlinedInstrumentation(
6868
"tysan-verify-outlined-instrumentation",

llvm/test/Instrumentation/TypeSanitizer/access-with-offset.ll

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
2-
; RUN: opt -passes='tysan' -S %s | FileCheck %s
32

4-
;.
3+
; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE
4+
; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE
5+
56
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
67
; CHECK: @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [18 x i8] } { i64 2, i64 0, [18 x i8] c"Simple C/C++ TBAA\00" }, comdat
78
; CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat
@@ -11,6 +12,24 @@
1112
; CHECK: @__tysan_shadow_memory_address = external global i64
1213
; CHECK: @__tysan_app_memory_mask = external global i64
1314
;.
15+
; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
16+
; CHECK-INLINE: @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [18 x i8] } { i64 2, i64 0, [18 x i8] c"Simple C/C++ TBAA\00" }, comdat
17+
; CHECK-INLINE: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat
18+
; CHECK-INLINE: @__tysan_v1_any_20pointer = linkonce_odr constant { i64, i64, ptr, i64, [12 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [12 x i8] c"any pointer\00" }, comdat
19+
; CHECK-INLINE: @__tysan_v1_any_20pointer_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_any_20pointer, ptr @__tysan_v1_any_20pointer, i64 0 }, comdat
20+
; CHECK-INLINE: @llvm.used = appending global [5 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_any_20pointer, ptr @__tysan_v1_any_20pointer_o_0], section "llvm.metadata"
21+
; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64
22+
; CHECK-INLINE: @__tysan_app_memory_mask = external global i64
23+
;.
24+
; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
25+
; CHECK-OUTLINE: @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [18 x i8] } { i64 2, i64 0, [18 x i8] c"Simple C/C++ TBAA\00" }, comdat
26+
; CHECK-OUTLINE: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat
27+
; CHECK-OUTLINE: @__tysan_v1_any_20pointer = linkonce_odr constant { i64, i64, ptr, i64, [12 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [12 x i8] c"any pointer\00" }, comdat
28+
; CHECK-OUTLINE: @__tysan_v1_any_20pointer_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_any_20pointer, ptr @__tysan_v1_any_20pointer, i64 0 }, comdat
29+
; CHECK-OUTLINE: @llvm.used = appending global [5 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2fC_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_any_20pointer, ptr @__tysan_v1_any_20pointer_o_0], section "llvm.metadata"
30+
; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64
31+
; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64
32+
;.
1433
define ptr @test_load_offset(ptr %argv) {
1534
; CHECK-LABEL: define ptr @test_load_offset(
1635
; CHECK-SAME: ptr [[ARGV:%.*]]) {
@@ -52,6 +71,55 @@ define ptr @test_load_offset(ptr %argv) {
5271
; CHECK-NEXT: [[L:%.*]] = load ptr, ptr null, align 8, !tbaa [[ANYPTR_TBAA1:![0-9]+]]
5372
; CHECK-NEXT: ret ptr [[L]]
5473
;
74+
; CHECK-INLINE-LABEL: define ptr @test_load_offset(
75+
; CHECK-INLINE-SAME: ptr [[ARGV:%.*]]) {
76+
; CHECK-INLINE-NEXT: [[ENTRY:.*:]]
77+
; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4
78+
; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4
79+
; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 0, [[APP_MEM_MASK]]
80+
; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3
81+
; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]]
82+
; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr
83+
; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8
84+
; CHECK-INLINE-NEXT: [[DESC_SET:%.*]] = icmp eq ptr [[SHADOW_DESC]], null
85+
; CHECK-INLINE-NEXT: br i1 [[DESC_SET]], label %[[SET_TYPE:.*]], label %[[BB0:.*]], !prof [[PROF0:![0-9]+]]
86+
; CHECK-INLINE: [[SET_TYPE]]:
87+
; CHECK-INLINE-NEXT: store ptr @__tysan_v1_any_20pointer_o_0, ptr [[SHADOW_PTR]], align 8
88+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8
89+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr
90+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8
91+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16
92+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr
93+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8
94+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24
95+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr
96+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8
97+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_4_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 32
98+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_4_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_4_OFFSET]] to ptr
99+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -4 to ptr), ptr [[SHADOW_BYTE_4_PTR]], align 8
100+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_5_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 40
101+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_5_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_5_OFFSET]] to ptr
102+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -5 to ptr), ptr [[SHADOW_BYTE_5_PTR]], align 8
103+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_6_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 48
104+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_6_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_6_OFFSET]] to ptr
105+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -6 to ptr), ptr [[SHADOW_BYTE_6_PTR]], align 8
106+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_7_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 56
107+
; CHECK-INLINE-NEXT: [[SHADOW_BYTE_7_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_7_OFFSET]] to ptr
108+
; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -7 to ptr), ptr [[SHADOW_BYTE_7_PTR]], align 8
109+
; CHECK-INLINE-NEXT: br label %[[BB0]]
110+
; CHECK-INLINE: [[BB0]]:
111+
; CHECK-INLINE-NEXT: [[L:%.*]] = load ptr, ptr null, align 8, !tbaa [[ANYPTR_TBAA1:![0-9]+]]
112+
; CHECK-INLINE-NEXT: ret ptr [[L]]
113+
;
114+
; CHECK-OUTLINE-LABEL: define ptr @test_load_offset(
115+
; CHECK-OUTLINE-SAME: ptr [[ARGV:%.*]]) {
116+
; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]]
117+
; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4
118+
; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4
119+
; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr null, ptr @__tysan_v1_any_20pointer_o_0, i1 false, i64 8, i32 1)
120+
; CHECK-OUTLINE-NEXT: [[L:%.*]] = load ptr, ptr null, align 8, !tbaa [[ANYPTR_TBAA0:![0-9]+]]
121+
; CHECK-OUTLINE-NEXT: ret ptr [[L]]
122+
;
55123
entry:
56124
%l = load ptr, ptr null, align 8, !tbaa !0
57125
ret ptr %l
@@ -61,12 +129,25 @@ entry:
61129
!1 = !{!"any pointer", !2, i64 0}
62130
!2 = !{!"omnipotent char", !3, i64 0}
63131
!3 = !{!"Simple C/C++ TBAA"}
64-
;.
65132
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind }
66-
;.
67133
; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000}
68134
; CHECK: [[ANYPTR_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0}
69135
; CHECK: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0}
70136
; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
71137
; CHECK: [[META4]] = !{!"Simple C/C++ TBAA"}
72138
;.
139+
; CHECK-INLINE: attributes #[[ATTR0:[0-9]+]] = { nounwind }
140+
;.
141+
; CHECK-OUTLINE: attributes #[[ATTR0:[0-9]+]] = { nounwind }
142+
;.
143+
; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000}
144+
; CHECK-INLINE: [[ANYPTR_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0}
145+
; CHECK-INLINE: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0}
146+
; CHECK-INLINE: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
147+
; CHECK-INLINE: [[META4]] = !{!"Simple C/C++ TBAA"}
148+
;.
149+
; CHECK-OUTLINE: [[ANYPTR_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
150+
; CHECK-OUTLINE: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0}
151+
; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
152+
; CHECK-OUTLINE: [[META3]] = !{!"Simple C/C++ TBAA"}
153+
;.

llvm/test/Instrumentation/TypeSanitizer/alloca-only.ll

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
22
; Test basic type sanitizer instrumentation.
33
;
4-
; RUN: opt -passes='tysan' -S %s | FileCheck %s
4+
; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE
5+
; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE
56

67
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
78

8-
;.
99
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata"
1010
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
1111
; CHECK: @__tysan_shadow_memory_address = external global i64
1212
; CHECK: @__tysan_app_memory_mask = external global i64
1313
;.
14+
; CHECK-INLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata"
15+
; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
16+
; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64
17+
; CHECK-INLINE: @__tysan_app_memory_mask = external global i64
18+
;.
19+
; CHECK-OUTLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata"
20+
; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
21+
; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64
22+
; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64
23+
;.
1424
define void @test_alloca_only() sanitize_type {
1525
; CHECK-LABEL: @test_alloca_only(
1626
; CHECK-NEXT: entry:
@@ -26,6 +36,29 @@ define void @test_alloca_only() sanitize_type {
2636
; CHECK-NEXT: call void @foo(ptr [[TMP1]])
2737
; CHECK-NEXT: ret void
2838
;
39+
; CHECK-INLINE-LABEL: @test_alloca_only(
40+
; CHECK-INLINE-NEXT: entry:
41+
; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8
42+
; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8
43+
; CHECK-INLINE-NEXT: [[A:%.*]] = alloca i32, align 4
44+
; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
45+
; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]]
46+
; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3
47+
; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]]
48+
; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
49+
; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 32, i1 false)
50+
; CHECK-INLINE-NEXT: call void @foo(ptr [[A]])
51+
; CHECK-INLINE-NEXT: ret void
52+
;
53+
; CHECK-OUTLINE-LABEL: @test_alloca_only(
54+
; CHECK-OUTLINE-NEXT: entry:
55+
; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8
56+
; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8
57+
; CHECK-OUTLINE-NEXT: [[A:%.*]] = alloca i32, align 4
58+
; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[A]], ptr null, i64 4, i1 false)
59+
; CHECK-OUTLINE-NEXT: call void @foo(ptr [[A]])
60+
; CHECK-OUTLINE-NEXT: ret void
61+
;
2962
entry:
3063
%a = alloca i32
3164
call void @foo(ptr %a)
@@ -42,8 +75,14 @@ declare void @foo(ptr)
4275
!4 = !{!"_ZTS1x", !2, i64 0, !2, i64 4}
4376
!5 = !{!"_ZTS1v", !2, i64 8, !2, i64 12, !4, i64 16}
4477
!6 = !{!5, !2, i64 12}
45-
;.
4678
; CHECK: attributes #[[ATTR0:[0-9]+]] = { sanitize_type }
4779
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
4880
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
4981
;.
82+
; CHECK-INLINE: attributes #[[ATTR0:[0-9]+]] = { sanitize_type }
83+
; CHECK-INLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind }
84+
; CHECK-INLINE: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
85+
;.
86+
; CHECK-OUTLINE: attributes #[[ATTR0:[0-9]+]] = { sanitize_type }
87+
; CHECK-OUTLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind }
88+
;.

0 commit comments

Comments
 (0)