282 Commits

Author SHA1 Message Date
serge-sans-paille
f5e4ffaa49
Revert "[llvm] Use computeConstantRange to improve llvm.objectsize computation (#114673)"
This reverts commit 5f342816efe1854333f2be41a03fdd25fa0db433.

This seems to break various builders, such as

https://lab.llvm.org/buildbot/#/builders/41/builds/3259
https://lab.llvm.org/buildbot/#/builders/76/builds/4298
2024-11-07 13:40:50 +01:00
serge-sans-paille
5f342816ef
[llvm] Use computeConstantRange to improve llvm.objectsize computation (#114673)
Using LazyValueInfo, it is possible to compute valuable information for
allocation functions, GEP and alloca, even in the presence of dynamic
information.

llvm.objectsize plays an important role in _FORTIFY_SOURCE definitions,
so improving its diagnostic in turns improves the security of compiled
application.

As a side note, as a result of recent optimization improvements, clang
no longer passes
https://github.com/serge-sans-paille/builtin_object_size-test-suite This
commit restores the situation and greatly improves the scope of code
handled by the static version of __builtin_object_size.
2024-11-07 09:01:14 +00:00
Kazu Hirata
236fda550d
[Analysis] Remove unused includes (NFC) (#114936)
Identified with misc-include-cleaner.
2024-11-05 19:11:34 -08:00
serge-sans-paille
01a103b0b9
[llvm] Fix __builtin_object_size interaction between Negative Offset … (#111827)
…and Select/Phi

When picking a SizeOffsetAPInt through combineSizeOffset, the behavior
differs if we're going to apply a constant offset that's positive or
negative: If it's positive, then we need to compare the remaining bytes
(i.e. Size
- Offset), but if it's negative, we need to compare the preceding bytes
(i.e. Offset).

Fix #111709
2024-11-02 09:14:35 +00:00
Nikita Popov
255a99c29f
[APInt] Fix APInt constructions where value does not fit bitwidth (NFCI) (#80309)
This fixes all the places that hit the new assertion added in
https://github.com/llvm/llvm-project/pull/106524 in tests. That is,
cases where the value passed to the APInt constructor is not an N-bit
signed/unsigned integer, where N is the bit width and signedness is
determined by the isSigned flag.

The fixes either set the correct value for isSigned, set the
implicitTrunc flag, or perform more calculations inside APInt.

Note that the assertion is currently still disabled by default, so this
patch is mostly NFC.
2024-10-17 08:48:08 +02:00
Nikita Popov
53c41f95db [MemoryBuiltins] Use getAllOnesValue()
Split out from https://github.com/llvm/llvm-project/pull/80309.
2024-08-13 15:04:23 +02:00
Nikita Popov
5bc1f9e5b0 [MemoryBuiltins] Simplify getCalledFunction() helper (NFC)
If nobuiltin is set, directly return nullptr instead of using a
separate out parameter and having all callers check this.
2024-08-09 15:46:31 +02:00
Nikita Popov
195362929c [MemoryBuiltins] Handle allocator attributes on call-site
We should handle allocator attributes not only on function
declarations, but also on the call-site. That way we can e.g.
also optimize cases where the allocator function is a virtual
function call.

This was already supported in some of the MemoryBuiltins helpers,
but not all of them. This adds support for allocsize, alloc-family
and allockind("free").
2024-08-09 15:22:54 +02:00
Nikita Popov
2d209d964a
[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)
This is a helper to avoid writing `getModule()->getDataLayout()`. I
regularly try to use this method only to remember it doesn't exist...

`getModule()->getDataLayout()` is also a common (the most common?)
reason why code has to include the Module.h header.
2024-06-27 16:38:15 +02:00
Stephen Tozer
d75f9dd1d2 Revert "[IR][NFC] Update IRBuilder to use InsertPosition (#96497)"
Reverts the above commit, as it updates a common header function and
did not update all callsites:

  https://lab.llvm.org/buildbot/#/builders/29/builds/382

This reverts commit 6481dc57612671ebe77fe9c34214fba94e1b3b27.
2024-06-24 18:00:22 +01:00
Stephen Tozer
6481dc5761
[IR][NFC] Update IRBuilder to use InsertPosition (#96497)
Uses the new InsertPosition class (added in #94226) to simplify some of
the IRBuilder interface, and removes the need to pass a BasicBlock
alongside a BasicBlock::iterator, using the fact that we can now get the
parent basic block from the iterator even if it points to the sentinel.
This patch removes the BasicBlock argument from each constructor or call
to setInsertPoint.

This has no functional effect, but later on as we look to remove the
`Instruction *InsertBefore` argument from instruction-creation
(discussed
[here](https://discourse.llvm.org/t/psa-instruction-constructors-changing-to-iterator-only-insertion/77845)),
this will simplify the process by allowing us to deprecate the
InsertPosition constructor directly and catch all the cases where we use
instructions rather than iterators.
2024-06-24 17:27:43 +01:00
Vitaly Buka
43a38e2759
[BoundsChecking] Handle vscale allocas (#90926) 2024-05-02 19:13:14 -07:00
Bill Wendling
fc6b5666db
[NFC][ObjectSizeOffset] Use classes instead of std::pair (#76882)
The use of std::pair makes the values it holds opaque. Using classes
improves this while keeping the POD aspect of a std::pair. As a nice
addition, the "known" functions held inappropriately in the Visitor
classes can now properly reside in the value classes. :-)
2024-01-05 18:08:53 -08:00
Nikita Popov
180eae1f1e [MemoryBuiltins] Simplify getAllocFnKind() implementation (NFC) 2023-10-19 16:35:02 +02:00
Arthur Eubanks
cf7eac9650
[ObjectSizeOffsetVisitor] Bail after visiting 100 instructions (#67479)
We're running into stack overflows for huge functions with lots of phis.
Even without the stack overflows, this is recursing >7000 in some
auto-generated code.

This fixes the stack overflow and brings down the compile time to
something reasonable.
2023-09-27 14:54:41 +02:00
Arthur Eubanks
0944eea823 [NFC][ObjectSizeOffsetVisitor] Remove redundant equality check
Originally suggested in https://reviews.llvm.org/D131001 but I accidentally took only have of the suggestion.
2023-09-22 13:15:22 -07:00
Bevin Hansson
e412697451
[MemoryBuiltins] Cache the result of ObjectOffsetSizeVisitor::visit. #64796 (#65326)
visit will skip visiting instructions it already has visited
to avoid issues with cycles in the data graph. However,
the result of this skipping behavior is that if we
encounter the same instruction twice, and that instruction
has a well defined result and isn't part of a cycle, we
will introduce unknowns into the analysis even though we
knew the size and offset of the instruction's result.

Instead of skipping such instructions, keep a cache of
the result of visiting them. This result is initialized
to unknown() before visiting, so if we happen to visit
it again recursively (perhaps as the result of a cycle
or a phi), we will get unknown as the cached result and
exit out.
2023-09-15 10:30:45 +02:00
Jeremy Morse
e54277fa10 [NFC][RemoveDIs] Use iterators over inst-pointers when using IRBuilder
This patch adds a two-argument SetInsertPoint method to IRBuilder that
takes a block/iterator instead of an instruction, and updates many call
sites to use it. The motivating reason for doing this is given here [0],
we'd like to pass around more information about the position of debug-info
in the iterator object. That necessitates passing iterators around most of
the time.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152468
2023-09-11 20:01:19 +01:00
Anshil Gandhi
e578b3be24 [InstSimplify] Fold all global variables with initializers
Allow computing size of interposable or externally initializable global variables.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D152145
2023-07-03 15:11:41 -06:00
Nikita Popov
8762f4c748 [InstCombine] Track inserted instructions when lowering objectsize
The inserted instructions can usually be simplified. Make sure this
happens in the same InstCombine iteration by adding them to the
worklist.

We happen to get some better optimization in two cases, but this is
just a lucky accident. https://github.com/llvm/llvm-project/issues/63472
tracks implementing a fold for that case.

This doesn't track all inserted instructions yet, for that we would
also have to include those created by ObjectSizeOffsetEvaluator.
2023-06-23 15:36:23 +02:00
Alan Zhao
3d5cf0df4f Revert "[InstSimplify] Fold all global variables with initializers"
This reverts commit 17b7df3daee85c1a4d1d955e558d42b34ce17549.

Reason: causes chrome builds to crash: https://crbug.com/1454861
2023-06-14 14:10:31 -07:00
Anshil Gandhi
17b7df3dae [InstSimplify] Fold all global variables with initializers
Allow computing size of interposable or externally initializable global variables.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D152145
2023-06-13 15:15:19 -06:00
Nikita Popov
1379127481 [MemoryBuiltins] Handle phi nodes without operands (PR63013)
Conservatively return unknown in this degenerate case. This is
hard to hit in practice, because such phis are usually optimized
away before they reach a getObjectSize() call.

Fixes https://github.com/llvm/llvm-project/issues/63013.
2023-05-31 10:47:15 +02:00
Teresa Johnson
39f7b48671 [MemProf] Use updated version of hot/cold operator new
Switch to the just updated versions of the API in tcmalloc that change
the name of the hot cold paramter to a reserved identifier __hot_cold_t.
This was based on feedback from Richard Smith, as I also need to add
some follow-on handling to clang so they are annotated properly.

Differential Revision: https://reviews.llvm.org/D149475
2023-04-28 13:35:46 -07:00
Teresa Johnson
a35206d782 [MemProf] Optionally pass hot/cold hints to operator new
Optionally (off by default) replace operator new() calls marked with a
hot or cold memprof attribute with an operator new() call that takes a
hot_cold_t parameter.

Currently this is supported by the open source version of tcmalloc, see:
https://github.com/google/tcmalloc/blob/master/tcmalloc/new_extension.h

Differential Revision: https://reviews.llvm.org/D148718
2023-04-19 13:33:46 -07:00
Krzysztof Drewniak
916425b2d1 [llvm] Use pointer index type for more GEP offsets (pre-codegen)
Many uses of getIntPtrType() were using that type to calculate the
neened type for GEP offset arguments. However, some time ago,
DataLayout was extended to support pointers where the size of the
pointer is not equal to the size of the values used to index it.

Much code was already migrated to, for example, use getIndexSizeInBits
instead of getPtrSizeInBits, but some rewrites still used
getIntPtrType() to get the type for GEP offsets.

This commit changes uses of getIntPtrType() to getIndexType() where
they are involved in a GEP-related calculation.

In at least one case (bounds check insertion) this resolves a compiler
crash that the new test added here would previously trigger.

This commit does not impact
- C library-related rewriting (memcpy()), which are operating under
the assumption that intptr_t == size_t. While all the mechanisms for
breaking this assumption now exist, doing so is outside the scope of
this commit.
- Code generation and below. Note that the use of getIntPtrType() in
CodeGenPrepare will be changed in a future commit.
- Usage of getIntPtrType() in any backend

Depends on D143435

Reviewed By: arichardson

Differential Revision: https://reviews.llvm.org/D143437
2023-03-28 16:41:02 +00:00
Guillaume Chatelet
48f5d77eee [NFC] Use TypeSize::getKnownMinValue() instead of TypeSize::getKnownMinSize()
This change is one of a series to implement the discussion from
https://reviews.llvm.org/D141134.
2023-01-11 16:36:39 +00:00
Benjamin Kramer
a3d58bbaff Detemplate llvm::EmitGEPOffset and move it into a cpp file. NFC. 2022-12-29 16:24:21 +01:00
Fangrui Song
2fa744e631 std::optional::value => operator*/operator->
value() has undesired exception checking semantics and calls
__throw_bad_optional_access in libc++. Moreover, the API is unavailable without
_LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).

This commit fixes LLVMAnalysis and its dependencies.
2022-12-16 22:44:08 +00:00
Kazu Hirata
6eb0b0a045 Don't include Optional.h
These files no longer use llvm::Optional.
2022-12-14 21:16:22 -08:00
Fangrui Song
d4b6fcb32e [Analysis] llvm::Optional => std::optional 2022-12-14 07:32:24 +00:00
Kazu Hirata
e5ef6aced2 [Analysis] Use std::optional in MemoryBuiltins.cpp (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-11 01:32:26 -08:00
Alex Richardson
e96ddad85c [MemoryBuiltins] Avoid comparing against Type::getInt8PtrTy(0)
This does not make sense with opaque pointers, and also caused issues for
CHERI/Morello where hardcoding address-space zero prevented optimization.

Downstream change: https://git.morello-project.org/morello/llvm-project/-/merge_requests/180
Co-authored-by: Silviu Baranga <silviu.baranga@arm.com>

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D139708
2022-12-09 14:00:46 +00:00
Nikita Popov
b3df1ce389 [MemoryBuiltins] Remove unused TLI parameters (NFC) 2022-12-09 12:57:40 +01:00
Nikita Popov
9d7244409d [MemoryBuiltins] Remove CallocLike (NFC)
All functions of this kind already use allocator attributes. This
also highlights that isMallocOrCallocLikeFn() doesn't really do
what the name says (notably, it does not check for allocator
attributes). The places it is used in are also very dubious, so
we'll want to remove it.
2022-12-09 12:46:26 +01:00
Nikita Popov
cf7d8fd73c [MemoryBuiltins] Remove AlignedAllocLike (NFC)
All functions that formerly had this AllocType now use allocator
attributes, so drop it.
2022-12-09 12:36:27 +01:00
Nikita Popov
195af8e034 [MemoryBuiltins] Drop ReallocLike type (NFC)
All realloc style functions have been migrated to use allocator
attributes, so we no longer need to check for this.
2022-12-09 11:35:20 +01:00
Nikita Popov
e8dfafff66 [MemoryBuiltins] Remove some hardcoded builtins
For all of these we already infer the new memory attributes, so
they don't need to be explicitly listed.
2022-12-09 11:28:51 +01:00
Kazu Hirata
405fc404bf [ADT] Don't including None.h (NFC)
These source files no longer use None, so they do not need to include
None.h.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-06 20:14:51 -08:00
Kazu Hirata
19aff0f37d [Analysis] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02 19:43:04 -08:00
Krzysztof Parzyszek
26424c96c0 Attributes: convert Optional to std::optional 2022-12-02 08:15:45 -06:00
Matt Arsenault
ad3c91eedc MemoryBuiltins: Don't check for unsized allocas
The verifier rejects these.
2022-11-16 09:13:11 -08:00
Teresa Johnson
0d7f3464ce [MemProf] Update metadata during inlining
Update both memprof and callsite metadata to reflect inlined functions.

For callsite metadata this is simply a concatenation of each cloned
call's call stack with that of the inlined callsite's.

For memprof metadata, each profiled memory info block (MIB) is either
moved to the cloned allocation call or left on the original allocation
call depending on whether its context matches the newly refined call
stack context on the cloned call. We also reapply context trimming
optimizations based on the refined set of contexts on each of the calls
(cloned and original), via utilities in MemoryProfileInfo.

Depends on D128142.

Differential Revision: https://reviews.llvm.org/D128143
2022-09-30 16:46:17 -07:00
Teresa Johnson
f9403ca41e Profile matching and IR annotation for memprof profiles.
See also related RFCs:
RFC: Sanitizer-based Heap Profiler [1]
RFC: A binary serialization format for MemProf [2]
RFC: IR metadata format for MemProf [3]*

* Note that the IR metadata format has changed from the RFC during
implementation, as described in the preceeding patch adding the basic
metadata and verification support.

The matching is performed during the normal PGO annotation phase, to
ensure that the inlines applied in the IR at that point are a subset
of the inlines in the profiled binary and thus reflected in the
profile's call stacks. This is important because the call frames are
associated with functions in the profile based on the inlining in the
symbolized call stacks, and this simplifies locating the subset of
profile data relevant for matching onto each function's IR.

The PGOInstrumentationUse pass is enhanced to perform matching for
whatever combination of memprof and regular PGO profile data exists in
the profile.

Using the utilities introduced in D128854:
The memprof profile data for each context is converted to "cold" or
"notcold" based on parameterized thresholds for size, access count, and
lifetime. The memprof allocation contexts are trimmed to the minimal
amount of context required to uniquely identify whether the context is
cold or not cold. For allocations where all profiled contexts have the
same allocation type, no memprof metadata is attached and instead the
allocation call is directly annotated with an attribute specifying the
alloction type. This is the same attributed that will be applied to
allocation calls once cloned for different contexts, and later used
during LibCall simplification to emit allocation hints [4].

Depends on D128141 and D128854.

[1] https://lists.llvm.org/pipermail/llvm-dev/2020-June/142744.html
[2] https://lists.llvm.org/pipermail/llvm-dev/2021-September/153007.html
[3] https://discourse.llvm.org/t/rfc-ir-metadata-format-for-memprof/59165
[4] ab87cf382d

Differential Revision: https://reviews.llvm.org/D128142
2022-09-30 16:46:17 -07:00
Teresa Johnson
b1926f308f Restore "[MemProf] Memprof profile matching and annotation"
This reverts commit 794b7ea960ccc3222f2af582efadbc5e5c464292, and
thus restores commit a212d8da94d08e229aa8d65283e4b116310bba10, and
follow on fixes 0cd6763fa93159b84d70a5bb602c24996acaafaa,
e9ff53d42feac7fc157718523275619a8106f2f3, and
37c6a25e9ab230e5e21fa34e246d9fec55275df0.

Use a hash function (BLAKE3) instead of hash_combine/hash_code which are
not guaranteed to be stable across executions.

Additionally, it adds a "REQUIRES: x86_64-linux" to the tests that have
raw profile inputs to avoid failures on big endian bots.

Reviewers: snehasish, davidxl

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D128142
2022-09-23 11:38:47 -07:00
Teresa Johnson
794b7ea960 Revert "[MemProf] Memprof profile matching and annotation"
This reverts commit a212d8da94d08e229aa8d65283e4b116310bba10, and follow
on fixes 0cd6763fa93159b84d70a5bb602c24996acaafaa,
e9ff53d42feac7fc157718523275619a8106f2f3, and
37c6a25e9ab230e5e21fa34e246d9fec55275df0.

After re-reading the documentation for hash_combine, I don't think this
is the appropriate hash function to use for computing the hash to use as
a stack id in the metadata, since it is not guaranteed to produce stable
values across executions. I have not hit this problem, but plan to
switch to using an MD5 hash. I am hitting an issue with one of the bots
(https://lab.llvm.org/buildbot/#/builders/171/builds/20732)
where the values produced are only the lower 32 bits of the expected
hash values, however, which I assume is related to the implementation of
hash_combine and hash_code.

I believe I fixed all of the other bot failures with the follow on fixes,
which I'll merge into the new version before reapplying.
2022-09-22 16:08:03 -07:00
Teresa Johnson
37c6a25e9a [MemProf] Fix buildbot error due to hasValue deprecation warning
Use has_value instead of hasValue to address a deprecation warning from
a212d8da94d08e229aa8d65283e4b116310bba10. E.g.:

https://lab.llvm.org/buildbot/#/builders/57/builds/22166/steps/5/logs/stdio
2022-09-22 13:26:53 -07:00
Teresa Johnson
a212d8da94 [MemProf] Memprof profile matching and annotation
Profile matching and IR annotation for memprof profiles.

See also related RFCs:
RFC: Sanitizer-based Heap Profiler [1]
RFC: A binary serialization format for MemProf [2]
RFC: IR metadata format for MemProf [3]*

* Note that the IR metadata format has changed from the RFC during
implementation, as described in the preceeding patch adding the basic
metadata and verification support.

The matching is performed during the normal PGO annotation phase, to
ensure that the inlines applied in the IR at that point are a subset
of the inlines in the profiled binary and thus reflected in the
profile's call stacks. This is important because the call frames are
associated with functions in the profile based on the inlining in the
symbolized call stacks, and this simplifies locating the subset of
profile data relevant for matching onto each function's IR.

The PGOInstrumentationUse pass is enhanced to perform matching for
whatever combination of memprof and regular PGO profile data exists in
the profile.

Using the utilities introduced in D128854:
The memprof profile data for each context is converted to "cold" or
"notcold" based on parameterized thresholds for size, access count, and
lifetime. The memprof allocation contexts are trimmed to the minimal
amount of context required to uniquely identify whether the context is
cold or not cold. For allocations where all profiled contexts have the
same allocation type, no memprof metadata is attached and instead the
allocation call is directly annotated with an attribute specifying the
alloction type. This is the same attributed that will be applied to
allocation calls once cloned for different contexts, and later used
during LibCall simplification to emit allocation hints [4].

Depends on D128141 and D128854.

[1] https://lists.llvm.org/pipermail/llvm-dev/2020-June/142744.html
[2] https://lists.llvm.org/pipermail/llvm-dev/2021-September/153007.html
[3] https://discourse.llvm.org/t/rfc-ir-metadata-format-for-memprof/59165
[4] ab87cf382d

Differential Revision: https://reviews.llvm.org/D128142
2022-09-22 12:48:31 -07:00
Arthur Eubanks
203296d642 [BoundsChecking] Fix merging of sizes
BoundsChecking uses ObjectSizeOffsetEvaluator to keep track of the
underlying size/offset of pointers in allocations.  However,
ObjectSizeOffsetVisitor (something ObjectSizeOffsetEvaluator
uses to check for constant sizes/offsets)
doesn't quite treat sizes and offsets the same way as
BoundsChecking.  BoundsChecking wants to know the size of the
underlying allocation and the current pointer's offset within
it, but ObjectSizeOffsetVisitor only cares about the size
from the pointer to the end of the underlying allocation.

This only comes up when merging two size/offset pairs. Add a new mode to
ObjectSizeOffsetVisitor which cares about the underlying size/offset
rather than the size from the current pointer to the end of the
allocation.

Fixes a false positive with -fsanitize=bounds.

Reviewed By: vitalybuka, asbirlea

Differential Revision: https://reviews.llvm.org/D131001
2022-08-03 17:21:19 -07:00
Augie Fackler
85063090e9 MemoryBuiltins: remove malloc-family funcs from list
We no longer need specialized knowledge of these allocator functions in
this file since we have the correct attributes available now.

As far as I can tell the changes in the attributor tests are due to
things getting more consistent on alloc-family once we remove the static
list entries.

The two test changes in NewGVN merit extra scrutiny: NewGVN appears to
be _extremely_ sensitive to the inaccessiblememonly for reasons that
are beyond me. As a result, I had-enumerated all the attributes on
allocation functions in those two tests instead of using -inferattrs.
I assumed that the two -disable-simplify-libcalls tests there no
longer are sensible since the function declaration now includes all the
relevant attributes.

Differential Revision: https://reviews.llvm.org/D130107
2022-07-25 17:29:01 -04:00