289 Commits

Author SHA1 Message Date
Nikita Popov
3824a2dbce [MemoryBuiltins] Support allocas in getInitialValueOfAllocation (NFC) 2025-06-16 11:52:16 +02:00
serge-sans-paille
e4db3f0d97
[llvm] Bail out when meeting pointer with negative offset in approximated mode instead of … (#120424)
…generating empty location

Fix the regression detected by
https://github.com/llvm/llvm-test-suite/pull/188
2024-12-20 12:16:49 +00:00
serge-sans-paille
f8c1a22220
[llvm] Improve llvm.objectsize computation by computing GEP, alloca a… (#117849)
…nd malloc parameters bound

Using a naive expression walker, it is possible to compute valuable
information for allocation functions, GEP and alloca, even in the
presence of some dynamic information.

We don't rely on computeConstantRange to avoid taking advantage of
undefined behavior, which would be counter-productive wrt. usual
llvm.objectsize usage.

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.

This is a recommit of https://github.com/llvm/llvm-project/pull/115522
with fix applied.
2024-12-10 06:28:03 +00: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
Florian Mayer
a44d60f06f
Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound" (#117020)
Reverts llvm/llvm-project#115522

This caused UBSan errors in multi-stage clang build:

https://lab.llvm.org/buildbot/#/builders/25/builds/4241/steps/10/logs/stdio
2024-11-20 14:21:09 -08:00
serge-sans-paille
02b8ee2819
[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound (#115522)
Using a naive expression walker, it is possible to compute valuable
information for
allocation functions, GEP and alloca, even in the presence of some
dynamic
information.
    
We don't rely on computeConstantRange to avoid taking advantage of
undefined behavior, which would be counter-productive wrt. usual
llvm.objectsize usage.
    
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-19 07:45:18 +00:00
serge-sans-paille
1dcb3db0ac
[llvm] Fix behavior of llvm.objectsize in presence of negative / large offset (#115504)
The internal structure used to carry intermediate computations hold
signed values. If an object size happens to overflow signed values, we
can get invalid result, so make sure this situation never happens.
    
This is not very limitative as static allocation of such large values
should scarcely happen.
2024-11-18 07:39:04 +00:00
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