From 95c5ff34c043680cbf85d7baf3e73ef7680e5854 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Fri, 31 Oct 2025 21:02:34 +0000 Subject: [PATCH 1/9] [TySan][Clang] Add clang flag to use tysan outlined instrumentation and update docs --- clang/docs/TypeSanitizer.rst | 27 ++++++++++++++++--- clang/docs/UsersManual.rst | 9 +++++++ clang/include/clang/Driver/SanitizerArgs.h | 2 ++ clang/include/clang/Options/Options.td | 12 +++++++++ clang/lib/Driver/SanitizerArgs.cpp | 20 ++++++++++++++ clang/test/CodeGen/sanitize-type-outlined.cpp | 23 ++++++++++++++++ 6 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/sanitize-type-outlined.cpp diff --git a/clang/docs/TypeSanitizer.rst b/clang/docs/TypeSanitizer.rst index 3c683a6c24bb4..6420d9e1d0ebd 100644 --- a/clang/docs/TypeSanitizer.rst +++ b/clang/docs/TypeSanitizer.rst @@ -20,9 +20,13 @@ code is build with ``-fno-strict-aliasing``, sacrificing performance. TypeSanitizer is built to catch when these strict aliasing rules have been violated, helping users find where such bugs originate in their code despite the code looking valid at first glance. -As TypeSanitizer is still experimental, it can currently have a large impact on runtime speed, -memory use, and code size. It also has a large compile-time overhead. Work is being done to -reduce these impacts. +Typical memory overhead introduced by TypeSanitizer is about **8x**. Runtime slowdown varies greatly +depending on how often the instrumented code relies on type aliasing. In the best case slowdown is +**2x-3x**. + +The compiler instrumentation also has an impact on code size and compilation overhead. There is an +experimental :ref:`instrumentation outlining option` which can greatly reduce this +but this may decrease runtime performance. The TypeSanitizer Algorithm =========================== @@ -128,6 +132,23 @@ references to LLVM IR specific terms. Sanitizer features ================== +.. _outlining_flag: + +Instrumentation code outlining +------------------------------ + +By default TypeSanitizer inlines the instrumentation code. This leads to increased +binary size and compilation time. Using the clang flag +``-fsanitize-type-outline-instrumentation`` (default: ``false``) +forces all code instrumentation to be outlined. This reduces the size of the +generated code and reduces compile-time overhead, but it also reduces runtime +performance. + +This outlined instrumentation is new. If you wish to verify that the outlined instrumentation +is behaving in the same way as the inline instrumentation, you can force TypeSanitizer +to use both types of instrumentation. You can use the clang flag +``-fsanitize-type-verify-outlined-instrumentation`` (default: ``false``) to do this. + ``__has_feature(type_sanitizer)`` ------------------------------------ diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index fb22ad3c90af4..04da152bd0aff 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2277,6 +2277,15 @@ are listed below. See :doc: `AddressSanitizer` for more details. +.. option:: -f[no-]sanitize-type-outline-instrumentation + + Controls how type sanitizer code is generated. If enabled will always use + a function call instead of inlining the code. Turning this option on may + reduce the binary size and compilation overhead, but might result in a worse + run-time performance. + + See :doc: `TypeSanitizer` for more details. + .. option:: -f[no-]sanitize-stats Enable simple statistics gathering for the enabled sanitizers. diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index eea7897e96afd..29569bcf7fa25 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -67,6 +67,8 @@ class SanitizerArgs { bool TsanFuncEntryExit = true; bool TsanAtomics = true; bool MinimalRuntime = false; + bool TysanOutlineInstrumentation = false; + bool TysanVerifyOutlinedInstrumentation = false; // True if cross-dso CFI support if provided by the system (i.e. Android). bool ImplicitCfiRuntime = false; bool NeedsMemProfRt = false; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 2f7434d8afe11..1890f46ec5893 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2459,6 +2459,18 @@ def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-o def fno_sanitize_address_outline_instrumentation : Flag<["-"], "fno-sanitize-address-outline-instrumentation">, Group, HelpText<"Use default code inlining logic for the address sanitizer">; +def fsanitize_type_outline_instrumentation : Flag<["-"], "fsanitize-type-outline-instrumentation">, + Group, + HelpText<"Always generate function calls for type sanitizer instrumentation">; +def fno_sanitize_type_outline_instrumentation : Flag<["-"], "fno-sanitize-type-outline-instrumentation">, + Group, + HelpText<"Use default code inlining logic for the type sanitizer">; +def fsanitize_type_verify_outlined_instrumentation : Flag<["-"], "fsanitize_type_verify_outlined_instrumentation">, + Group, + HelpText<"Use both inlined and outlined instrumentation for type sanitizer to verify equivilence">; +def fno_sanitize_type_verify_outlined_instrumentation : Flag<["-"], "fno_sanitize_type_verify_outlined_instrumentation">, + Group, + HelpText<"Don't use both inlined and outlined instrumentation for type sanitizer to verify equivilence">; defm sanitize_stable_abi : OptInCC1FFlag<"sanitize-stable-abi", "Stable ", "Conventional ", "ABI instrumentation for sanitizer runtime. Default: Conventional">; diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 420c4cddbc8dd..efd050373b991 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1176,6 +1176,17 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, options::OPT_fno_sanitize_alloc_token_extended, AllocTokenExtended); } + if (AllAddedKinds & SanitizerKind::Type) { + TysanOutlineInstrumentation = + Args.hasFlag(options::OPT_fsanitize_type_outline_instrumentation, + options::OPT_fno_sanitize_type_outline_instrumentation, + TysanOutlineInstrumentation); + TysanVerifyOutlinedInstrumentation = Args.hasFlag( + options::OPT_fsanitize_type_verify_outlined_instrumentation, + options::OPT_fno_sanitize_type_verify_outlined_instrumentation, + TysanVerifyOutlinedInstrumentation); + } + LinkRuntimes = Args.hasFlag(options::OPT_fsanitize_link_runtime, options::OPT_fno_sanitize_link_runtime, !Args.hasArg(options::OPT_r)); @@ -1500,6 +1511,15 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0"); } + if (TysanOutlineInstrumentation || TysanVerifyOutlinedInstrumentation) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tysan-outline-instrumentation"); + } + if (TysanVerifyOutlinedInstrumentation) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tysan-verify-outlined-instrumentation"); + } + // When emitting Stable ABI instrumentation, force outlining calls and avoid // inlining shadow memory poisoning. While this is a big performance burden // for now it allows full abstraction from implementation details. diff --git a/clang/test/CodeGen/sanitize-type-outlined.cpp b/clang/test/CodeGen/sanitize-type-outlined.cpp new file mode 100644 index 0000000000000..3c22f15c93d94 --- /dev/null +++ b/clang/test/CodeGen/sanitize-type-outlined.cpp @@ -0,0 +1,23 @@ +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: -fsanitize-type-outline-instrumentation \ +// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE + +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: -fsanitize-type-outline-instrumentation \ +// RUN: -fsanitize-type-verify-outlined-instrumentation \ +// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE-VERIFY +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: -fsanitize-type-verify-outlined-instrumentation \ +// RUN: | FileCheck %s --check-prefixes=CHECK-VERIFY + +// CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-OUTLINE: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-OUTLINE-VERIFY: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-VERIFY: call{{.*}}@__tysan_instrument_mem_inst + +float alias(int *ptr){ + float *aliasedPtr = (float *)ptr; + return *aliasedPtr; +} From d9dc8be807a7fd79f085ceb2e650ef0d8b30f333 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Mon, 3 Nov 2025 15:06:23 +0000 Subject: [PATCH 2/9] Fix typo in Option.td --- clang/include/clang/Options/Options.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 1890f46ec5893..893ebe918f7cd 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2465,10 +2465,10 @@ def fsanitize_type_outline_instrumentation : Flag<["-"], "fsanitize-type-outline def fno_sanitize_type_outline_instrumentation : Flag<["-"], "fno-sanitize-type-outline-instrumentation">, Group, HelpText<"Use default code inlining logic for the type sanitizer">; -def fsanitize_type_verify_outlined_instrumentation : Flag<["-"], "fsanitize_type_verify_outlined_instrumentation">, +def fsanitize_type_verify_outlined_instrumentation : Flag<["-"], "fsanitize-type-verify-outlined-instrumentation">, Group, HelpText<"Use both inlined and outlined instrumentation for type sanitizer to verify equivilence">; -def fno_sanitize_type_verify_outlined_instrumentation : Flag<["-"], "fno_sanitize_type_verify_outlined_instrumentation">, +def fno_sanitize_type_verify_outlined_instrumentation : Flag<["-"], "fno_sanitize-type-verify-outlined-instrumentation">, Group, HelpText<"Don't use both inlined and outlined instrumentation for type sanitizer to verify equivilence">; defm sanitize_stable_abi From 9ff2fb9ae3b11521f67eea963a690195b76a0b05 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Mon, 3 Nov 2025 15:33:54 +0000 Subject: [PATCH 3/9] Windows doesnt support tysan so unsupport in the test --- clang/test/CodeGen/sanitize-type-outlined.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/CodeGen/sanitize-type-outlined.cpp b/clang/test/CodeGen/sanitize-type-outlined.cpp index 3c22f15c93d94..de21b903621fc 100644 --- a/clang/test/CodeGen/sanitize-type-outlined.cpp +++ b/clang/test/CodeGen/sanitize-type-outlined.cpp @@ -1,3 +1,5 @@ +// UNSUPPORTED: target={{.*}}-windows-{{.*}} + // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ // RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ From 709c21812cad47621106beac5085b467e88d0925 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Thu, 13 Nov 2025 13:54:30 +0000 Subject: [PATCH 4/9] Switch outlining to default, remove verification focused flag changes --- clang/docs/TypeSanitizer.rst | 5 ----- clang/include/clang/Driver/SanitizerArgs.h | 1 - clang/include/clang/Options/Options.td | 6 ------ clang/lib/Driver/SanitizerArgs.cpp | 10 +--------- clang/test/CodeGen/sanitize-type-outlined.cpp | 10 ---------- llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp | 2 +- 6 files changed, 2 insertions(+), 32 deletions(-) diff --git a/clang/docs/TypeSanitizer.rst b/clang/docs/TypeSanitizer.rst index 6420d9e1d0ebd..07af5d6f605b4 100644 --- a/clang/docs/TypeSanitizer.rst +++ b/clang/docs/TypeSanitizer.rst @@ -144,11 +144,6 @@ forces all code instrumentation to be outlined. This reduces the size of the generated code and reduces compile-time overhead, but it also reduces runtime performance. -This outlined instrumentation is new. If you wish to verify that the outlined instrumentation -is behaving in the same way as the inline instrumentation, you can force TypeSanitizer -to use both types of instrumentation. You can use the clang flag -``-fsanitize-type-verify-outlined-instrumentation`` (default: ``false``) to do this. - ``__has_feature(type_sanitizer)`` ------------------------------------ diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 29569bcf7fa25..4803ddecc6b9d 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -68,7 +68,6 @@ class SanitizerArgs { bool TsanAtomics = true; bool MinimalRuntime = false; bool TysanOutlineInstrumentation = false; - bool TysanVerifyOutlinedInstrumentation = false; // True if cross-dso CFI support if provided by the system (i.e. Android). bool ImplicitCfiRuntime = false; bool NeedsMemProfRt = false; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 893ebe918f7cd..c8cfee88e94a9 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2465,12 +2465,6 @@ def fsanitize_type_outline_instrumentation : Flag<["-"], "fsanitize-type-outline def fno_sanitize_type_outline_instrumentation : Flag<["-"], "fno-sanitize-type-outline-instrumentation">, Group, HelpText<"Use default code inlining logic for the type sanitizer">; -def fsanitize_type_verify_outlined_instrumentation : Flag<["-"], "fsanitize-type-verify-outlined-instrumentation">, - Group, - HelpText<"Use both inlined and outlined instrumentation for type sanitizer to verify equivilence">; -def fno_sanitize_type_verify_outlined_instrumentation : Flag<["-"], "fno_sanitize-type-verify-outlined-instrumentation">, - Group, - HelpText<"Don't use both inlined and outlined instrumentation for type sanitizer to verify equivilence">; defm sanitize_stable_abi : OptInCC1FFlag<"sanitize-stable-abi", "Stable ", "Conventional ", "ABI instrumentation for sanitizer runtime. Default: Conventional">; diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index efd050373b991..42acc0c6c64ec 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1181,10 +1181,6 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Args.hasFlag(options::OPT_fsanitize_type_outline_instrumentation, options::OPT_fno_sanitize_type_outline_instrumentation, TysanOutlineInstrumentation); - TysanVerifyOutlinedInstrumentation = Args.hasFlag( - options::OPT_fsanitize_type_verify_outlined_instrumentation, - options::OPT_fno_sanitize_type_verify_outlined_instrumentation, - TysanVerifyOutlinedInstrumentation); } LinkRuntimes = Args.hasFlag(options::OPT_fsanitize_link_runtime, @@ -1511,14 +1507,10 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0"); } - if (TysanOutlineInstrumentation || TysanVerifyOutlinedInstrumentation) { + if (TysanOutlineInstrumentation) { CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-tysan-outline-instrumentation"); } - if (TysanVerifyOutlinedInstrumentation) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-tysan-verify-outlined-instrumentation"); - } // When emitting Stable ABI instrumentation, force outlining calls and avoid // inlining shadow memory poisoning. While this is a big performance burden diff --git a/clang/test/CodeGen/sanitize-type-outlined.cpp b/clang/test/CodeGen/sanitize-type-outlined.cpp index de21b903621fc..57b66fb626f51 100644 --- a/clang/test/CodeGen/sanitize-type-outlined.cpp +++ b/clang/test/CodeGen/sanitize-type-outlined.cpp @@ -6,18 +6,8 @@ // RUN: -fsanitize-type-outline-instrumentation \ // RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE -// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ -// RUN: -fsanitize-type-outline-instrumentation \ -// RUN: -fsanitize-type-verify-outlined-instrumentation \ -// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE-VERIFY -// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ -// RUN: -fsanitize-type-verify-outlined-instrumentation \ -// RUN: | FileCheck %s --check-prefixes=CHECK-VERIFY - // CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_mem_inst // CHECK-OUTLINE: call{{.*}}@__tysan_instrument_mem_inst -// CHECK-OUTLINE-VERIFY: call{{.*}}@__tysan_instrument_mem_inst -// CHECK-VERIFY: call{{.*}}@__tysan_instrument_mem_inst float alias(int *ptr){ float *aliasedPtr = (float *)ptr; diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp index 87eba5f2c5242..1c91d833ea616 100644 --- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp @@ -62,7 +62,7 @@ static cl::opt ClOutlineInstrumentation( "tysan-outline-instrumentation", cl::desc("Uses function calls for all TySan instrumentation, reducing " "ELF size"), - cl::Hidden, cl::init(false)); + cl::Hidden, cl::init(true)); static cl::opt ClVerifyOutlinedInstrumentation( "tysan-verify-outlined-instrumentation", From 2edb5d37a8394d820c42ff3ae35ba703073b1951 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Thu, 13 Nov 2025 14:05:47 +0000 Subject: [PATCH 5/9] Update docs --- clang/docs/TypeSanitizer.rst | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/clang/docs/TypeSanitizer.rst b/clang/docs/TypeSanitizer.rst index 07af5d6f605b4..fefa22954607a 100644 --- a/clang/docs/TypeSanitizer.rst +++ b/clang/docs/TypeSanitizer.rst @@ -24,10 +24,6 @@ Typical memory overhead introduced by TypeSanitizer is about **8x**. Runtime slo depending on how often the instrumented code relies on type aliasing. In the best case slowdown is **2x-3x**. -The compiler instrumentation also has an impact on code size and compilation overhead. There is an -experimental :ref:`instrumentation outlining option` which can greatly reduce this -but this may decrease runtime performance. - The TypeSanitizer Algorithm =========================== For each TBAA type-access descriptor, encoded in LLVM IR using TBAA Metadata, the instrumentation @@ -132,17 +128,13 @@ references to LLVM IR specific terms. Sanitizer features ================== -.. _outlining_flag: - -Instrumentation code outlining +Instrumentation code inlining ------------------------------ -By default TypeSanitizer inlines the instrumentation code. This leads to increased -binary size and compilation time. Using the clang flag -``-fsanitize-type-outline-instrumentation`` (default: ``false``) -forces all code instrumentation to be outlined. This reduces the size of the -generated code and reduces compile-time overhead, but it also reduces runtime -performance. +By default TypeSanitizer inserts instrumentation through function calls. This may lead to a reduction in +runtime performance. ``-fno-sanitize-type-outline-instrumentation`` (default: ``false``) forces all +code instrumentation to be inlined. This will increase the size of the generated code and compiler +overhead, but may improve the runtime performance of the resulting code. ``__has_feature(type_sanitizer)`` ------------------------------------ From 384c35f7fccdb90fa08a8450202c2e836fa091b7 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Fri, 14 Nov 2025 11:03:31 +0000 Subject: [PATCH 6/9] Fixup tests --- clang/test/CodeGen/sanitize-type-outlined.cpp | 7 +- .../TypeSanitizer/access-with-offset.ll | 70 +++- .../TypeSanitizer/alloca-only.ll | 45 ++- .../Instrumentation/TypeSanitizer/alloca.ll | 133 +++++++- .../Instrumentation/TypeSanitizer/anon.ll | 320 +++++++++++++++++- .../TypeSanitizer/basic-nosan.ll | 137 +++++++- .../Instrumentation/TypeSanitizer/basic.ll | 235 ++++++++++++- .../TypeSanitizer/basic_outlined.ll | 68 ---- .../Instrumentation/TypeSanitizer/byval.ll | 121 ++++++- .../Instrumentation/TypeSanitizer/globals.ll | 100 +++++- .../TypeSanitizer/globals_outlined.ll | 24 -- .../TypeSanitizer/invalid-metadata.ll | 60 +++- .../TypeSanitizer/memintrinsics.ll | 76 ++++- .../TypeSanitizer/nosanitize.ll | 42 ++- .../TypeSanitizer/sanitize-no-tbaa.ll | 181 +++++++++- .../TypeSanitizer/swifterror.ll | 19 +- 16 files changed, 1482 insertions(+), 156 deletions(-) delete mode 100644 llvm/test/Instrumentation/TypeSanitizer/basic_outlined.ll delete mode 100644 llvm/test/Instrumentation/TypeSanitizer/globals_outlined.ll diff --git a/clang/test/CodeGen/sanitize-type-outlined.cpp b/clang/test/CodeGen/sanitize-type-outlined.cpp index 57b66fb626f51..770327aa19921 100644 --- a/clang/test/CodeGen/sanitize-type-outlined.cpp +++ b/clang/test/CodeGen/sanitize-type-outlined.cpp @@ -1,13 +1,14 @@ // UNSUPPORTED: target={{.*}}-windows-{{.*}} -// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ -// RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ // RUN: -fsanitize-type-outline-instrumentation \ // RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: -fno-sanitize-type-outline-instrumentation \ +// RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE -// CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_mem_inst // CHECK-OUTLINE: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_mem_inst float alias(int *ptr){ float *aliasedPtr = (float *)ptr; diff --git a/llvm/test/Instrumentation/TypeSanitizer/access-with-offset.ll b/llvm/test/Instrumentation/TypeSanitizer/access-with-offset.ll index 84e0f7307c7ec..3adb0f5119a91 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/access-with-offset.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/access-with-offset.ll @@ -1,7 +1,8 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6 -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 + +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE -;. ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ; 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 ; 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 @@ -10,7 +11,6 @@ ; CHECK: @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" ; CHECK: @__tysan_shadow_memory_address = external global i64 ; CHECK: @__tysan_app_memory_mask = external global i64 -;. define ptr @test_load_offset(ptr %argv) { ; CHECK-LABEL: define ptr @test_load_offset( ; CHECK-SAME: ptr [[ARGV:%.*]]) { @@ -52,6 +52,55 @@ define ptr @test_load_offset(ptr %argv) { ; CHECK-NEXT: [[L:%.*]] = load ptr, ptr null, align 8, !tbaa [[ANYPTR_TBAA1:![0-9]+]] ; CHECK-NEXT: ret ptr [[L]] ; +; CHECK-INLINE-LABEL: define ptr @test_load_offset( +; CHECK-INLINE-SAME: ptr [[ARGV:%.*]]) { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 0, [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[DESC_SET:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[DESC_SET]], label %[[SET_TYPE:.*]], label %[[BB0:.*]], !prof [[PROF0:![0-9]+]] +; CHECK-INLINE: [[SET_TYPE]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_any_20pointer_o_0, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_4_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 32 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_4_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_4_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -4 to ptr), ptr [[SHADOW_BYTE_4_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_5_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 40 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_5_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_5_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -5 to ptr), ptr [[SHADOW_BYTE_5_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_6_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 48 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_6_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_6_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -6 to ptr), ptr [[SHADOW_BYTE_6_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_7_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 56 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_7_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_7_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -7 to ptr), ptr [[SHADOW_BYTE_7_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB0]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: [[L:%.*]] = load ptr, ptr null, align 8, !tbaa [[ANYPTR_TBAA1:![0-9]+]] +; CHECK-INLINE-NEXT: ret ptr [[L]] +; +; CHECK-OUTLINE-LABEL: define ptr @test_load_offset( +; CHECK-OUTLINE-SAME: ptr [[ARGV:%.*]]) { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4 +; 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) +; CHECK-OUTLINE-NEXT: [[L:%.*]] = load ptr, ptr null, align 8, !tbaa [[ANYPTR_TBAA0:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret ptr [[L]] +; entry: %l = load ptr, ptr null, align 8, !tbaa !0 ret ptr %l @@ -61,12 +110,21 @@ entry: !1 = !{!"any pointer", !2, i64 0} !2 = !{!"omnipotent char", !3, i64 0} !3 = !{!"Simple C/C++ TBAA"} -;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind } -;. ; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} ; CHECK: [[ANYPTR_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0} ; CHECK: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0} ; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} ; CHECK: [[META4]] = !{!"Simple C/C++ TBAA"} ;. +; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} +; CHECK-INLINE: [[ANYPTR_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0} +; CHECK-INLINE: [[META2]] = !{!"any pointer", [[META3:![0-9]+]], i64 0} +; CHECK-INLINE: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} +; CHECK-INLINE: [[META4]] = !{!"Simple C/C++ TBAA"} +;. +; CHECK-OUTLINE: [[ANYPTR_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} +; CHECK-OUTLINE: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"Simple C/C++ TBAA"} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/alloca-only.ll b/llvm/test/Instrumentation/TypeSanitizer/alloca-only.ll index 117cd1a3d4100..1c492a77e630e 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/alloca-only.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/alloca-only.ll @@ -1,16 +1,26 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -;. ; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ; CHECK: @__tysan_shadow_memory_address = external global i64 ; CHECK: @__tysan_app_memory_mask = external global i64 ;. +; CHECK-INLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +;. +; CHECK-OUTLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +;. define void @test_alloca_only() sanitize_type { ; CHECK-LABEL: @test_alloca_only( ; CHECK-NEXT: entry: @@ -26,6 +36,29 @@ define void @test_alloca_only() sanitize_type { ; CHECK-NEXT: call void @foo(ptr [[TMP1]]) ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: @test_alloca_only( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 32, i1 false) +; CHECK-INLINE-NEXT: call void @foo(ptr [[A]]) +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_alloca_only( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[A]], ptr null, i64 4, i1 false) +; CHECK-OUTLINE-NEXT: call void @foo(ptr [[A]]) +; CHECK-OUTLINE-NEXT: ret void +; entry: %a = alloca i32 call void @foo(ptr %a) @@ -42,8 +75,14 @@ declare void @foo(ptr) !4 = !{!"_ZTS1x", !2, i64 0, !2, i64 4} !5 = !{!"_ZTS1v", !2, i64 8, !2, i64 12, !4, i64 16} !6 = !{!5, !2, i64 12} -;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind } ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ;. +; CHECK-INLINE: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } +; CHECK-INLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +; CHECK-INLINE: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +;. +; CHECK-OUTLINE: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } +; CHECK-OUTLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/alloca.ll b/llvm/test/Instrumentation/TypeSanitizer/alloca.ll index deddecfc19d81..13d08e58ed094 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/alloca.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/alloca.ll @@ -1,7 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -22,6 +23,29 @@ define void @alloca_test() sanitize_type { ; CHECK-NEXT: call void @alloca_test_use(ptr [[X]]) ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: @alloca_test( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[X:%.*]] = alloca [10 x i8], align 1 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 80, i1 false) +; CHECK-INLINE-NEXT: call void @alloca_test_use(ptr [[X]]) +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @alloca_test( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: [[X:%.*]] = alloca [10 x i8], align 1 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 10, i1 false) +; CHECK-OUTLINE-NEXT: call void @alloca_test_use(ptr [[X]]) +; CHECK-OUTLINE-NEXT: ret void +; entry: %x = alloca [10 x i8], align 1 call void @alloca_test_use(ptr %x) @@ -61,6 +85,55 @@ define void @alloca_lifetime_test(i1 %c) sanitize_type { ; CHECK: exit: ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: @alloca_lifetime_test( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[X:%.*]] = alloca [10 x i8], align 1 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 80, i1 false) +; CHECK-INLINE-NEXT: br label [[LOOP:%.*]] +; CHECK-INLINE: loop: +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = shl i64 [[TMP6]], 3 +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP9]], i8 0, i64 80, i1 false) +; CHECK-INLINE-NEXT: call void @llvm.lifetime.start.p0(ptr [[X]]) +; CHECK-INLINE-NEXT: call void @alloca_test_use(ptr [[X]]) +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = and i64 [[TMP10]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = shl i64 [[TMP11]], 3 +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[TMP12]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP14]], i8 0, i64 80, i1 false) +; CHECK-INLINE-NEXT: call void @llvm.lifetime.end.p0(ptr [[X]]) +; CHECK-INLINE-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK-INLINE: exit: +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @alloca_lifetime_test( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: [[X:%.*]] = alloca [10 x i8], align 1 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 10, i1 false) +; CHECK-OUTLINE-NEXT: br label [[LOOP:%.*]] +; CHECK-OUTLINE: loop: +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 10, i1 false) +; CHECK-OUTLINE-NEXT: call void @llvm.lifetime.start.p0(ptr [[X]]) +; CHECK-OUTLINE-NEXT: call void @alloca_test_use(ptr [[X]]) +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 10, i1 false) +; CHECK-OUTLINE-NEXT: call void @llvm.lifetime.end.p0(ptr [[X]]) +; CHECK-OUTLINE-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK-OUTLINE: exit: +; CHECK-OUTLINE-NEXT: ret void +; entry: %x = alloca [10 x i8], align 1 br label %loop @@ -114,6 +187,64 @@ define void @dynamic_alloca_lifetime_test(i1 %c, i64 %n) sanitize_type { ; CHECK: exit: ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: @dynamic_alloca_lifetime_test( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[X:%.*]] = alloca i32, i64 [[N:%.*]], align 1 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = mul i64 [[N]], 4 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 3 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = add i64 [[TMP3]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = shl i64 [[TMP0]], 3 +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP5]], i8 0, i64 [[TMP6]], i1 false) +; CHECK-INLINE-NEXT: br label [[LOOP:%.*]] +; CHECK-INLINE: loop: +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = mul i64 [[N]], 4 +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = shl i64 [[TMP9]], 3 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = add i64 [[TMP10]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to ptr +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = shl i64 [[TMP7]], 3 +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP12]], i8 0, i64 [[TMP13]], i1 false) +; CHECK-INLINE-NEXT: call void @llvm.lifetime.start.p0(ptr [[X]]) +; CHECK-INLINE-NEXT: call void @alloca_test_use(ptr [[X]]) +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = mul i64 [[N]], 4 +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = ptrtoint ptr [[X]] to i64 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = and i64 [[TMP15]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = shl i64 [[TMP16]], 3 +; CHECK-INLINE-NEXT: [[TMP18:%.*]] = add i64 [[TMP17]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP19:%.*]] = inttoptr i64 [[TMP18]] to ptr +; CHECK-INLINE-NEXT: [[TMP20:%.*]] = shl i64 [[TMP14]], 3 +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP19]], i8 0, i64 [[TMP20]], i1 false) +; CHECK-INLINE-NEXT: call void @llvm.lifetime.end.p0(ptr [[X]]) +; CHECK-INLINE-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK-INLINE: exit: +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @dynamic_alloca_lifetime_test( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: [[X:%.*]] = alloca i32, i64 [[N:%.*]], align 1 +; CHECK-OUTLINE-NEXT: [[TMP0:%.*]] = mul i64 [[N]], 4 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 [[TMP0]], i1 false) +; CHECK-OUTLINE-NEXT: br label [[LOOP:%.*]] +; CHECK-OUTLINE: loop: +; CHECK-OUTLINE-NEXT: [[TMP1:%.*]] = mul i64 [[N]], 4 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 [[TMP1]], i1 false) +; CHECK-OUTLINE-NEXT: call void @llvm.lifetime.start.p0(ptr [[X]]) +; CHECK-OUTLINE-NEXT: call void @alloca_test_use(ptr [[X]]) +; CHECK-OUTLINE-NEXT: [[TMP2:%.*]] = mul i64 [[N]], 4 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 [[TMP2]], i1 false) +; CHECK-OUTLINE-NEXT: call void @llvm.lifetime.end.p0(ptr [[X]]) +; CHECK-OUTLINE-NEXT: br i1 [[C:%.*]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK-OUTLINE: exit: +; CHECK-OUTLINE-NEXT: ret void +; entry: %x = alloca i32, i64 %n, align 1 br label %loop diff --git a/llvm/test/Instrumentation/TypeSanitizer/anon.ll b/llvm/test/Instrumentation/TypeSanitizer/anon.ll index 1f0f1bd7ace15..7018d4b7fe2a0 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/anon.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/anon.ll @@ -1,13 +1,13 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6 ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -;. ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ; CHECK: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat ; CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat @@ -22,6 +22,34 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK: @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95, ptr @__tysan_v1_int, i64 24 }, comdat ; CHECK: @llvm.used = appending global [6 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24], section "llvm.metadata" ;. +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-INLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-INLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-INLINE: @__tysan_v1___ZTSN12__GLOBAL____N__11zE = internal constant { i64, i64, ptr, i64, [23 x i8] } { i64 2, i64 1, ptr @__tysan_v1_int, i64 24, [23 x i8] c"_ZTSN12_GLOBAL__N_11zE\00" } +; CHECK-INLINE: @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24 = internal constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE, ptr @__tysan_v1_int, i64 24 } +; CHECK-INLINE: @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE = internal constant { i64, i64, ptr, i64, [27 x i8] } { i64 2, i64 1, ptr @__tysan_v1_int, i64 24, [27 x i8] c"_ZTS1yIN12_GLOBAL__N_11zEE\00" } +; CHECK-INLINE: @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24 = internal constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE, ptr @__tysan_v1_int, i64 24 } +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-INLINE: @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95 = linkonce_odr constant { i64, i64, ptr, i64, [1 x i8] } { i64 2, i64 1, ptr @__tysan_v1_int, i64 24, [1 x i8] zeroinitializer }, comdat +; CHECK-INLINE: @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95, ptr @__tysan_v1_int, i64 24 }, comdat +; CHECK-INLINE: @llvm.used = appending global [6 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24], section "llvm.metadata" +;. +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-OUTLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1___ZTSN12__GLOBAL____N__11zE = internal constant { i64, i64, ptr, i64, [23 x i8] } { i64 2, i64 1, ptr @__tysan_v1_int, i64 24, [23 x i8] c"_ZTSN12_GLOBAL__N_11zE\00" } +; CHECK-OUTLINE: @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24 = internal constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE, ptr @__tysan_v1_int, i64 24 } +; CHECK-OUTLINE: @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE = internal constant { i64, i64, ptr, i64, [27 x i8] } { i64 2, i64 1, ptr @__tysan_v1_int, i64 24, [27 x i8] c"_ZTS1yIN12_GLOBAL__N_11zEE\00" } +; CHECK-OUTLINE: @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24 = internal constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE, ptr @__tysan_v1_int, i64 24 } +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-OUTLINE: @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95 = linkonce_odr constant { i64, i64, ptr, i64, [1 x i8] } { i64 2, i64 1, ptr @__tysan_v1_int, i64 24, [1 x i8] zeroinitializer }, comdat +; CHECK-OUTLINE: @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95, ptr @__tysan_v1_int, i64 24 }, comdat +; CHECK-OUTLINE: @llvm.used = appending global [6 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24], section "llvm.metadata" +;. define void @test_anon_ns(ptr %a, ptr %b) sanitize_type { ; CHECK-LABEL: define void @test_anon_ns( ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) #[[ATTR0:[0-9]+]] { @@ -180,6 +208,174 @@ define void @test_anon_ns(ptr %a, ptr %b) sanitize_type { ; CHECK-NEXT: store i32 43, ptr [[B]], align 4, !tbaa [[INT_TBAA6:![0-9]+]] ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: define void @test_anon_ns( +; CHECK-INLINE-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24 +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC]], label %[[BB0:.*]], label %[[BB22:.*]], !prof [[PROF0:![0-9]+]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB20:.*]] +; CHECK-INLINE: [[BB2]]: +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]] +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]] +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]] +; CHECK-INLINE-NEXT: br i1 [[TMP17]], label %[[BB18:.*]], label %[[BB19:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB18]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB19]] +; CHECK-INLINE: [[BB19]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB21:.*]] +; CHECK-INLINE: [[BB20]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB21]] +; CHECK-INLINE: [[BB21]]: +; CHECK-INLINE-NEXT: br label %[[BB43:.*]] +; CHECK-INLINE: [[BB22]]: +; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr +; CHECK-INLINE-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8 +; CHECK-INLINE-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64 +; CHECK-INLINE-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0 +; CHECK-INLINE-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]] +; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr +; CHECK-INLINE-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8 +; CHECK-INLINE-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64 +; CHECK-INLINE-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0 +; CHECK-INLINE-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]] +; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr +; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8 +; CHECK-INLINE-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64 +; CHECK-INLINE-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0 +; CHECK-INLINE-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]] +; CHECK-INLINE-NEXT: br i1 [[TMP40]], label %[[BB41:.*]], label %[[BB42:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB41]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB42]] +; CHECK-INLINE: [[BB42]]: +; CHECK-INLINE-NEXT: br label %[[BB43]] +; CHECK-INLINE: [[BB43]]: +; CHECK-INLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] +; CHECK-INLINE-NEXT: [[APP_PTR_INT1:%.*]] = ptrtoint ptr [[B]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED2:%.*]] = and i64 [[APP_PTR_INT1]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED3:%.*]] = shl i64 [[APP_PTR_MASKED2]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT4:%.*]] = add i64 [[APP_PTR_SHIFTED3]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR5:%.*]] = inttoptr i64 [[SHADOW_PTR_INT4]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC6:%.*]] = load ptr, ptr [[SHADOW_PTR5]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC7:%.*]] = icmp ne ptr [[SHADOW_DESC6]], @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24 +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC7]], label %[[BB44:.*]], label %[[BB66:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB44]]: +; CHECK-INLINE-NEXT: [[TMP45:%.*]] = icmp eq ptr [[SHADOW_DESC6]], null +; CHECK-INLINE-NEXT: br i1 [[TMP45]], label %[[BB46:.*]], label %[[BB64:.*]] +; CHECK-INLINE: [[BB46]]: +; CHECK-INLINE-NEXT: [[TMP47:%.*]] = add i64 [[SHADOW_PTR_INT4]], 8 +; CHECK-INLINE-NEXT: [[TMP48:%.*]] = inttoptr i64 [[TMP47]] to ptr +; CHECK-INLINE-NEXT: [[TMP49:%.*]] = load ptr, ptr [[TMP48]], align 8 +; CHECK-INLINE-NEXT: [[TMP50:%.*]] = icmp ne ptr [[TMP49]], null +; CHECK-INLINE-NEXT: [[TMP51:%.*]] = or i1 false, [[TMP50]] +; CHECK-INLINE-NEXT: [[TMP52:%.*]] = add i64 [[SHADOW_PTR_INT4]], 16 +; CHECK-INLINE-NEXT: [[TMP53:%.*]] = inttoptr i64 [[TMP52]] to ptr +; CHECK-INLINE-NEXT: [[TMP54:%.*]] = load ptr, ptr [[TMP53]], align 8 +; CHECK-INLINE-NEXT: [[TMP55:%.*]] = icmp ne ptr [[TMP54]], null +; CHECK-INLINE-NEXT: [[TMP56:%.*]] = or i1 [[TMP51]], [[TMP55]] +; CHECK-INLINE-NEXT: [[TMP57:%.*]] = add i64 [[SHADOW_PTR_INT4]], 24 +; CHECK-INLINE-NEXT: [[TMP58:%.*]] = inttoptr i64 [[TMP57]] to ptr +; CHECK-INLINE-NEXT: [[TMP59:%.*]] = load ptr, ptr [[TMP58]], align 8 +; CHECK-INLINE-NEXT: [[TMP60:%.*]] = icmp ne ptr [[TMP59]], null +; CHECK-INLINE-NEXT: [[TMP61:%.*]] = or i1 [[TMP56]], [[TMP60]] +; CHECK-INLINE-NEXT: br i1 [[TMP61]], label %[[BB62:.*]], label %[[BB63:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB62]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[B]], i32 4, ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB63]] +; CHECK-INLINE: [[BB63]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24, ptr [[SHADOW_PTR5]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET8:%.*]] = add i64 [[SHADOW_PTR_INT4]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR9:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET8]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR9]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET10:%.*]] = add i64 [[SHADOW_PTR_INT4]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR11:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET10]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR11]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET12:%.*]] = add i64 [[SHADOW_PTR_INT4]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR13:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET12]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR13]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB65:.*]] +; CHECK-INLINE: [[BB64]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[B]], i32 4, ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB65]] +; CHECK-INLINE: [[BB65]]: +; CHECK-INLINE-NEXT: br label %[[BB87:.*]] +; CHECK-INLINE: [[BB66]]: +; CHECK-INLINE-NEXT: [[TMP67:%.*]] = add i64 [[SHADOW_PTR_INT4]], 8 +; CHECK-INLINE-NEXT: [[TMP68:%.*]] = inttoptr i64 [[TMP67]] to ptr +; CHECK-INLINE-NEXT: [[TMP69:%.*]] = load ptr, ptr [[TMP68]], align 8 +; CHECK-INLINE-NEXT: [[TMP70:%.*]] = ptrtoint ptr [[TMP69]] to i64 +; CHECK-INLINE-NEXT: [[TMP71:%.*]] = icmp sge i64 [[TMP70]], 0 +; CHECK-INLINE-NEXT: [[TMP72:%.*]] = or i1 false, [[TMP71]] +; CHECK-INLINE-NEXT: [[TMP73:%.*]] = add i64 [[SHADOW_PTR_INT4]], 16 +; CHECK-INLINE-NEXT: [[TMP74:%.*]] = inttoptr i64 [[TMP73]] to ptr +; CHECK-INLINE-NEXT: [[TMP75:%.*]] = load ptr, ptr [[TMP74]], align 8 +; CHECK-INLINE-NEXT: [[TMP76:%.*]] = ptrtoint ptr [[TMP75]] to i64 +; CHECK-INLINE-NEXT: [[TMP77:%.*]] = icmp sge i64 [[TMP76]], 0 +; CHECK-INLINE-NEXT: [[TMP78:%.*]] = or i1 [[TMP72]], [[TMP77]] +; CHECK-INLINE-NEXT: [[TMP79:%.*]] = add i64 [[SHADOW_PTR_INT4]], 24 +; CHECK-INLINE-NEXT: [[TMP80:%.*]] = inttoptr i64 [[TMP79]] to ptr +; CHECK-INLINE-NEXT: [[TMP81:%.*]] = load ptr, ptr [[TMP80]], align 8 +; CHECK-INLINE-NEXT: [[TMP82:%.*]] = ptrtoint ptr [[TMP81]] to i64 +; CHECK-INLINE-NEXT: [[TMP83:%.*]] = icmp sge i64 [[TMP82]], 0 +; CHECK-INLINE-NEXT: [[TMP84:%.*]] = or i1 [[TMP78]], [[TMP83]] +; CHECK-INLINE-NEXT: br i1 [[TMP84]], label %[[BB85:.*]], label %[[BB86:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB85]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[B]], i32 4, ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB86]] +; CHECK-INLINE: [[BB86]]: +; CHECK-INLINE-NEXT: br label %[[BB87]] +; CHECK-INLINE: [[BB87]]: +; CHECK-INLINE-NEXT: store i32 43, ptr [[B]], align 4, !tbaa [[INT_TBAA6:![0-9]+]] +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: define void @test_anon_ns( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A]], ptr @__tysan_v1___ZTSN12__GLOBAL____N__11zE_o_24, i1 true, i64 4, i32 2) +; CHECK-OUTLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA0:![0-9]+]] +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[B]], ptr @__tysan_v1___ZTS1yIN12__GLOBAL____N__11zEE_o_24, i1 true, i64 4, i32 2) +; CHECK-OUTLINE-NEXT: store i32 43, ptr [[B]], align 4, !tbaa [[INT_TBAA5:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret void +; entry: store i32 42, ptr %a, align 4, !tbaa !8 store i32 43, ptr %b, align 4, !tbaa !10 @@ -270,6 +466,97 @@ define void @test_anon_type(ptr %a) sanitize_type { ; CHECK-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA8:![0-9]+]] ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: define void @test_anon_type( +; CHECK-INLINE-SAME: ptr [[A:%.*]]) #[[ATTR0]] { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24 +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC]], label %[[BB0:.*]], label %[[BB22:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB20:.*]] +; CHECK-INLINE: [[BB2]]: +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]] +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]] +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]] +; CHECK-INLINE-NEXT: br i1 [[TMP17]], label %[[BB18:.*]], label %[[BB19:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB18]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB19]] +; CHECK-INLINE: [[BB19]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB21:.*]] +; CHECK-INLINE: [[BB20]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB21]] +; CHECK-INLINE: [[BB21]]: +; CHECK-INLINE-NEXT: br label %[[BB43:.*]] +; CHECK-INLINE: [[BB22]]: +; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr +; CHECK-INLINE-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8 +; CHECK-INLINE-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64 +; CHECK-INLINE-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0 +; CHECK-INLINE-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]] +; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr +; CHECK-INLINE-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8 +; CHECK-INLINE-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64 +; CHECK-INLINE-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0 +; CHECK-INLINE-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]] +; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr +; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8 +; CHECK-INLINE-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64 +; CHECK-INLINE-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0 +; CHECK-INLINE-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]] +; CHECK-INLINE-NEXT: br i1 [[TMP40]], label %[[BB41:.*]], label %[[BB42:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB41]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB42]] +; CHECK-INLINE: [[BB42]]: +; CHECK-INLINE-NEXT: br label %[[BB43]] +; CHECK-INLINE: [[BB43]]: +; CHECK-INLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA8:![0-9]+]] +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: define void @test_anon_type( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]]) #[[ATTR0]] { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A]], ptr @__tysan_v1_____anonymous__027d9e575c5d34cb5d60d6a1d6276f95_o_24, i1 true, i64 4, i32 2) +; CHECK-OUTLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA7:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret void +; entry: store i32 42, ptr %a, align 4, !tbaa !12 ret void @@ -285,10 +572,8 @@ entry: !10 = !{!9, !2, i64 24} !11 = !{!"", !2, i64 24} !12 = !{!11, !2, i64 24} -;. ; CHECK: attributes #[[ATTR0]] = { sanitize_type } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind } -;. ; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} ; CHECK: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META3:![0-9]+]], i64 24} ; CHECK: [[META2]] = !{!"_ZTSN12_GLOBAL__N_11zE", [[META3]], i64 24} @@ -300,3 +585,30 @@ entry: ; CHECK: [[INT_TBAA8]] = !{[[META9:![0-9]+]], [[META3]], i64 24} ; CHECK: [[META9]] = !{!"", [[META3]], i64 24} ;. +; CHECK-INLINE: attributes #[[ATTR0]] = { sanitize_type } +; CHECK-INLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. +; CHECK-OUTLINE: attributes #[[ATTR0]] = { sanitize_type } +; CHECK-OUTLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. +; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} +; CHECK-INLINE: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META3:![0-9]+]], i64 24} +; CHECK-INLINE: [[META2]] = !{!"_ZTSN12_GLOBAL__N_11zE", [[META3]], i64 24} +; CHECK-INLINE: [[META3]] = !{!"int", [[META4:![0-9]+]], i64 0} +; CHECK-INLINE: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} +; CHECK-INLINE: [[META5]] = !{!"Simple C++ TBAA"} +; CHECK-INLINE: [[INT_TBAA6]] = !{[[META7:![0-9]+]], [[META3]], i64 24} +; CHECK-INLINE: [[META7]] = !{!"_ZTS1yIN12_GLOBAL__N_11zEE", [[META3]], i64 24} +; CHECK-INLINE: [[INT_TBAA8]] = !{[[META9:![0-9]+]], [[META3]], i64 24} +; CHECK-INLINE: [[META9]] = !{!"", [[META3]], i64 24} +;. +; CHECK-OUTLINE: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META2:![0-9]+]], i64 24} +; CHECK-OUTLINE: [[META1]] = !{!"_ZTSN12_GLOBAL__N_11zE", [[META2]], i64 24} +; CHECK-OUTLINE: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META4]] = !{!"Simple C++ TBAA"} +; CHECK-OUTLINE: [[INT_TBAA5]] = !{[[META6:![0-9]+]], [[META2]], i64 24} +; CHECK-OUTLINE: [[META6]] = !{!"_ZTS1yIN12_GLOBAL__N_11zEE", [[META2]], i64 24} +; CHECK-OUTLINE: [[INT_TBAA7]] = !{[[META8:![0-9]+]], [[META2]], i64 24} +; CHECK-OUTLINE: [[META8]] = !{!"", [[META2]], i64 24} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/basic-nosan.ll b/llvm/test/Instrumentation/TypeSanitizer/basic-nosan.ll index c1a452d629b7b..10672f7c258a0 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/basic-nosan.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/basic-nosan.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 6 ; Test basic type sanitizer instrumentation. -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -21,7 +22,6 @@ entry: !1 = !{!"omnipotent char", !0, i64 0} !2 = !{!"int", !1, i64 0} !3 = !{!2, !2, i64 0} -;. ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ; CHECK: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat ; CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat @@ -30,7 +30,6 @@ entry: ; CHECK: @llvm.used = appending global [5 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0], section "llvm.metadata" ; CHECK: @__tysan_shadow_memory_address = external global i64 ; CHECK: @__tysan_app_memory_mask = external global i64 -;. ; CHECK-LABEL: define i32 @test_load_nsan( ; CHECK-SAME: ptr [[A:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] @@ -59,8 +58,6 @@ entry: ; CHECK: [[BB0]]: ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] ; CHECK-NEXT: ret i32 [[TMP1]] -; -; ; CHECK-LABEL: define void @test_store_nsan( ; CHECK-SAME: ptr [[A:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] @@ -89,19 +86,139 @@ entry: ; CHECK: [[BB0]]: ; CHECK-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA1]] ; CHECK-NEXT: ret void -; -; ; CHECK-LABEL: define internal void @tysan.module_ctor( ; CHECK-SAME: ) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: call void @__tysan_init() ; CHECK-NEXT: ret void -; -;. ; CHECK: attributes #[[ATTR0]] = { nounwind } -;. ; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} ; CHECK: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0} ; CHECK: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0} ; CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} ; CHECK: [[META4]] = !{!"Simple C++ TBAA"} ;. +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-INLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-INLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-INLINE: @__tysan_v1_int_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_int, ptr @__tysan_v1_int, i64 0 }, comdat +; CHECK-INLINE: @llvm.used = appending global [5 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0], section "llvm.metadata" +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +;. +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-OUTLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1_int_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_int, ptr @__tysan_v1_int, i64 0 }, comdat +; CHECK-OUTLINE: @llvm.used = appending global [5 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0], section "llvm.metadata" +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +;. +; CHECK-INLINE-LABEL: define i32 @test_load_nsan( +; CHECK-INLINE-SAME: ptr [[A:%.*]]) { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[DESC_SET:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[DESC_SET]], label %[[SET_TYPE:.*]], label %[[BB0:.*]], !prof [[PROF0:![0-9]+]] +; CHECK-INLINE: [[SET_TYPE]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_int_o_0, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB0]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] +; CHECK-INLINE-NEXT: ret i32 [[TMP1]] +; +; +; CHECK-INLINE-LABEL: define void @test_store_nsan( +; CHECK-INLINE-SAME: ptr [[A:%.*]]) { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[DESC_SET:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[DESC_SET]], label %[[SET_TYPE:.*]], label %[[BB0:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[SET_TYPE]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_int_o_0, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB0]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA1]] +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-INLINE-LABEL: define internal void @tysan.module_ctor( +; CHECK-INLINE-SAME: ) #[[ATTR0:[0-9]+]] { +; CHECK-INLINE-NEXT: call void @__tysan_init() +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: define i32 @test_load_nsan( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]]) { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A]], ptr @__tysan_v1_int_o_0, i1 false, i64 4, i32 1) +; CHECK-OUTLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA0:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret i32 [[TMP1]] +; +; +; CHECK-OUTLINE-LABEL: define void @test_store_nsan( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]]) { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A]], ptr @__tysan_v1_int_o_0, i1 false, i64 4, i32 2) +; CHECK-OUTLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA0]] +; CHECK-OUTLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: define internal void @tysan.module_ctor( +; CHECK-OUTLINE-SAME: ) #[[ATTR0:[0-9]+]] { +; CHECK-OUTLINE-NEXT: call void @__tysan_init() +; CHECK-OUTLINE-NEXT: ret void +; +;. +; CHECK-INLINE: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK-OUTLINE: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} +; CHECK-INLINE: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0} +; CHECK-INLINE: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0} +; CHECK-INLINE: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} +; CHECK-INLINE: [[META4]] = !{!"Simple C++ TBAA"} +;. +; CHECK-OUTLINE: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} +; CHECK-OUTLINE: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"Simple C++ TBAA"} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/basic.ll b/llvm/test/Instrumentation/TypeSanitizer/basic.ll index ae7ac5304dc08..18956e5deebdf 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/basic.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/basic.ll @@ -1,13 +1,13 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6 ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" declare i32 @declaration_only(i32 %a) sanitize_type -;. ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ; CHECK: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat ; CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat @@ -20,6 +20,30 @@ declare i32 @declaration_only(i32 %a) sanitize_type ; CHECK: @__tysan_v1___ZTS1v_o_12 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1_int, i64 12 }, comdat ; CHECK: @llvm.used = appending global [8 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0, ptr @__tysan_v1___ZTS1x, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1___ZTS1v_o_12], section "llvm.metadata" ;. +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-INLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-INLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-INLINE: @__tysan_v1_int_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_int, ptr @__tysan_v1_int, i64 0 }, comdat +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-INLINE: @__tysan_v1___ZTS1x = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, [7 x i8] } { i64 2, i64 2, ptr @__tysan_v1_int, i64 0, ptr @__tysan_v1_int, i64 4, [7 x i8] c"_ZTS1x\00" }, comdat +; CHECK-INLINE: @__tysan_v1___ZTS1v = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, ptr, i64, [7 x i8] } { i64 2, i64 3, ptr @__tysan_v1_int, i64 8, ptr @__tysan_v1_int, i64 12, ptr @__tysan_v1___ZTS1x, i64 16, [7 x i8] c"_ZTS1v\00" }, comdat +; CHECK-INLINE: @__tysan_v1___ZTS1v_o_12 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1_int, i64 12 }, comdat +; CHECK-INLINE: @llvm.used = appending global [8 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0, ptr @__tysan_v1___ZTS1x, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1___ZTS1v_o_12], section "llvm.metadata" +;. +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-OUTLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1_int_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_int, ptr @__tysan_v1_int, i64 0 }, comdat +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-OUTLINE: @__tysan_v1___ZTS1x = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, [7 x i8] } { i64 2, i64 2, ptr @__tysan_v1_int, i64 0, ptr @__tysan_v1_int, i64 4, [7 x i8] c"_ZTS1x\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1___ZTS1v = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, ptr, i64, [7 x i8] } { i64 2, i64 3, ptr @__tysan_v1_int, i64 8, ptr @__tysan_v1_int, i64 12, ptr @__tysan_v1___ZTS1x, i64 16, [7 x i8] c"_ZTS1v\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1___ZTS1v_o_12 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1_int, i64 12 }, comdat +; CHECK-OUTLINE: @llvm.used = appending global [8 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0, ptr @__tysan_v1___ZTS1x, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1___ZTS1v_o_12], section "llvm.metadata" +;. define i32 @test_load(ptr %a) sanitize_type { ; CHECK-LABEL: define i32 @test_load( ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { @@ -103,6 +127,97 @@ define i32 @test_load(ptr %a) sanitize_type { ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] ; CHECK-NEXT: ret i32 [[TMP1]] ; +; CHECK-INLINE-LABEL: define i32 @test_load( +; CHECK-INLINE-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], @__tysan_v1_int_o_0 +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC]], label %[[BB0:.*]], label %[[BB22:.*]], !prof [[PROF0:![0-9]+]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB20:.*]] +; CHECK-INLINE: [[BB2]]: +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]] +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]] +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]] +; CHECK-INLINE-NEXT: br i1 [[TMP17]], label %[[BB18:.*]], label %[[BB19:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB18]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1_int_o_0, i32 1) +; CHECK-INLINE-NEXT: br label %[[BB19]] +; CHECK-INLINE: [[BB19]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_int_o_0, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB21:.*]] +; CHECK-INLINE: [[BB20]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1_int_o_0, i32 1) +; CHECK-INLINE-NEXT: br label %[[BB21]] +; CHECK-INLINE: [[BB21]]: +; CHECK-INLINE-NEXT: br label %[[BB43:.*]] +; CHECK-INLINE: [[BB22]]: +; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr +; CHECK-INLINE-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8 +; CHECK-INLINE-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64 +; CHECK-INLINE-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0 +; CHECK-INLINE-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]] +; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr +; CHECK-INLINE-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8 +; CHECK-INLINE-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64 +; CHECK-INLINE-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0 +; CHECK-INLINE-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]] +; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr +; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8 +; CHECK-INLINE-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64 +; CHECK-INLINE-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0 +; CHECK-INLINE-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]] +; CHECK-INLINE-NEXT: br i1 [[TMP40]], label %[[BB41:.*]], label %[[BB42:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB41]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1_int_o_0, i32 1) +; CHECK-INLINE-NEXT: br label %[[BB42]] +; CHECK-INLINE: [[BB42]]: +; CHECK-INLINE-NEXT: br label %[[BB43]] +; CHECK-INLINE: [[BB43]]: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] +; CHECK-INLINE-NEXT: ret i32 [[TMP1]] +; +; CHECK-OUTLINE-LABEL: define i32 @test_load( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A]], ptr @__tysan_v1_int_o_0, i1 true, i64 4, i32 1) +; CHECK-OUTLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA0:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret i32 [[TMP1]] +; entry: %tmp1 = load i32, ptr %a, align 4, !tbaa !3 ret i32 %tmp1 @@ -191,6 +306,97 @@ define void @test_store(ptr %a) sanitize_type { ; CHECK-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA5:![0-9]+]] ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: define void @test_store( +; CHECK-INLINE-SAME: ptr [[A:%.*]]) #[[ATTR0]] { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], @__tysan_v1___ZTS1v_o_12 +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC]], label %[[BB0:.*]], label %[[BB22:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB0]]: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB20:.*]] +; CHECK-INLINE: [[BB2]]: +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]] +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]] +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]] +; CHECK-INLINE-NEXT: br i1 [[TMP17]], label %[[BB18:.*]], label %[[BB19:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB18]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1___ZTS1v_o_12, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB19]] +; CHECK-INLINE: [[BB19]]: +; CHECK-INLINE-NEXT: store ptr @__tysan_v1___ZTS1v_o_12, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label %[[BB21:.*]] +; CHECK-INLINE: [[BB20]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1___ZTS1v_o_12, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB21]] +; CHECK-INLINE: [[BB21]]: +; CHECK-INLINE-NEXT: br label %[[BB43:.*]] +; CHECK-INLINE: [[BB22]]: +; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr +; CHECK-INLINE-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8 +; CHECK-INLINE-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64 +; CHECK-INLINE-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0 +; CHECK-INLINE-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]] +; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr +; CHECK-INLINE-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8 +; CHECK-INLINE-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64 +; CHECK-INLINE-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0 +; CHECK-INLINE-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]] +; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr +; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8 +; CHECK-INLINE-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64 +; CHECK-INLINE-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0 +; CHECK-INLINE-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]] +; CHECK-INLINE-NEXT: br i1 [[TMP40]], label %[[BB41:.*]], label %[[BB42:.*]], !prof [[PROF0]] +; CHECK-INLINE: [[BB41]]: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr @__tysan_v1___ZTS1v_o_12, i32 2) +; CHECK-INLINE-NEXT: br label %[[BB42]] +; CHECK-INLINE: [[BB42]]: +; CHECK-INLINE-NEXT: br label %[[BB43]] +; CHECK-INLINE: [[BB43]]: +; CHECK-INLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA5:![0-9]+]] +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: define void @test_store( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]]) #[[ATTR0]] { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A]], ptr @__tysan_v1___ZTS1v_o_12, i1 true, i64 4, i32 2) +; CHECK-OUTLINE-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[INT_TBAA4:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret void +; entry: store i32 42, ptr %a, align 4, !tbaa !6 ret void @@ -203,10 +409,8 @@ entry: !4 = !{!"_ZTS1x", !2, i64 0, !2, i64 4} !5 = !{!"_ZTS1v", !2, i64 8, !2, i64 12, !4, i64 16} !6 = !{!5, !2, i64 12} -;. ; CHECK: attributes #[[ATTR0]] = { sanitize_type } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind } -;. ; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} ; CHECK: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0} ; CHECK: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0} @@ -216,3 +420,26 @@ entry: ; CHECK: [[META6]] = !{!"_ZTS1v", [[META2]], i64 8, [[META2]], i64 12, [[META7:![0-9]+]], i64 16} ; CHECK: [[META7]] = !{!"_ZTS1x", [[META2]], i64 0, [[META2]], i64 4} ;. +; CHECK-INLINE: attributes #[[ATTR0]] = { sanitize_type } +; CHECK-INLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. +; CHECK-OUTLINE: attributes #[[ATTR0]] = { sanitize_type } +; CHECK-OUTLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. +; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} +; CHECK-INLINE: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0} +; CHECK-INLINE: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0} +; CHECK-INLINE: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0} +; CHECK-INLINE: [[META4]] = !{!"Simple C++ TBAA"} +; CHECK-INLINE: [[INT_TBAA5]] = !{[[META6:![0-9]+]], [[META2]], i64 12} +; CHECK-INLINE: [[META6]] = !{!"_ZTS1v", [[META2]], i64 8, [[META2]], i64 12, [[META7:![0-9]+]], i64 16} +; CHECK-INLINE: [[META7]] = !{!"_ZTS1x", [[META2]], i64 0, [[META2]], i64 4} +;. +; CHECK-OUTLINE: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} +; CHECK-OUTLINE: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"Simple C++ TBAA"} +; CHECK-OUTLINE: [[INT_TBAA4]] = !{[[META5:![0-9]+]], [[META1]], i64 12} +; CHECK-OUTLINE: [[META5]] = !{!"_ZTS1v", [[META1]], i64 8, [[META1]], i64 12, [[META6:![0-9]+]], i64 16} +; CHECK-OUTLINE: [[META6]] = !{!"_ZTS1x", [[META1]], i64 0, [[META1]], i64 4} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/basic_outlined.ll b/llvm/test/Instrumentation/TypeSanitizer/basic_outlined.ll deleted file mode 100644 index 1d118560f7580..0000000000000 --- a/llvm/test/Instrumentation/TypeSanitizer/basic_outlined.ll +++ /dev/null @@ -1,68 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals -; Test basic type sanitizer instrumentation. -; -; RUN: opt -passes='tysan' -tysan-outline-instrumentation -S %s | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" - -;. -; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] -; CHECK: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat -; CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat -; CHECK: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat -; CHECK: @__tysan_v1_int_o_0 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1_int, ptr @__tysan_v1_int, i64 0 }, comdat -; CHECK: @__tysan_shadow_memory_address = external global i64 -; CHECK: @__tysan_app_memory_mask = external global i64 -; CHECK: @__tysan_v1___ZTS1x = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, [7 x i8] } { i64 2, i64 2, ptr @__tysan_v1_int, i64 0, ptr @__tysan_v1_int, i64 4, [7 x i8] c"_ZTS1x\00" }, comdat -; CHECK: @__tysan_v1___ZTS1v = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, ptr, i64, [7 x i8] } { i64 2, i64 3, ptr @__tysan_v1_int, i64 8, ptr @__tysan_v1_int, i64 12, ptr @__tysan_v1___ZTS1x, i64 16, [7 x i8] c"_ZTS1v\00" }, comdat -; CHECK: @__tysan_v1___ZTS1v_o_12 = linkonce_odr constant { i64, ptr, ptr, i64 } { i64 1, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1_int, i64 12 }, comdat -; CHECK: @llvm.used = appending global [8 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_int_o_0, ptr @__tysan_v1___ZTS1x, ptr @__tysan_v1___ZTS1v, ptr @__tysan_v1___ZTS1v_o_12], section "llvm.metadata" -;. -define i32 @test_load(ptr %a) sanitize_type { -; CHECK-LABEL: @test_load( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 -; CHECK-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 -; CHECK-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A:%.*]], ptr @__tysan_v1_int_o_0, i1 true, i64 4, i32 1) -; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[TBAA0:![0-9]+]] -; CHECK-NEXT: ret i32 [[TMP1]] -; -entry: - %tmp1 = load i32, ptr %a, align 4, !tbaa !3 - ret i32 %tmp1 -} - -define void @test_store(ptr %a) sanitize_type { -; CHECK-LABEL: @test_store( -; CHECK-NEXT: entry: -; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 -; CHECK-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 -; CHECK-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A:%.*]], ptr @__tysan_v1___ZTS1v_o_12, i1 true, i64 4, i32 2) -; CHECK-NEXT: store i32 42, ptr [[A]], align 4, !tbaa [[TBAA4:![0-9]+]] -; CHECK-NEXT: ret void -; - -entry: - store i32 42, ptr %a, align 4, !tbaa !6 - ret void -} - -!0 = !{!"Simple C++ TBAA"} -!1 = !{!"omnipotent char", !0, i64 0} -!2 = !{!"int", !1, i64 0} -!3 = !{!2, !2, i64 0} -!4 = !{!"_ZTS1x", !2, i64 0, !2, i64 4} -!5 = !{!"_ZTS1v", !2, i64 8, !2, i64 12, !4, i64 16} -!6 = !{!5, !2, i64 12} -;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } -; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind } -;. -; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} -; CHECK: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} -; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} -; CHECK: [[META3]] = !{!"Simple C++ TBAA"} -; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META1]], i64 12} -; CHECK: [[META5]] = !{!"_ZTS1v", [[META1]], i64 8, [[META1]], i64 12, [[META6:![0-9]+]], i64 16} -; CHECK: [[META6]] = !{!"_ZTS1x", [[META1]], i64 0, [[META1]], i64 4} -;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/byval.ll b/llvm/test/Instrumentation/TypeSanitizer/byval.ll index 6ae343d8d5344..70af980542d52 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/byval.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/byval.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs ; Test basic type sanitizer instrumentation. -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -21,12 +22,10 @@ entry: %0 = load ptr, ptr %name, align 8 ret ptr %0 } -;. ; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ; CHECK: @__tysan_shadow_memory_address = external global i64 ; CHECK: @__tysan_app_memory_mask = external global i64 -;. ; CHECK-LABEL: @byval_test( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 @@ -38,8 +37,6 @@ entry: ; CHECK-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 256, i1 false) ; CHECK-NEXT: ret void -; -; ; CHECK-LABEL: @test_insert_point( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 @@ -86,16 +83,120 @@ entry: ; CHECK: 5: ; CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[NAME]], align 8 ; CHECK-NEXT: ret ptr [[TMP6]] -; -; ; CHECK-LABEL: @tysan.module_ctor( ; CHECK-NEXT: call void @__tysan_init() ; CHECK-NEXT: ret void -; -;. ; CHECK: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind } ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } -;. ; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} ;. +; CHECK-INLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +;. +; CHECK-OUTLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +;. +; CHECK-INLINE-LABEL: @byval_test( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[X:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 256, i1 false) +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-INLINE-LABEL: @test_insert_point( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 128, i1 false) +; CHECK-INLINE-NEXT: [[NAME:%.*]] = getelementptr inbounds [[STRUCT:%.*]], ptr [[V]], i64 0, i32 1 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[NAME]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[DESC_SET:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[DESC_SET]], label [[SET_TYPE:%.*]], label [[TMP5:%.*]], !prof [[PROF0:![0-9]+]] +; CHECK-INLINE: set.type: +; CHECK-INLINE-NEXT: store ptr null, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_4_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 32 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_4_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_4_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -4 to ptr), ptr [[SHADOW_BYTE_4_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_5_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 40 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_5_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_5_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -5 to ptr), ptr [[SHADOW_BYTE_5_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_6_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 48 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_6_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_6_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -6 to ptr), ptr [[SHADOW_BYTE_6_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_7_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 56 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_7_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_7_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -7 to ptr), ptr [[SHADOW_BYTE_7_PTR]], align 8 +; CHECK-INLINE-NEXT: br label [[TMP5]] +; CHECK-INLINE: 5: +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = load ptr, ptr [[NAME]], align 8 +; CHECK-INLINE-NEXT: ret ptr [[TMP6]] +; +; +; CHECK-INLINE-LABEL: @tysan.module_ctor( +; CHECK-INLINE-NEXT: call void @__tysan_init() +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: @byval_test( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X:%.*]], ptr null, i64 32, i1 false) +; CHECK-OUTLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: @test_insert_point( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[V:%.*]], ptr null, i64 16, i1 false) +; CHECK-OUTLINE-NEXT: [[NAME:%.*]] = getelementptr inbounds [[STRUCT:%.*]], ptr [[V]], i64 0, i32 1 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[NAME]], ptr null, i1 false, i64 8, i32 1) +; CHECK-OUTLINE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[NAME]], align 8 +; CHECK-OUTLINE-NEXT: ret ptr [[TMP0]] +; +; +; CHECK-OUTLINE-LABEL: @tysan.module_ctor( +; CHECK-OUTLINE-NEXT: call void @__tysan_init() +; CHECK-OUTLINE-NEXT: ret void +; +;. +; CHECK-INLINE: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } +; CHECK-INLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +; CHECK-INLINE: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } +;. +; CHECK-INLINE: [[PROF0]] = !{!"branch_weights", i32 1, i32 100000} +;. +; CHECK-OUTLINE: attributes #[[ATTR0:[0-9]+]] = { sanitize_type } +; CHECK-OUTLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/globals.ll b/llvm/test/Instrumentation/TypeSanitizer/globals.ll index a73599e864485..5835f9ef5a512 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/globals.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/globals.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals --include-generated-funcs -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -16,7 +17,6 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" !2 = !{!"int", !1, i64 0} !13 = !{ptr @global1, !2} !14 = !{ptr @global1, !2} -;. ; CHECK: @global1 = global i32 0, align 4 ; CHECK: @global2 = global i32 0, align 4 ; CHECK: @__tysan_shadow_memory_address = external global i64 @@ -26,14 +26,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat ; CHECK: @llvm.used = appending global [4 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int], section "llvm.metadata" ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] -;. ; CHECK-LABEL: define {{[^@]+}}@tysan.module_ctor ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: call void @__tysan_init() ; CHECK-NEXT: call void @__tysan_set_globals_types() ; CHECK-NEXT: ret void -; -; ; CHECK-LABEL: define {{[^@]+}}@__tysan_set_globals_types() { ; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 ; CHECK-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 @@ -66,12 +63,99 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK-NEXT: [[SHADOW_BYTE_3_PTR10:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET9]] to ptr ; CHECK-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR10]], align 8 ; CHECK-NEXT: ret void -; -;. ; CHECK: attributes #[[ATTR0]] = { nounwind } -;. ; CHECK: [[META0:![0-9]+]] = !{ptr @global1, [[META1:![0-9]+]]} ; CHECK: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} ; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} ; CHECK: [[META3]] = !{!"Simple C++ TBAA"} ;. +; CHECK-INLINE: @global1 = global i32 0, align 4 +; CHECK-INLINE: @global2 = global i32 0, align 4 +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-INLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-INLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-INLINE: @llvm.used = appending global [4 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int], section "llvm.metadata" +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +;. +; CHECK-OUTLINE: @global1 = global i32 0, align 4 +; CHECK-OUTLINE: @global2 = global i32 0, align 4 +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-OUTLINE: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat +; 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_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat +; CHECK-OUTLINE: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat +; CHECK-OUTLINE: @llvm.used = appending global [4 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int], section "llvm.metadata" +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +;. +; CHECK-INLINE-LABEL: define {{[^@]+}}@tysan.module_ctor +; CHECK-INLINE-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-INLINE-NEXT: call void @__tysan_init() +; CHECK-INLINE-NEXT: call void @__tysan_set_globals_types() +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-INLINE-LABEL: define {{[^@]+}}@__tysan_set_globals_types() { +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 ptrtoint (ptr @global1 to i64), [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_int, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED1:%.*]] = and i64 ptrtoint (ptr @global1 to i64), [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED2:%.*]] = shl i64 [[APP_PTR_MASKED1]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT3:%.*]] = add i64 [[APP_PTR_SHIFTED2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR4:%.*]] = inttoptr i64 [[SHADOW_PTR_INT3]] to ptr +; CHECK-INLINE-NEXT: store ptr @__tysan_v1_int, ptr [[SHADOW_PTR4]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET5:%.*]] = add i64 [[SHADOW_PTR_INT3]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR6:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET5]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR6]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET7:%.*]] = add i64 [[SHADOW_PTR_INT3]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR8:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET7]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR8]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET9:%.*]] = add i64 [[SHADOW_PTR_INT3]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR10:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET9]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR10]], align 8 +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: define {{[^@]+}}@tysan.module_ctor +; CHECK-OUTLINE-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-OUTLINE-NEXT: call void @__tysan_init() +; CHECK-OUTLINE-NEXT: call void @__tysan_set_globals_types() +; CHECK-OUTLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: define {{[^@]+}}@__tysan_set_globals_types() { +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_set_shadow_type(ptr @global1, ptr @__tysan_v1_int, i64 4) +; CHECK-OUTLINE-NEXT: call void @__tysan_set_shadow_type(ptr @global1, ptr @__tysan_v1_int, i64 4) +; CHECK-OUTLINE-NEXT: ret void +; +;. +; CHECK-INLINE: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK-OUTLINE: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK-INLINE: [[META0:![0-9]+]] = !{ptr @global1, [[META1:![0-9]+]]} +; CHECK-INLINE: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} +; CHECK-INLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-INLINE: [[META3]] = !{!"Simple C++ TBAA"} +;. +; CHECK-OUTLINE: [[META0:![0-9]+]] = !{ptr @global1, [[META1:![0-9]+]]} +; CHECK-OUTLINE: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"Simple C++ TBAA"} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/globals_outlined.ll b/llvm/test/Instrumentation/TypeSanitizer/globals_outlined.ll deleted file mode 100644 index 0bd7940467415..0000000000000 --- a/llvm/test/Instrumentation/TypeSanitizer/globals_outlined.ll +++ /dev/null @@ -1,24 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs -; RUN: opt -passes='tysan' -tysan-outline-instrumentation -S %s | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" - -@global1 = global i32 0, align 4 -@global2 = global i32 0, align 4 - - -; CHECK-LABEL: define internal void @__tysan_set_globals_types( -; CHECK-NEXT: %app.mem.mask = load i64, ptr @__tysan_app_memory_mask, align 8 -; CHECK-NEXT: %shadow.base = load i64, ptr @__tysan_shadow_memory_address, align 8 -; CHECK-NEXT: call void @__tysan_set_shadow_type(ptr @global1, ptr @__tysan_v1_int, i64 4) -; CHECK-NEXT: call void @__tysan_set_shadow_type(ptr @global1, ptr @__tysan_v1_int, i64 4) -; CHECK-NEXT: ret void -; CHECK-NEXT: } - -!llvm.tysan.globals = !{!13, !14} - -!0 = !{!"Simple C++ TBAA"} -!1 = !{!"omnipotent char", !0, i64 0} -!2 = !{!"int", !1, i64 0} -!13 = !{ptr @global1, !2} -!14 = !{ptr @global1, !2} diff --git a/llvm/test/Instrumentation/TypeSanitizer/invalid-metadata.ll b/llvm/test/Instrumentation/TypeSanitizer/invalid-metadata.ll index 0c99c0f2e674c..e3565c0721e1f 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/invalid-metadata.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/invalid-metadata.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals --include-generated-funcs -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE !llvm.tysan.globals = !{!0} @@ -7,29 +8,72 @@ !1 = !{!"any pointer", !2, i64 0} !2 = !{!"omnipotent char", !3, i64 0} !3 = !{!"Simple C/C++ TBAA"} -;. ; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" ; CHECK: @__tysan_shadow_memory_address = external global i64 ; CHECK: @__tysan_app_memory_mask = external global i64 ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] -;. ; CHECK-LABEL: define {{[^@]+}}@tysan.module_ctor ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: call void @__tysan_init() ; CHECK-NEXT: call void @__tysan_set_globals_types() ; CHECK-NEXT: ret void -; -; ; CHECK-LABEL: define {{[^@]+}}@__tysan_set_globals_types() { ; CHECK-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4 ; CHECK-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4 ; CHECK-NEXT: ret void -; -;. ; CHECK: attributes #[[ATTR0]] = { nounwind } -;. ; CHECK: [[META0:![0-9]+]] = distinct !{ptr null, [[META1:![0-9]+]]} ; CHECK: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0} ; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} ; CHECK: [[META3]] = !{!"Simple C/C++ TBAA"} ;. +; CHECK-INLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-INLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-INLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +;. +; CHECK-OUTLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-OUTLINE: @__tysan_shadow_memory_address = external global i64 +; CHECK-OUTLINE: @__tysan_app_memory_mask = external global i64 +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +;. +; CHECK-INLINE-LABEL: define {{[^@]+}}@tysan.module_ctor +; CHECK-INLINE-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-INLINE-NEXT: call void @__tysan_init() +; CHECK-INLINE-NEXT: call void @__tysan_set_globals_types() +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-INLINE-LABEL: define {{[^@]+}}@__tysan_set_globals_types() { +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4 +; CHECK-INLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: define {{[^@]+}}@tysan.module_ctor +; CHECK-OUTLINE-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-OUTLINE-NEXT: call void @__tysan_init() +; CHECK-OUTLINE-NEXT: call void @__tysan_set_globals_types() +; CHECK-OUTLINE-NEXT: ret void +; +; +; CHECK-OUTLINE-LABEL: define {{[^@]+}}@__tysan_set_globals_types() { +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 4 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 4 +; CHECK-OUTLINE-NEXT: ret void +; +;. +; CHECK-INLINE: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK-OUTLINE: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK-INLINE: [[META0:![0-9]+]] = distinct !{ptr null, [[META1:![0-9]+]]} +; CHECK-INLINE: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0} +; CHECK-INLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-INLINE: [[META3]] = !{!"Simple C/C++ TBAA"} +;. +; CHECK-OUTLINE: [[META0:![0-9]+]] = distinct !{ptr null, [[META1:![0-9]+]]} +; CHECK-OUTLINE: [[META1]] = !{!"any pointer", [[META2:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"Simple C/C++ TBAA"} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/memintrinsics.ll b/llvm/test/Instrumentation/TypeSanitizer/memintrinsics.ll index 65a30bd1ace46..08869afdcb34b 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/memintrinsics.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/memintrinsics.ll @@ -1,7 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -22,6 +23,27 @@ define void @test_memset(ptr %a, ptr %b) nounwind uwtable sanitize_type { ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 800, i1 false) ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[A]], i8 0, i64 100, i1 false) ; CHECK-NEXT: ret void +; +; CHECK-INLINE-LABEL: @test_memset( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[TMP4]], i8 0, i64 800, i1 false) +; CHECK-INLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[A]], i8 0, i64 100, i1 false) +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_memset( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[A:%.*]], ptr null, i64 100, i1 false) +; CHECK-OUTLINE-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[A]], i8 0, i64 100, i1 false) +; CHECK-OUTLINE-NEXT: ret void ; entry: tail call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 100, i32 1, i1 false) @@ -46,6 +68,32 @@ define void @test_memmove(ptr %a, ptr %b) nounwind uwtable sanitize_type { ; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 8 [[TMP4]], ptr align 8 [[TMP9]], i64 800, i1 false) ; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[A]], ptr align 1 [[B]], i64 100, i1 false) ; CHECK-NEXT: ret void +; +; CHECK-INLINE-LABEL: @test_memmove( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[B:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = shl i64 [[TMP6]], 3 +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 8 [[TMP4]], ptr align 8 [[TMP9]], i64 800, i1 false) +; CHECK-INLINE-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[A]], ptr align 1 [[B]], i64 100, i1 false) +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_memmove( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[A:%.*]], ptr [[B:%.*]], i64 100, i1 true) +; CHECK-OUTLINE-NEXT: call void @llvm.memmove.p0.p0.i64(ptr align 1 [[A]], ptr align 1 [[B]], i64 100, i1 false) +; CHECK-OUTLINE-NEXT: ret void ; entry: tail call void @llvm.memmove.p0.p0.i64(ptr %a, ptr %b, i64 100, i32 1, i1 false) @@ -70,6 +118,32 @@ define void @test_memcpy(ptr %a, ptr %b) nounwind uwtable sanitize_type { ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP4]], ptr align 8 [[TMP9]], i64 800, i1 false) ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[A]], ptr align 1 [[B]], i64 100, i1 false) ; CHECK-NEXT: ret void +; +; CHECK-INLINE-LABEL: @test_memcpy( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 3 +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[B:%.*]] to i64 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = shl i64 [[TMP6]], 3 +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP4]], ptr align 8 [[TMP9]], i64 800, i1 false) +; CHECK-INLINE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[A]], ptr align 1 [[B]], i64 100, i1 false) +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_memcpy( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_mem_inst(ptr [[A:%.*]], ptr [[B:%.*]], i64 100, i1 false) +; CHECK-OUTLINE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[A]], ptr align 1 [[B]], i64 100, i1 false) +; CHECK-OUTLINE-NEXT: ret void ; entry: tail call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %b, i64 100, i32 1, i1 false) diff --git a/llvm/test/Instrumentation/TypeSanitizer/nosanitize.ll b/llvm/test/Instrumentation/TypeSanitizer/nosanitize.ll index d0ae3bcb435ba..7982bb627a3fd 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/nosanitize.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/nosanitize.ll @@ -1,14 +1,20 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6 ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -;. ; CHECK: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" ; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] ;. +; CHECK-INLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-INLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +;. +; CHECK-OUTLINE: @llvm.used = appending global [1 x ptr] [ptr @tysan.module_ctor], section "llvm.metadata" +; CHECK-OUTLINE: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }] +;. define i32 @test_load(ptr %a) sanitize_type { ; CHECK-LABEL: define i32 @test_load( ; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { @@ -16,6 +22,18 @@ define i32 @test_load(ptr %a) sanitize_type { ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA0:![0-9]+]], !nosanitize [[META4:![0-9]+]] ; CHECK-NEXT: ret i32 [[TMP1]] ; +; CHECK-INLINE-LABEL: define i32 @test_load( +; CHECK-INLINE-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-INLINE-NEXT: [[ENTRY:.*:]] +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA0:![0-9]+]], !nosanitize [[META4:![0-9]+]] +; CHECK-INLINE-NEXT: ret i32 [[TMP1]] +; +; CHECK-OUTLINE-LABEL: define i32 @test_load( +; CHECK-OUTLINE-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-OUTLINE-NEXT: [[ENTRY:.*:]] +; CHECK-OUTLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa [[INT_TBAA0:![0-9]+]], !nosanitize [[META4:![0-9]+]] +; CHECK-OUTLINE-NEXT: ret i32 [[TMP1]] +; entry: %tmp1 = load i32, ptr %a, align 4, !tbaa !3, !nosanitize !{} ret i32 %tmp1 @@ -28,13 +46,29 @@ entry: !4 = !{!"_ZTS1x", !2, i64 0, !2, i64 4} !5 = !{!"_ZTS1v", !2, i64 8, !2, i64 12, !4, i64 16} !6 = !{!5, !2, i64 12} -;. ; CHECK: attributes #[[ATTR0]] = { sanitize_type } ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind } -;. ; CHECK: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} ; CHECK: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} ; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} ; CHECK: [[META3]] = !{!"Simple C++ TBAA"} ; CHECK: [[META4]] = !{} ;. +; CHECK-INLINE: attributes #[[ATTR0]] = { sanitize_type } +; CHECK-INLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. +; CHECK-OUTLINE: attributes #[[ATTR0]] = { sanitize_type } +; CHECK-OUTLINE: attributes #[[ATTR1:[0-9]+]] = { nounwind } +;. +; CHECK-INLINE: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} +; CHECK-INLINE: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} +; CHECK-INLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-INLINE: [[META3]] = !{!"Simple C++ TBAA"} +; CHECK-INLINE: [[META4]] = !{} +;. +; CHECK-OUTLINE: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} +; CHECK-OUTLINE: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0} +; CHECK-OUTLINE: [[META3]] = !{!"Simple C++ TBAA"} +; CHECK-OUTLINE: [[META4]] = !{} +;. diff --git a/llvm/test/Instrumentation/TypeSanitizer/sanitize-no-tbaa.ll b/llvm/test/Instrumentation/TypeSanitizer/sanitize-no-tbaa.ll index 060f031bf2c58..57fe2e2c73faf 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/sanitize-no-tbaa.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/sanitize-no-tbaa.ll @@ -1,7 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -87,6 +88,95 @@ define i32 @test_load_unk(ptr %a) sanitize_type { ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4 ; CHECK-NEXT: ret i32 [[TMP1]] ; +; CHECK-INLINE-LABEL: @test_load_unk( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A:%.*]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC]], label [[TMP0:%.*]], label [[TMP22:%.*]], !prof [[PROF0:![0-9]+]] +; CHECK-INLINE: 0: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]] +; CHECK-INLINE: 2: +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]] +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]] +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]] +; CHECK-INLINE-NEXT: br i1 [[TMP17]], label [[TMP18:%.*]], label [[TMP19:%.*]], !prof [[PROF0]] +; CHECK-INLINE: 18: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 1) +; CHECK-INLINE-NEXT: br label [[TMP19]] +; CHECK-INLINE: 19: +; CHECK-INLINE-NEXT: store ptr null, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label [[TMP21:%.*]] +; CHECK-INLINE: 20: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 1) +; CHECK-INLINE-NEXT: br label [[TMP21]] +; CHECK-INLINE: 21: +; CHECK-INLINE-NEXT: br label [[TMP43:%.*]] +; CHECK-INLINE: 22: +; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr +; CHECK-INLINE-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8 +; CHECK-INLINE-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64 +; CHECK-INLINE-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0 +; CHECK-INLINE-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]] +; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr +; CHECK-INLINE-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8 +; CHECK-INLINE-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64 +; CHECK-INLINE-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0 +; CHECK-INLINE-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]] +; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr +; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8 +; CHECK-INLINE-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64 +; CHECK-INLINE-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0 +; CHECK-INLINE-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]] +; CHECK-INLINE-NEXT: br i1 [[TMP40]], label [[TMP41:%.*]], label [[TMP42:%.*]], !prof [[PROF0]] +; CHECK-INLINE: 41: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 1) +; CHECK-INLINE-NEXT: br label [[TMP42]] +; CHECK-INLINE: 42: +; CHECK-INLINE-NEXT: br label [[TMP43]] +; CHECK-INLINE: 43: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4 +; CHECK-INLINE-NEXT: ret i32 [[TMP1]] +; +; CHECK-OUTLINE-LABEL: @test_load_unk( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A:%.*]], ptr null, i1 true, i64 4, i32 1) +; CHECK-OUTLINE-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4 +; CHECK-OUTLINE-NEXT: ret i32 [[TMP1]] +; entry: %tmp1 = load i32, ptr %a, align 4 ret i32 %tmp1 @@ -174,6 +264,95 @@ define void @test_store_unk(ptr %a) sanitize_type { ; CHECK-NEXT: store i32 42, ptr [[A]], align 4 ; CHECK-NEXT: ret void ; +; CHECK-INLINE-LABEL: @test_store_unk( +; CHECK-INLINE-NEXT: entry: +; CHECK-INLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-INLINE-NEXT: [[APP_PTR_INT:%.*]] = ptrtoint ptr [[A:%.*]] to i64 +; CHECK-INLINE-NEXT: [[APP_PTR_MASKED:%.*]] = and i64 [[APP_PTR_INT]], [[APP_MEM_MASK]] +; CHECK-INLINE-NEXT: [[APP_PTR_SHIFTED:%.*]] = shl i64 [[APP_PTR_MASKED]], 3 +; CHECK-INLINE-NEXT: [[SHADOW_PTR_INT:%.*]] = add i64 [[APP_PTR_SHIFTED]], [[SHADOW_BASE]] +; CHECK-INLINE-NEXT: [[SHADOW_PTR:%.*]] = inttoptr i64 [[SHADOW_PTR_INT]] to ptr +; CHECK-INLINE-NEXT: [[SHADOW_DESC:%.*]] = load ptr, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[BAD_DESC:%.*]] = icmp ne ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[BAD_DESC]], label [[TMP0:%.*]], label [[TMP22:%.*]], !prof [[PROF0]] +; CHECK-INLINE: 0: +; CHECK-INLINE-NEXT: [[TMP1:%.*]] = icmp eq ptr [[SHADOW_DESC]], null +; CHECK-INLINE-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP20:%.*]] +; CHECK-INLINE: 2: +; CHECK-INLINE-NEXT: [[TMP3:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr +; CHECK-INLINE-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8 +; CHECK-INLINE-NEXT: [[TMP6:%.*]] = icmp ne ptr [[TMP5]], null +; CHECK-INLINE-NEXT: [[TMP7:%.*]] = or i1 false, [[TMP6]] +; CHECK-INLINE-NEXT: [[TMP8:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr +; CHECK-INLINE-NEXT: [[TMP10:%.*]] = load ptr, ptr [[TMP9]], align 8 +; CHECK-INLINE-NEXT: [[TMP11:%.*]] = icmp ne ptr [[TMP10]], null +; CHECK-INLINE-NEXT: [[TMP12:%.*]] = or i1 [[TMP7]], [[TMP11]] +; CHECK-INLINE-NEXT: [[TMP13:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr +; CHECK-INLINE-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP14]], align 8 +; CHECK-INLINE-NEXT: [[TMP16:%.*]] = icmp ne ptr [[TMP15]], null +; CHECK-INLINE-NEXT: [[TMP17:%.*]] = or i1 [[TMP12]], [[TMP16]] +; CHECK-INLINE-NEXT: br i1 [[TMP17]], label [[TMP18:%.*]], label [[TMP19:%.*]], !prof [[PROF0]] +; CHECK-INLINE: 18: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 2) +; CHECK-INLINE-NEXT: br label [[TMP19]] +; CHECK-INLINE: 19: +; CHECK-INLINE-NEXT: store ptr null, ptr [[SHADOW_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_1_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_1_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -1 to ptr), ptr [[SHADOW_BYTE_1_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_2_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_2_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -2 to ptr), ptr [[SHADOW_BYTE_2_PTR]], align 8 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_OFFSET:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[SHADOW_BYTE_3_PTR:%.*]] = inttoptr i64 [[SHADOW_BYTE_3_OFFSET]] to ptr +; CHECK-INLINE-NEXT: store ptr inttoptr (i64 -3 to ptr), ptr [[SHADOW_BYTE_3_PTR]], align 8 +; CHECK-INLINE-NEXT: br label [[TMP21:%.*]] +; CHECK-INLINE: 20: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 2) +; CHECK-INLINE-NEXT: br label [[TMP21]] +; CHECK-INLINE: 21: +; CHECK-INLINE-NEXT: br label [[TMP43:%.*]] +; CHECK-INLINE: 22: +; CHECK-INLINE-NEXT: [[TMP23:%.*]] = add i64 [[SHADOW_PTR_INT]], 8 +; CHECK-INLINE-NEXT: [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to ptr +; CHECK-INLINE-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP24]], align 8 +; CHECK-INLINE-NEXT: [[TMP26:%.*]] = ptrtoint ptr [[TMP25]] to i64 +; CHECK-INLINE-NEXT: [[TMP27:%.*]] = icmp sge i64 [[TMP26]], 0 +; CHECK-INLINE-NEXT: [[TMP28:%.*]] = or i1 false, [[TMP27]] +; CHECK-INLINE-NEXT: [[TMP29:%.*]] = add i64 [[SHADOW_PTR_INT]], 16 +; CHECK-INLINE-NEXT: [[TMP30:%.*]] = inttoptr i64 [[TMP29]] to ptr +; CHECK-INLINE-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP30]], align 8 +; CHECK-INLINE-NEXT: [[TMP32:%.*]] = ptrtoint ptr [[TMP31]] to i64 +; CHECK-INLINE-NEXT: [[TMP33:%.*]] = icmp sge i64 [[TMP32]], 0 +; CHECK-INLINE-NEXT: [[TMP34:%.*]] = or i1 [[TMP28]], [[TMP33]] +; CHECK-INLINE-NEXT: [[TMP35:%.*]] = add i64 [[SHADOW_PTR_INT]], 24 +; CHECK-INLINE-NEXT: [[TMP36:%.*]] = inttoptr i64 [[TMP35]] to ptr +; CHECK-INLINE-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP36]], align 8 +; CHECK-INLINE-NEXT: [[TMP38:%.*]] = ptrtoint ptr [[TMP37]] to i64 +; CHECK-INLINE-NEXT: [[TMP39:%.*]] = icmp sge i64 [[TMP38]], 0 +; CHECK-INLINE-NEXT: [[TMP40:%.*]] = or i1 [[TMP34]], [[TMP39]] +; CHECK-INLINE-NEXT: br i1 [[TMP40]], label [[TMP41:%.*]], label [[TMP42:%.*]], !prof [[PROF0]] +; CHECK-INLINE: 41: +; CHECK-INLINE-NEXT: call void @__tysan_check(ptr [[A]], i32 4, ptr null, i32 2) +; CHECK-INLINE-NEXT: br label [[TMP42]] +; CHECK-INLINE: 42: +; CHECK-INLINE-NEXT: br label [[TMP43]] +; CHECK-INLINE: 43: +; CHECK-INLINE-NEXT: store i32 42, ptr [[A]], align 4 +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_store_unk( +; CHECK-OUTLINE-NEXT: entry: +; CHECK-OUTLINE-NEXT: [[APP_MEM_MASK:%.*]] = load i64, ptr @__tysan_app_memory_mask, align 8 +; CHECK-OUTLINE-NEXT: [[SHADOW_BASE:%.*]] = load i64, ptr @__tysan_shadow_memory_address, align 8 +; CHECK-OUTLINE-NEXT: call void @__tysan_instrument_with_shadow_update(ptr [[A:%.*]], ptr null, i1 true, i64 4, i32 2) +; CHECK-OUTLINE-NEXT: store i32 42, ptr [[A]], align 4 +; CHECK-OUTLINE-NEXT: ret void +; entry: store i32 42, ptr %a, align 4 ret void diff --git a/llvm/test/Instrumentation/TypeSanitizer/swifterror.ll b/llvm/test/Instrumentation/TypeSanitizer/swifterror.ll index dc83a020bc1a9..b4418586a4b91 100644 --- a/llvm/test/Instrumentation/TypeSanitizer/swifterror.ll +++ b/llvm/test/Instrumentation/TypeSanitizer/swifterror.ll @@ -1,7 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test basic type sanitizer instrumentation. ; -; RUN: opt -passes='tysan' -S %s | FileCheck %s +; RUN: opt -passes='tysan' -tysan-outline-instrumentation=false -S %s | FileCheck %s --check-prefix=CHECK-INLINE +; RUN: opt -passes='tysan' -S %s | FileCheck %s --check-prefix=CHECK-OUTLINE target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -9,6 +10,14 @@ define void @test_swifterror(ptr swifterror) sanitize_type { ; CHECK-LABEL: @test_swifterror( ; CHECK-NEXT: [[SWIFTERROR_PTR_VALUE:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 ; CHECK-NEXT: ret void +; +; CHECK-INLINE-LABEL: @test_swifterror( +; CHECK-INLINE-NEXT: [[SWIFTERROR_PTR_VALUE:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_swifterror( +; CHECK-OUTLINE-NEXT: [[SWIFTERROR_PTR_VALUE:%.*]] = load ptr, ptr [[TMP0:%.*]], align 8 +; CHECK-OUTLINE-NEXT: ret void ; %swifterror_ptr_value = load ptr, ptr %0 ret void @@ -18,6 +27,14 @@ define void @test_swifterror_2(ptr swifterror) sanitize_type { ; CHECK-LABEL: @test_swifterror_2( ; CHECK-NEXT: store ptr null, ptr [[TMP0:%.*]], align 8 ; CHECK-NEXT: ret void +; +; CHECK-INLINE-LABEL: @test_swifterror_2( +; CHECK-INLINE-NEXT: store ptr null, ptr [[TMP0:%.*]], align 8 +; CHECK-INLINE-NEXT: ret void +; +; CHECK-OUTLINE-LABEL: @test_swifterror_2( +; CHECK-OUTLINE-NEXT: store ptr null, ptr [[TMP0:%.*]], align 8 +; CHECK-OUTLINE-NEXT: ret void ; store ptr null, ptr %0 ret void From 88ce7ab26be208976b93bbb5b630b169fe522479 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Mon, 17 Nov 2025 14:35:16 +0000 Subject: [PATCH 7/9] Re-add reset changes --- clang/docs/TypeSanitizer.rst | 4 ---- clang/lib/Driver/SanitizerArgs.cpp | 4 ++++ llvm/docs/ReleaseNotes.md | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/docs/TypeSanitizer.rst b/clang/docs/TypeSanitizer.rst index fefa22954607a..5a98a2547aa87 100644 --- a/clang/docs/TypeSanitizer.rst +++ b/clang/docs/TypeSanitizer.rst @@ -187,10 +187,6 @@ Limitations shadow memory for each byte of user memory. * There are transformation passes which run before TypeSanitizer. If these passes optimize out an aliasing violation, TypeSanitizer cannot catch it. -* Currently, all instrumentation is inlined. This can result in a **15x** - (on average) increase in generated file size, and **3x** to **7x** increase - in compile time. In some documented cases this can cause the compiler to hang. - There are plans to improve this in the future. * Codebases that use unions and struct-initialized variables can see incorrect results, as TypeSanitizer doesn't yet instrument these reliably. * Since Clang & LLVM's TBAA system is used to generate the checks used by the diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 42acc0c6c64ec..5e92d329bd0dc 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1511,6 +1511,10 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-tysan-outline-instrumentation"); } + else{ + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tysan-outline-instrumentation=false"); + } // When emitting Stable ABI instrumentation, force outlining calls and avoid // inlining shadow memory poisoning. While this is a big performance burden diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 6f386b81476ac..e605ed55a5197 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -217,6 +217,8 @@ Changes to BOLT Changes to Sanitizers --------------------- +* TypeSanitizer no longer inlines all instrumentation by default + Other Changes ------------- From 61d9c1fdd22d69cfa63acebcf97120d65972dc4c Mon Sep 17 00:00:00 2001 From: gbMattN Date: Mon, 17 Nov 2025 14:40:04 +0000 Subject: [PATCH 8/9] Add more reset changes --- clang/docs/UsersManual.rst | 6 +++--- clang/include/clang/Driver/SanitizerArgs.h | 2 +- clang/include/clang/Options/Options.td | 2 +- clang/lib/Driver/SanitizerArgs.cpp | 6 +----- clang/test/CodeGen/sanitize-type-outlined.cpp | 19 ++++++++++++++++--- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 04da152bd0aff..d1f46cfd41a7a 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2280,9 +2280,9 @@ are listed below. .. option:: -f[no-]sanitize-type-outline-instrumentation Controls how type sanitizer code is generated. If enabled will always use - a function call instead of inlining the code. Turning this option on may - reduce the binary size and compilation overhead, but might result in a worse - run-time performance. + a function call instead of inlining the code. Turning this option off may + result in better run-time performance, but will increase binary size and + compilation overhead. See :doc: `TypeSanitizer` for more details. diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 4803ddecc6b9d..08e3c147d0557 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -67,7 +67,7 @@ class SanitizerArgs { bool TsanFuncEntryExit = true; bool TsanAtomics = true; bool MinimalRuntime = false; - bool TysanOutlineInstrumentation = false; + bool TysanOutlineInstrumentation = true; // True if cross-dso CFI support if provided by the system (i.e. Android). bool ImplicitCfiRuntime = false; bool NeedsMemProfRt = false; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index c8cfee88e94a9..ef569a5a6801a 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2464,7 +2464,7 @@ def fsanitize_type_outline_instrumentation : Flag<["-"], "fsanitize-type-outline HelpText<"Always generate function calls for type sanitizer instrumentation">; def fno_sanitize_type_outline_instrumentation : Flag<["-"], "fno-sanitize-type-outline-instrumentation">, Group, - HelpText<"Use default code inlining logic for the type sanitizer">; + HelpText<"Use code inlining logic for the type sanitizer">; defm sanitize_stable_abi : OptInCC1FFlag<"sanitize-stable-abi", "Stable ", "Conventional ", "ABI instrumentation for sanitizer runtime. Default: Conventional">; diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 5e92d329bd0dc..dbecdc191885c 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1507,11 +1507,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0"); } - if (TysanOutlineInstrumentation) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-tysan-outline-instrumentation"); - } - else{ + if (!TysanOutlineInstrumentation) { CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-tysan-outline-instrumentation=false"); } diff --git a/clang/test/CodeGen/sanitize-type-outlined.cpp b/clang/test/CodeGen/sanitize-type-outlined.cpp index 770327aa19921..9bbd5d519c6a6 100644 --- a/clang/test/CodeGen/sanitize-type-outlined.cpp +++ b/clang/test/CodeGen/sanitize-type-outlined.cpp @@ -1,16 +1,29 @@ // UNSUPPORTED: target={{.*}}-windows-{{.*}} +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ // RUN: -fsanitize-type-outline-instrumentation \ // RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE + // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ -// RUN: -fno-sanitize-type-outline-instrumentation \ -// RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE +// RUN: -fsanitize-type-outline-instrumentation \ +// RUN: -fsanitize-type-verify-outlined-instrumentation \ +// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE +// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: -fsanitize-type-verify-outlined-instrumentation \ +// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE -// CHECK-OUTLINE: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-LABEL: @alias +// CHECK: __tysan_app_memory_mask +// CHECK: __tysan_shadow_memory_address // CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-NO-OUTLINE-NOT: call{{.*}}@__tysan_instrument_with_shadow_update +// CHECK-OUTLINE: call{{.*}}@__tysan_instrument_mem_inst +// CHECK-OUTLINE: call{{.*}}@__tysan_instrument_with_shadow_update float alias(int *ptr){ float *aliasedPtr = (float *)ptr; + *aliasedPtr *= 2.0f; return *aliasedPtr; } From 3a9ddee2ac2d3889f1ab6794ac0c5696e7096c42 Mon Sep 17 00:00:00 2001 From: gbMattN Date: Mon, 17 Nov 2025 15:43:59 +0000 Subject: [PATCH 9/9] review comments and fix that one outline test --- clang/test/CodeGen/sanitize-type-outlined.cpp | 9 +-------- llvm/docs/ReleaseNotes.md | 4 +++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/clang/test/CodeGen/sanitize-type-outlined.cpp b/clang/test/CodeGen/sanitize-type-outlined.cpp index 9bbd5d519c6a6..64e0882aa1e1a 100644 --- a/clang/test/CodeGen/sanitize-type-outlined.cpp +++ b/clang/test/CodeGen/sanitize-type-outlined.cpp @@ -1,19 +1,12 @@ // UNSUPPORTED: target={{.*}}-windows-{{.*}} // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ +// RUN: -fno-sanitize-type-outline-instrumentation \ // RUN: | FileCheck %s --check-prefixes=CHECK-NO-OUTLINE // RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ // RUN: -fsanitize-type-outline-instrumentation \ // RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE -// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ -// RUN: -fsanitize-type-outline-instrumentation \ -// RUN: -fsanitize-type-verify-outlined-instrumentation \ -// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE -// RUN: %clang -S -fsanitize=type -emit-llvm -o - -fsanitize=type %s \ -// RUN: -fsanitize-type-verify-outlined-instrumentation \ -// RUN: | FileCheck %s --check-prefixes=CHECK-OUTLINE - // CHECK-LABEL: @alias // CHECK: __tysan_app_memory_mask // CHECK: __tysan_shadow_memory_address diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index e605ed55a5197..88f958641b31a 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -217,7 +217,9 @@ Changes to BOLT Changes to Sanitizers --------------------- -* TypeSanitizer no longer inlines all instrumentation by default +* TypeSanitizer no longer inlines all instrumentation by default. Added the + `-f[no-]sanitize-type-outline-instrumentation` flags to give users control + over this behaviour. Other Changes -------------