1612 Commits

Author SHA1 Message Date
Thurston Dang
fdadef9be3
[msan] Handle x86_avx512_(min|max)_p[sd]_512 intrinsics (#124421)
The AVX/SSE variants are already handled heuristically (maybeHandleSimpleNomemIntrinsic via handleUnknownIntrinsic), but the AVX512 variants contain an additional parameter (the rounding method) which fails to match heuristically. This patch generalizes maybeHandleSimpleNomemIntrinsic to allow additional flags (ignored by MSan) and explicitly call it to handle AVX512 min/max ps/pd intrinsics.

It also updates the test added in https://github.com/llvm/llvm-project/pull/123980
2025-01-28 19:12:44 -08:00
Thurston Dang
b8cdc5ea27
Reapply "[msan] Add avx512-intrinsics.ll and avx512-intrinsics-upgrade.ll test case (#123980)" (#124500)
This reverts commit b2647ffbf797dd5a457b6b19faab06956934d067 i.e.,
relands 980e86f130.

I had reverted the original patch because of buildbot failures (e.g., https://lab.llvm.org/buildbot/#/builders/13/builds/4938/steps/5/logs/FAIL__LLVM__avx512-intrinsics-upgrade_ll). This reland addresses the likely root cause; namely, that the target datalayout had not been specified.

Additionally, this reland improves the test case by replacing undef with extra parameters.
2025-01-28 15:29:21 -08:00
Thurston Dang
4a426079d6
[msan] Use horizontal add to compute shadow for horizontal sub (#124835)
This improves the horizontal sub handling (from
https://github.com/llvm/llvm-project/pull/124159), by always using
horizontal add for the shadow, as recommended by Vitaly.

Fixes https://github.com/llvm/llvm-project/issues/124662
2025-01-28 14:56:05 -08:00
Thurston Dang
063db51cd4 Reapply "[msan] Add handlers for AVX masked load/store intrinsics (#123857)"
This reverts commit b9d301cc7e4fe4c442ec15169686fa4a18f5cdfc i.e.,
relands db79fb2a91df31a07f312f8e061936927ac5c506.

I had mistakenly thought this caused a buildbot breakage (the actual
culprit was my other patch,
https://github.com/llvm/llvm-project/pull/123980, which landed at the
same time) and thus had reverted it even though AFAIK it is not broken.
2025-01-28 18:11:44 +00:00
Thurston Dang
ef92e6b99f
[BoundsChecking] Update ubsantrap to use GuardKind (#124613)
This change makes it consistent with other uses of ubsantrap.

This also updates the tests. Notably, BoundsChecking/runtimes.ll had guard=3 which passed only because the method of calculating the parameter (`IRB.GetInsertBlock()->getParent()->size()`) happened to give the same answer.
2025-01-28 08:52:31 -08:00
Thurston Dang
b2647ffbf7 Revert "[msan] Add avx512-intrinsics.ll and avx512-intrinsics-upgrade.ll test case (#123980)"
This reverts commit 980e86f130eea02bd41b887f4ed896340fc90f6c.

Reason: buildbot breakage
(https://lab.llvm.org/buildbot/#/builders/154/builds/10901/steps/5/logs/FAIL__LLVM__avx512-intrinsics-upgrade_ll)
2025-01-27 01:35:32 +00:00
Thurston Dang
b6eeec586f Revert "[msan] Fix-forward avx512-intrinsics-upgrade.ll (#124495)"
This reverts commit a6044a05cd16d2c5dbca80757a160cba9a2cb037.

Reason: buildbot breakage
(https://lab.llvm.org/buildbot/#/builders/144/builds/16636/steps/6/logs/FAIL__LLVM__avx512-intrinsics-upgrade_ll)
2025-01-27 01:10:51 +00:00
Thurston Dang
b9d301cc7e Revert "[msan] Add handlers for AVX masked load/store intrinsics (#123857)"
This reverts commit db79fb2a91df31a07f312f8e061936927ac5c506.

Reason: buildbot breakage
(https://lab.llvm.org/buildbot/#/builders/144/builds/16636/steps/6/logs/FAIL__LLVM__avx512-intrinsics-upgrade_ll)
2025-01-27 01:10:35 +00:00
Thurston Dang
a6044a05cd
[msan] Fix-forward avx512-intrinsics-upgrade.ll (#124495)
I had added the test in https://github.com/llvm/llvm-project/pull/123980
and contemporaneously added AVX masked store/load intrinsics
(https://github.com/llvm/llvm-project/pull/123857) and forgot to update
the test output for the intersection. This patch fixes the output.
2025-01-26 16:59:34 -08:00
Thurston Dang
980e86f130
[msan] Add avx512-intrinsics.ll and avx512-intrinsics-upgrade.ll test case (#123980)
These are forked from the corresponding files in llvm/test/CodeGen/X86/.

avx512-intrinsics.ll shows that many intrinsics are already
heuristically handled by MSan, and can be used to track refinements to
the intrinsic handling.

avx512-intrinsics-upgrade.ll tests intrinsics that LLVM "auto-upgrades";
for example, @llvm.x86.avx512.mask.store is converted into
@llvm.masked.store (which has the interesting side effect that
MemorySanitizer can already handle it via its existing
handleMaskedStore).
2025-01-26 16:04:30 -08:00
Thurston Dang
db79fb2a91
[msan] Add handlers for AVX masked load/store intrinsics (#123857)
This patch adds explicit support for AVX masked load/store intrinsics,
largely by applying the intrinsics to the shadows (but subtly different
to handleIntrinsicByApplyingToShadow()).

We do not reuse the handleMaskedLoad/Store functions. The key challenge
is that the LLVM masked intrinsics require a vector of booleans, while
AVX masked intrinsics use the MSBs of a vector of integers.
X86InstCombineIntrinsic.cpp::simplifyX86MaskedLoad mentions that the x86
backend does not know how to efficiently convert from a vector of
booleans back into the AVX mask format; therefore, they (and we) do not
reduce AVX masked intrinsics into LLVM masked intrinsics.
2025-01-26 15:40:55 -08:00
Thurston Dang
8ef171ee83
[msan] Handle horizontal add/subtract intrinsic by applying to shadow (#124159)
Horizontal add (hadd) and subtract (hsub) are currently heuristically
handled by `maybeHandleSimpleNomemIntrinsic()` (via
`handleUnknownIntrinsic()`), which computes the shadow by bitwise OR'ing
the two operands. This has false positives for hadd/hsub shadows. For
example, suppose the shadows for the two operands are 00000000 and
11111111 respectively. The expected shadow for the result is 00001111,
but `maybeHandleSimpleNomemIntrinsic` would compute it as 11111111.

This patch handles horizontal add using
`handleIntrinsicByApplyingToShadow` (from
https://github.com/llvm/llvm-project/pull/114490), which has no false
positives for hadd/hsub: if each pair of adjacent shadow values is zero
(fully initialized), the result will be zero (fully initialized). More
generally, it is precise for hadd/hsub if at least one of the two
adjacent shadow values in each pair is zero.

It does have some false negatives for hadd/hsub: if we add/subtract two
adjacent non-zero shadow values, some bits of the result may incorrectly
be zero. We consider this an acceptable tradeoff for performance. To
make shadow propagation precise, we want the equivalent of "horizontal
OR", but this is not available. Reducing horizontal OR to (permutation
plus bitwise OR) is left as an exercise for the reader.
2025-01-23 22:53:56 -08:00
Vitaly Buka
1a7d46fac8
[BoundsChecking] Add guard= pass parameter (#122575)
And use that as an argument for
allow_ubsan_check when needed.

Other ubsan checks use SanitizerKind,
but those are known to the clang only.

So make it a parameter in LLVM.
2025-01-13 09:36:41 -08:00
Mingjie Xu
876fa60f08
[TySan] Skip instrumentation for function declarations (#122488)
Skip function declarations for instrumentation.

Fixes https://github.com/llvm/llvm-project/issues/122467
2025-01-11 20:15:21 +08:00
Vitaly Buka
8af4d206e0
[NFCI][BoundsChecking] Apply nosanitize on local-bounds instrumentation (#122416)
Should be NFCI as we run sanitizer, like msan, before local-bounds.
2025-01-10 18:11:19 -08:00
Thurston Dang
4f42e16516
[hwasan] Omit tag check for null pointers (#122206)
If the pointer to be checked is statically known to be zero, the tag
check will always pass since:
1) the tag is zero
2) shadow memory for address 0 is initialized to 0 and never updated.
We can therefore elide the tag check.

We perform the elision in two places:
1) the HWASan pass
2) when lowering the CHECK_MEMACCESS intrinsic. Conceivably, the HWASan
pass may encounter a "cannot currently statically prove to be null"
pointer (and is therefore unable to omit the intrinsic) that later
optimization passes convert into a statically known-null pointer. As a
last line of defense, we perform elision here too.

This also updates the tests from
https://github.com/llvm/llvm-project/pull/122186
2025-01-09 13:48:26 -08:00
Vitaly Buka
a7cbd41000
[BoundsChecking][test] Remove duplicate RUNS
Fixing failed conflict resolution in #122229.
2025-01-09 09:00:50 -08:00
Vitaly Buka
89499c6668
[BoundsChecking][test] Reorder RUN lines (#122229)
To match output order of update_test_checks.py.
2025-01-09 08:59:05 -08:00
Thurston Dang
b48b99f625
[hwasan] Add test case for null pointer dereference (#122186)
This shows that HWASan will emit a memaccess intrinsic for null pointer
dereferences, with or without a fixed shadow.

This is a simplification of an internal bug report by dvyukov.
2025-01-08 15:23:49 -08:00
Mingjie Xu
2a1632824d
[tysan] Convert TySan from function+module pass to just module pass (#120667)
As mentioned in https://github.com/llvm/llvm-project/pull/118989, all
sanitizers but tsan are converted to just module pass for easier
maintenance.

This patch removes the TySan function pass, convert TySan from
function+module pass to just module pass.
2025-01-08 11:25:32 +08:00
Thurston Dang
5bb650345d
Remove -bounds-checking-unique-traps (replace with -fno-sanitize-merge=local-bounds) (#120682)
#120613 removed -ubsan-unique-traps and replaced it with
-fno-sanitize-merge (introduced in #120511), which allows fine-grained
control of which UBSan checks to prevent merging. This analogous patch
removes -bound-checking-unique-traps, and allows it to be controlled via
-fno-sanitize-merge=local-bounds.

Most of this patch is simply plumbing through the compiler flags into
the bounds checking pass.

Note: this patch subtly changes -fsanitize-merge (the default) to also
include -fsanitize-merge=local-bounds. This is different from the
previous behavior, where -fsanitize-merge (or the old
-ubsan-unique-traps) did not affect local-bounds (requiring the separate
-bounds-checking-unique-traps). However, we argue that the new behavior
is more intuitive.

Removing -bounds-checking-unique-traps and merging its functionality
into -fsanitize-merge breaks backwards compatibility; we hope that this
is acceptable since '-mllvm -bounds-checking-unique-traps' was an
experimental flag.
2024-12-20 10:07:44 -08:00
Vitaly Buka
3d297514e2
[BoundsChecking] Add support for runtime handlers (#120513)
This is a step forward to have reporting consistent with other UBSAN
checks.

Runtime and clang parts are here #120515.
2024-12-19 16:24:02 -08:00
Philip Reames
0517772b4a Delete unused PoisonChecking utility pass
This was introduced ~5yrs ago (by me), and has never really gotten
any adoption.  By now, it's significantly out of sync with new/changed
poison propoagation rules.  The idea is still reasonable, but the
imagined use case is largely covered by alive2 these days anyways.
2024-12-19 14:23:38 -08:00
Vitaly Buka
55e87a79b9
[BoundsChecking] Add parameters to pass (#119894)
This check is a part of UBSAN, but does not support
verbose output like other UBSAN checks.

This is a step to fix that.
2024-12-17 22:07:14 -08:00
Florian Hahn
a487b792e2
[TySan] Add initial Type Sanitizer (LLVM) (#76259)
This patch introduces the LLVM components of a type sanitizer: a
sanitizer for type-based aliasing violations.

It is based on Hal Finkel's https://reviews.llvm.org/D32198.

C/C++ have type-based aliasing rules, and LLVM's optimizer can exploit
these given TBAA metadata added by Clang. Roughly, a pointer of given
type cannot be used to access an object of a different type (with, of
course, certain exceptions). Unfortunately, there's a lot of code in the
wild that violates these rules (e.g. for type punning), and such code
often must be built with -fno-strict-aliasing. Performance is often
sacrificed as a result. Part of the problem is the difficulty of finding
TBAA violations. Hopefully, this sanitizer will help.

For each TBAA type-access descriptor, encoded in LLVM's IR using
metadata, the corresponding instrumentation pass generates descriptor
tables. Thus, for each type (and access descriptor), we have a unique
pointer representation. Excepting anonymous-namespace types, these
tables are comdat, so the pointer values should be unique across the
program. The descriptors refer to other descriptors to form a type
aliasing tree (just like LLVM's TBAA metadata does). The instrumentation
handles the "fast path" (where the types match exactly and no
partial-overlaps are detected), and defers to the runtime to handle all
of the more-complicated cases. The runtime, of course, is also
responsible for reporting errors when those are detected.

The runtime uses essentially the same shadow memory region as tsan, and
we use 8 bytes of shadow memory, the size of the pointer to the type
descriptor, for every byte of accessed data in the program. The value 0
is used to represent an unknown type. The value -1 is used to represent
an interior byte (a byte that is part of a type, but not the first
byte). The instrumentation first checks for an exact match between the
type of the current access and the type for that address recorded in the
shadow memory. If it matches, it then checks the shadow for the
remainder of the bytes in the type to make sure that they're all -1. If
not, we call the runtime. If the exact match fails, we next check if the
value is 0 (i.e. unknown). If it is, then we check the shadow for the
remainder of the byes in the type (to make sure they're all 0). If
they're not, we call the runtime. We then set the shadow for the access
address and set the shadow for the remaining bytes in the type to -1
(i.e. marking them as interior bytes). If the type indicated by the
shadow memory for the access address is neither an exact match nor 0, we
call the runtime.

The instrumentation pass inserts calls to the memset intrinsic to set
the memory updated by memset, memcpy, and memmove, as well as
allocas/byval (and for lifetime.start/end) to reset the shadow memory to
reflect that the type is now unknown. The runtime intercepts memset,
memcpy, etc. to perform the same function for the library calls.

The runtime essentially repeats these checks, but uses the full TBAA
algorithm, just as the compiler does, to determine when two types are
permitted to alias. In a situation where access overlap has occurred and
aliasing is not permitted, an error is generated.

Clang's TBAA representation currently has a problem representing unions,
as demonstrated by the one XFAIL'd test in the runtime patch. We'll
update the TBAA representation to fix this, and at the same time, update
the sanitizer.

When the sanitizer is active, we disable actually using the TBAA
metadata for AA. This way we're less likely to use TBAA to remove memory
accesses that we'd like to verify.

As a note, this implementation does not use the compressed shadow-memory
scheme discussed previously
(http://lists.llvm.org/pipermail/llvm-dev/2017-April/111766.html). That
scheme would not handle the struct-path (i.e. structure offset)
information that our TBAA represents. I expect we'll want to further
work on compressing the shadow-memory representation, but I think it
makes sense to do that as follow-up work.

It goes together with the corresponding clang changes
(https://github.com/llvm/llvm-project/pull/76260) and compiler-rt
changes (https://github.com/llvm/llvm-project/pull/76261)

PR: https://github.com/llvm/llvm-project/pull/76259
2024-12-17 13:57:34 +00:00
Chris Apple
4a65861402
[rtsan][llvm] Remove function pass, only support module pass (#119739)
Most of the other sanitizers are now only module level passes. This
moves all functionality into the module pass, and removes the function
pass.
2024-12-13 08:50:36 -08:00
Alexander Shaposhnikov
3791323343
[msan] Add support for avx_round_pd_256/avx_round_ps_256 (#119334)
Add support for avx_round_pd_256/avx_round_ps_256.
This is a follow-up to https://github.com/llvm/llvm-project/pull/118441

Test plan:
ninja check-all
2024-12-09 23:27:34 -08:00
Thurston Dang
3b74abdf04
[msan] Support NEON vector multiplication instructions (#117944)
Approximates the shadow propagation via OR'ing.

Updates the neon_vmul.ll test introduced in
https://github.com/llvm/llvm-project/pull/117935
2024-12-09 11:39:29 -08:00
Alexander Richardson
4646cabf01
[SanitizerCoverage] Avoid unnecessary inttoptr
We are indexing into an array here, so we can use
CreateConstInBoundsGEP2_64 instead of the manual arithmetic.

Reviewed By: vitalybuka

Pull Request: https://github.com/llvm/llvm-project/pull/119097
2024-12-09 09:19:13 -08:00
Thurston Dang
4228a6ef2b
[msan] Add test for Arm NEON vmul (#117935) 2024-12-08 19:53:40 -08:00
Vitaly Buka
118f7b95c8
[sancov] Regenerate test (#119115)
For #119097.
2024-12-07 21:12:22 -08:00
Chris Apple
ca3180ad6e
[LLVM][rtsan] Add module pass to initialize rtsan (#118989)
This allows shared libraries instrumented with RTSan to be initialized.

This approach directly mirrors the approach in Tsan, Asan and many of
the other sanitizers
2024-12-06 11:29:11 -08:00
Ellis Hoag
2e33ed9ecc
[memprof] Use -memprof-runtime-default-options to set options during compile time (#118874)
Add the `__memprof_default_options_str` variable, initialized via the
`-memprof-runtime-default-options` LLVM flag, to hold the default options string
for memprof. This allows us to set these options during compile time in
the clang invocation.

Also update the docs to describe the various ways to set these options.
2024-12-06 09:22:16 -08:00
Alexander Shaposhnikov
95e44d3670
[msan] Add handling for sse41_round_pd/sse41_round_ps (#118441)
Add handling for sse41_round_pd/sse41_round_ps similarly to
maybeHandleSimpleNomemIntrinsic.

Test plan: ninja check-all
2024-12-04 08:27:08 -08:00
serge-sans-paille
19ddafafdf
[llvm] Fix ObjectSizeOffsetVisitor behavior in exact mode upon negati… (#116955)
…ve offset

In Exact mode, the approximation of returning (0,0) is invalid. It only
holds in min/max mode.
2024-11-23 07:38:37 +00:00
Paul Walker
56c091ea71
[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
This brings the printing of scalable vector constant splats inline with
their fixed length counterparts.
2024-11-21 11:21:12 +00:00
k-kashapov
d9e2fb70d0
[msan] Add 32-bit platforms support (#109284)
References https://github.com/llvm/llvm-project/issues/103057

Added `VAArgHelper` functions for platforms: ARM32, i386, RISC-V,
PowerPC32, MIPS32.

ARM, RISCV and MIPS share similar conventions regarding va args.
Therefore `VAArgGenericHelper` was introduced to avoid code duplication.

---------

Co-authored-by: Kamil Kashapov <kashapov@ispras.ru>
Co-authored-by: Vitaly Buka <vitalybuka@google.com>
2024-11-14 01:41:13 -08:00
Vitaly Buka
debfd7b0b4
[msan] Remove unnecacary zero increment (#116185) 2024-11-14 00:59:01 -08:00
Vitaly Buka
49e004fbe0
[nfc][msan] Regenerate tests missing FileCheck (#115794)
Extracted and updated from #115018

Co-authored-by: Kamil Kashapov <kashapov@ispras.ru>
2024-11-11 16:40:02 -08:00
Paul Walker
38fffa630e
[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548) 2024-11-06 11:53:33 +00:00
k-kashapov
8251754e3a
[MSan] Update 32-bit test checks (#112401)
* As suggested in
https://github.com/llvm/llvm-project/pull/111835#discussion_r1800179290,
ran llvm/utils/update_test_checks.py on all the copied tests.
* Target triple is still unchanged

---------

Co-authored-by: Kamil Kashapov <kashapov@ispras.ru>
Co-authored-by: Vitaly Buka <vitalybuka@gmail.com>
2024-11-03 19:24:17 -08:00
Thurston Dang
e549ec529c
[msan] Add handleIntrinsicByApplyingToShadow; support NEON tbl/tbx (#114490)
This adds a general function that handles intrinsics by applying the
intrinsic to the shadows, and applies it to the specific case of Arm
NEON TBL/TBX intrinsics.

This also updates the tests from
https://github.com/llvm/llvm-project/pull/114462
2024-11-01 14:58:45 -07:00
Thurston Dang
84f5c8571d
[msan] Add test for Arm NEON tbl intrinsics (#114462)
Arm NEON tbl intrinsics are currently not instrumented properly by MSan.
This test will help track progress.
2024-10-31 16:45:01 -07:00
davidtrevelyan
4102625380
[rtsan][llvm][NFC] Rename sanitize_realtime_unsafe attr to sanitize_realtime_blocking (#113155)
# What

This PR renames the newly-introduced llvm attribute
`sanitize_realtime_unsafe` to `sanitize_realtime_blocking`. Likewise,
sibling variables such as `SanitizeRealtimeUnsafe` are renamed to
`SanitizeRealtimeBlocking` respectively. There are no other functional
changes.


# Why?

- There are a number of problems that can cause a function to be
real-time "unsafe",
- we wish to communicate what problems rtsan detects and *why* they're
unsafe, and
- a generic "unsafe" attribute is, in our opinion, too broad a net -
which may lead to future implementations that need extra contextual
information passed through them in order to communicate meaningful
reasons to users.
- We want to avoid this situation and make the runtime library boundary
API/ABI as simple as possible, and
- we believe that restricting the scope of attributes to names like
`sanitize_realtime_blocking` is an effective means of doing so.

We also feel that the symmetry between `[[clang::blocking]]` and
`sanitize_realtime_blocking` is easier to follow as a developer.

# Concerns

- I'm aware that the LLVM attribute `sanitize_realtime_unsafe` has been
part of the tree for a few weeks now (introduced here:
https://github.com/llvm/llvm-project/pull/106754). Given that it hasn't
been released in version 20 yet, am I correct in considering this to not
be a breaking change?
2024-10-26 13:06:11 +01:00
Vitaly Buka
cf8d24531e
[msan] Reduces overhead of #113200, by 10% (#113201)
CTMark #113200 size overhead was 5.3%, now it's 4.7%.

The patch affects only signed integers.

https://alive2.llvm.org/ce/z/Lv5hyi

* The patch replaces code which extracted sign bit,
maximized/minimized it, then packed it back, with
simple sign bit flip. The another way to think about
transformation is as a subtraction of MIN_SINT from
A/B. Then we map MIN_SINT to 0, 0 to -MIN_SINT, and
MAX_SINT to MAX_UINT.

* Then to maximize/minimize A/B we don't need
to extract sign bit, we can apply shadow the
same way as to other bits.

* After sign bit flip, we had to switch to unsigned
version of the predicates.

* After change above  getHighestPossibleValue/getLowestPossibleValue
became very similar, so we can combine into a single function.

* Because the function does sign bit flip and
requires unsigned predicates used for returned values,
there is no point in keeping it as a member of class,
to hide, we switch to function local lambda.
2024-10-24 20:46:49 -07:00
Vitaly Buka
c77d8edf80
Revert "Revert "[msan] Switch to -msan-handle-icmp-exact my default"" (#113379)
Reverts llvm/llvm-project#113376

Fixed with #113378
2024-10-22 14:05:35 -07:00
Vitaly Buka
c3aa8b7dd6
Revert "[msan] Switch to -msan-handle-icmp-exact my default" (#113376)
Reverts llvm/llvm-project#113200

Breaks bots, see llvm/llvm-project#113200
2024-10-22 13:05:59 -07:00
Vitaly Buka
395093ec15
[msan] Switch to -msan-handle-icmp-exact my default (#113200)
Fixes #111212.

This grows .text by 5.3% on CTMark, (or 2.6% large internal binary)
Perf regressed by 1.6%. We will try to improve in follow up patches.

It worth to pay some performance regression to fix
correctness to avoid stuff like #111212.
2024-10-22 12:35:18 -07:00
Vitaly Buka
54cf62d19d
[nfc][msan] Generate test with update_test_checks.py (#113199)
PR is to:
1. Simplify test update in #113200
2. Make tests more comprehensive, currently interesting cases looks very
basic:

```
; CHECK-LABEL: @ICmpSGTAllOnes
; CHECK: icmp slt
; CHECK-NOT: call void @__msan_warning
; CHECK: icmp sgt
; CHECK-NOT: call void @__msan_warning
; CHECK: ret i1
```
2024-10-22 12:33:58 -07:00
Paul Walker
5bb34803a4 [NFC] Migrate tests to use autoupdate for CHECK lines. 2024-10-22 12:55:15 +00:00