350 Commits

Author SHA1 Message Date
Nikita Popov
36f0838a3d [FunctionAttrs] Consider non-willreturn functions during capture inference
Matching the CaptureTracking change in abd97d9685c07c4787ff22e56c0a7b8963630063,
only directly infer captures(none) for
readonly+nocapture+willreturn+void.

Part of https://github.com/llvm/llvm-project/issues/129090.
2025-02-28 11:33:44 +01:00
Nikita Popov
abd97d9685 [CaptureTracking] Take non-willreturn calls into account
We can leak one bit of information about the address by either
diverging or not.

Part of https://github.com/llvm/llvm-project/issues/129090.
2025-02-28 11:15:28 +01:00
Nikita Popov
e56a6a2683
Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880) (#128020)
Relative to the previous attempt this includes two fixes:
 * Adjust callCapturesBefore() to not skip captures(ret: address,
    provenance) arguments, as these will not count as a capture
    at the call-site.
 * When visiting uses during stack slot optimization, don't skip
    the ModRef check for passthru captures. Calls can both modref
    and be passthru for captures.

------

This extends CaptureTracking to support inferring non-trivial
CaptureInfos. The focus of this patch is to only support FunctionAttrs,
other users of CaptureTracking will be updated in followups.

The key API changes here are:

* DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC
component specifies what is captured at that Use and the ResultCC
component specifies what may be captured via the return value of the
User. Usually only one or the other will be used (corresponding to
previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for
call captures.
* The CaptureTracking::captures() extension point is passed this
UseCaptureInfo as well and then can decide what to do with it by
returning an Action, which is one of: Stop: stop traversal.
ContinueIgnoringReturn: continue traversal but don't follow the
instruction return value. Continue: continue traversal and follow the
instruction return value if it has additional CaptureComponents.

For now, this patch retains the (unsound) special logic for comparison
of null with a dereferenceable pointer. I'd like to switch key code to
take advantage of address/address_is_null before dropping it.

This PR mainly intends to introduce necessary API changes and basic
inference support, there are various possible improvements marked with
TODOs.
2025-02-27 09:38:29 +01:00
Nikita Popov
6361a8a1b7 [CaptureTracking] Check for equality predicate for null comparisons
The logic here is not valid for non-equality comparisons. E.g.
using slt will leak the sign bit, regardless of whether the
pointer is dereferenceable.

This fix is split out from https://github.com/llvm/llvm-project/pull/125880.
2025-02-20 13:08:45 +01:00
Nikita Popov
54f14d96bb [FunctionAttrs] Add test for incorrect predicate in capture analysis (NFC) 2025-02-20 13:08:45 +01:00
Nico Weber
e2ba1b6ffd Revert "Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)"
This reverts commit 0fab404ee874bc5b0c442d1841c7d2005c3f8729.
Seems to break LTO builds of clang on Windows, see comments on
https://github.com/llvm/llvm-project/pull/125880
2025-02-19 11:32:57 -05:00
Krzysztof Drewniak
f7d03707d1
[AMDGPU] Generalize amdgcn.make.buffer.rsrc to fat pointers (#126828)
Attempting to pass a `ptr addrspace(7)` to functions that take `ptr`
arguments produces undesirable `addrspacecast(addrspacecast(p8 x to p7)
to p0) => addrspacecast(p8 x to p0)` folds. This results in illegal GEP
operations on buffer resources, which can't be GEP'd. (However, note
that, while unimplemneted, addressspacecast from ptr addrspace(7) to ptr
is legal - it's just an effective address computation)

To resolve this problem, and thus prevent illegal
`getelementptr T, ptr addrspace(8) %x, ...` s from being produces, this
commit extends amdgcn.make.buffer.rsrc to also be variadic in its result
type, auto-upgrading old manglings.

The logic for handling a make.buffer.rsrc in instruction selection
remains untouched and expects the output type to be a ptr addrspace(8),
as does the Clang lowering for its builtin (the pointer-to-pointer
version might want a different name in clang). LowerBufferFatPointers
has been updated to lower
amdgcn.make.buffer.rsrc.p7.p* to amdgcn.make.buffer.rsrc.p8.p* .

This'll also make exposing buffer fat pointers in Clang easier, since
you don't have to cast between a `__amdgcn_rsrc_t` and a pointer.
2025-02-18 14:15:28 -06:00
Nikita Popov
7e3735d1a1 Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)
Relative to the previous attempt, this adjusts isEscapeSource()
to not treat calls with captures(ret: address, provenance) or similar
arguments as escape sources. This addresses the miscompile reported at:
https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577

The implementation uses a helper function on CallBase to make this
check a bit more efficient (e.g. by skipping the byval checks) as
checking attributes on all arguments if fairly expensive.

------

This extends CaptureTracking to support inferring non-trivial
CaptureInfos. The focus of this patch is to only support FunctionAttrs,
other users of CaptureTracking will be updated in followups.

The key API changes here are:

* DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC
component specifies what is captured at that Use and the ResultCC
component specifies what may be captured via the return value of the
User. Usually only one or the other will be used (corresponding to
previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for
call captures.
* The CaptureTracking::captures() extension point is passed this
UseCaptureInfo as well and then can decide what to do with it by
returning an Action, which is one of: Stop: stop traversal.
ContinueIgnoringReturn: continue traversal but don't follow the
instruction return value. Continue: continue traversal and follow the
instruction return value if it has additional CaptureComponents.

For now, this patch retains the (unsound) special logic for comparison
of null with a dereferenceable pointer. I'd like to switch key code to
take advantage of address/address_is_null before dropping it.

This PR mainly intends to introduce necessary API changes and basic
inference support, there are various possible improvements marked with
TODOs.
2025-02-14 12:38:04 +01:00
Nikita Popov
1e64ea9914 Revert "[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)"
This reverts commit ee655ca27aad466bcc54f6eba03f7e564940ad5a.

A miscompilation has been reported at:
https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577
2025-02-13 14:56:12 +01:00
Matt Arsenault
6a59d60e2b
AMDGPU: Mark sendmsg intrinsics as nocallback (#126782)
These can be nocallback, but no nosync. These return in the current
thread immediately, but may send a signal to the host, which could
trigger
the async execution of code in the module.

Fixes #124802
2025-02-13 18:35:16 +07:00
Nikita Popov
ee655ca27a
[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)
This extends CaptureTracking to support inferring non-trivial
CaptureInfos. The focus of this patch is to only support FunctionAttrs,
other users of CaptureTracking will be updated in followups.

The key API changes here are:

* DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC
component specifies what is captured at that Use and the ResultCC
component specifies what may be captured via the return value of the
User. Usually only one or the other will be used (corresponding to
previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for
call captures.
* The CaptureTracking::captures() extension point is passed this
UseCaptureInfo as well and then can decide what to do with it by
returning an Action, which is one of: Stop: stop traversal.
ContinueIgnoringReturn: continue traversal but don't follow the
instruction return value. Continue: continue traversal and follow the
instruction return value if it has additional CaptureComponents.

For now, this patch retains the (unsound) special logic for comparison
of null with a dereferenceable pointer. I'd like to switch key code to
take advantage of address/address_is_null before dropping it.

This PR mainly intends to introduce necessary API changes and basic
inference support, there are various possible improvements marked with
TODOs.
2025-02-13 09:36:35 +01:00
Nikita Popov
0bfcb76be1 [FunctionAttrs] Add additional tests for captures inference (NFC) 2025-02-06 15:32:55 +01:00
Nikita Popov
29441e4f5f
[IR] Convert from nocapture to captures(none) (#123181)
This PR removes the old `nocapture` attribute, replacing it with the new
`captures` attribute introduced in #116990. This change is
intended to be essentially NFC, replacing existing uses of `nocapture`
with `captures(none)` without adding any new analysis capabilities.
Making use of non-`none` values is left for a followup.

Some notes:
* `nocapture` will be upgraded to `captures(none)` by the bitcode
   reader.
* `nocapture` will also be upgraded by the textual IR reader. This is to
   make it easier to use old IR files and somewhat reduce the test churn in
   this PR.
* Helper APIs like `doesNotCapture()` will check for `captures(none)`.
* MLIR import will convert `captures(none)` into an `llvm.nocapture`
   attribute. The representation in the LLVM IR dialect should be updated
   separately.
2025-01-29 16:56:47 +01:00
Florian Hahn
4233a15c9f
[FunctionAttrs] Handle zero writes in initializes inference.
ConstantRange's constructor asserts that the range not empty, except if
lower/upper are min or max values.

Check if the length is strictly positive instead of just non-negative so
std::nullopt is returned when the size is 0. If that's the case, the
access doesn't initialize anything.

This should fix a crash when building on macOS with ASan & UBsan after
https://github.com/llvm/llvm-project/pull/97373 /
https://github.com/llvm/llvm-project/pull/117104 landed:
https://green.lab.llvm.org/job/llvm.org/job/clang-stage2-cmake-RgSan/664/console
2025-01-18 20:01:07 +00:00
Heejin Ahn
5a90168fa3
[ValueTracking] Provide getUnderlyingObjectAggressive fallback (#123019)
This callsite assumes `getUnderlyingObjectAggressive` returns a non-null
pointer:

273a94b3d5/llvm/lib/Transforms/IPO/FunctionAttrs.cpp (L124)

But it can return null when there are cycles in the value chain so there
is no more `Worklist` item anymore to explore, in which case it just
returns `Object` at the end of the function without ever setting it:
9b5857a683/llvm/lib/Analysis/ValueTracking.cpp (L6866-L6867)
9b5857a683/llvm/lib/Analysis/ValueTracking.cpp (L6889)

`getUnderlyingObject` does not seem to return null either judging by
looking at its code and its callsites, so I think it is not likely to be
the author's intention that `getUnderlyingObjectAggressive` returns
null.

So this checks whether `Object` is null at the end, and if so, falls
back to the original first value.

---

The test case here was reduced by bugpoint and further reduced manually,
but I find it hard to reduce it further.

To trigger this bug, the memory operation should not be reachable from
the entry BB, because the `phi`s should form a cycle without introducing
another value from the entry. I tried a minimal `phi` cycle with three
BBs (entry BB + two BBs in a cycle), but it was skipped here:
273a94b3d5/llvm/lib/Transforms/IPO/FunctionAttrs.cpp (L121-L122)
To get the result that's not `ModRefInfo::NoModRef`, the length of `phi`
chain needed to be greater than the `MaxLookup` value set in this
function:

02403f4e45/llvm/lib/Analysis/BasicAliasAnalysis.cpp (L744)

But just lengthening the `phi` chain to 8 didn't trigger the same error
in `getUnderlyingObjectAggressive` because `getUnderlyingObject` here
passes through a single-chain `phi`s so not all `phi`s end up in
`Visited`:

9b5857a683/llvm/lib/Analysis/ValueTracking.cpp (L6863)

So I just submit here the smallest test case I managed to create.

---

Fixes #117308 and fixes #122166.
2025-01-15 11:53:51 -08:00
Nikita Popov
2d760a139e [FunctionAttrs] Add test for initializes + byval (NFC) 2025-01-14 15:30:39 +01:00
Alex MacLean
c6c864da3f
[FunctionAttrs] Treat byval calls as only reading ptrs (#122618)
Since byval arguments are passed via a hidden copy of the pointee, they
do not have the same semantics as normal pointer arguments. The callee
cannot capture or write to the pointer and the copy is a read of the
pointer.
2025-01-13 12:10:26 -08:00
Haopeng Liu
8daba2c13d
Skip negative length while inferring initializes attr (#120874)
Bail out negative length while inferring initializes attr. Otherwise it
causes an assertion error:
`Attribute 'initializes' does not support unordered ranges`
2024-12-22 19:01:52 -08:00
Haopeng Liu
4d6e69143d
Add the initializes attribute inference (#117104)
reland https://github.com/llvm/llvm-project/pull/97373 after fixing
clang tests.

Confirmed with "ninja check-llvm" and "ninja check-clang"
2024-11-20 19:15:23 -08:00
Mikhail Goncharov
f77126c549 Revert "[FunctionAttrs] Add the "initializes" attribute inference (#97373)"
This reverts commit 661c593850715881d2805a59e90e6d87d8b9fbb8.

Multiple buildbot failures, e.g. https://lab.llvm.org/buildbot/#/builders/108/builds/6096
2024-11-19 10:29:36 +01:00
Haopeng Liu
661c593850
[FunctionAttrs] Add the "initializes" attribute inference (#97373)
Add the "initializes" attribute inference.

This change is expected to have ~0.09% compile time regression, which
seems acceptable for interprocedural DSE.

https://llvm-compile-time-tracker.com/compare.php?from=9f10252c4ad7cffbbcf692fa9c953698f82ac4f5&to=56345c1cee4375eb5c28b8e7abf4803d20216b3b&stat=instructions%3Au
2024-11-18 21:36:05 -08:00
Lee Wei
1ca64c5fb7
[llvm] Remove br i1 undef from some regression tests [NFC] (#115691)
This PR aims to remove undefined behavior from tests under the directory
`llvm/transforms/CodegenPrepare, ConstantHoisting, Coroutines` etc.
2024-11-11 12:56:31 +00:00
Matt Arsenault
d74b1f029d
ValueTracking: Do not return nullptr from getUnderlyingObject (#115258)
Fixup for 29a5c054e6d56a912ed5ba3f84e8ca631872db8b. The failure case
should return the last value found.
2024-11-07 07:35:33 -08:00
Noah Goldstein
6b11573b8c Recommit "[FunctionAttrs] deduce attr cold on functions if all CG paths call a cold function"
Fixed up the uar test that was failing. It seems with the new `cold`
attribute the order of the functions is different. As far as I can
tell this is not a concern.

Closes #105559
2024-08-22 10:14:08 -07:00
Noah Goldstein
69a0af756b Revert "[FunctionAttrs] deduce attr cold on functions if all CG paths call a cold function"
This reverts commit b7eac8c6fea1ba3930d08011a0e5e3a262bfaece.

Causing a test failure. Not 100% sure the issue so to reverting to
unblock pipeline.
2024-08-20 22:10:30 -07:00
Noah Goldstein
b7eac8c6fe [FunctionAttrs] deduce attr cold on functions if all CG paths call a cold function
Closes #101298
2024-08-20 15:29:24 -07:00
Noah Goldstein
26b79f8707 [FunctionAttrs] Add tests for deducing attr cold on functions; NFC 2024-08-20 15:29:24 -07:00
Nikita Popov
472c79ca52
[IR] Check that arguments of naked function are not used (#104757)
Verify that the arguments of a naked function are not used. They can
only be referenced via registers/stack in inline asm, not as IR values.
Doing so will result in assertion failures in the backend.

There's probably more that we should verify, though I'm not completely
sure what the constraints are (would it be correct to require that naked
functions are exactly an inline asm call + unreachable, or is more
allowed?)

Fixes https://github.com/llvm/llvm-project/issues/104718.
2024-08-20 09:29:05 +02:00
DianQK
559be8e2b5
Reapply "[FunctionAttrs] Determine underlying object by getUnderlyingObjectAggressive (#100102)"
Added handling for `AllocaInst`.

This reverts commit 1ee686a55aa6365eff39bbd1dc2059b16be6c2f1.
2024-07-24 20:01:22 +08:00
Nikita Popov
1ee686a55a Revert "[FunctionAttrs] Determine underlying object by getUnderlyingObjectAggressive (#100102)"
This reverts commit a213edd32abff8d154dad96824689b98ec7b5a35.

Assertion failures on buildbots.
2024-07-23 14:57:25 +02:00
DianQK
a213edd32a
[FunctionAttrs] Determine underlying object by getUnderlyingObjectAggressive (#100102)
Thanks to #99509, we can fix
https://github.com/rust-lang/rust/issues/119573 too.
2024-07-23 20:50:25 +08:00
Nikita Popov
f64732195c [FunctionAttrs] Regenerate test checks (NFC) 2024-05-23 08:45:38 +02:00
Johannes Doerfert
5ec91b392d
[AttributorLight] Without liveness checks, look at all functions (#91004) 2024-05-23 07:28:07 +02:00
Nikita Popov
f34d30cdae
[FunctionAttrs] Fix incorrect nonnull inference for non-inbounds GEP (#91180)
For inbounds GEPs, if the source pointer is non-null, the result must
also be non-null. However, this does not hold for non-inbounds GEPs.
    
Fixes https://github.com/llvm/llvm-project/issues/91177.
2024-05-07 09:47:28 +09:00
Nikita Popov
a2ccd5d88f
[FunctionAttrs] Fix incorrect noundef inference with poison attrs (#89348)
Currently, when inferring noundef, we only check that the return value
is not undef/poison. However, we fail to account for the possibility
that a poison-generating return attribute will convert the value to
poison, and then violate the noundef attribute, resulting in immediate
UB.

For the relevant return attributes (align, nonnull and range), check
whether we can trivially re-prove the relevant property, otherwise do
not infer noundef.

This fixes the FunctionAttrs side of
https://github.com/llvm/llvm-project/issues/88026.
2024-04-23 14:26:12 +09:00
Nikita Popov
bd898d5e11 [FunctionAttrs] Add tests for incorrect noundef inference (#88026) 2024-04-19 14:55:50 +09:00
elhewaty
fa8dc36350
[IR] Fix crashes caused by #85592 (#87169)
This patch fixes the crash caused by the pull request:
https://github.com/llvm/llvm-project/pull/85592
2024-04-02 15:49:31 +08:00
Yingwei Zheng
7e405eb722
[FuncAttrs] Don't infer noundef for functions with sanitize_memory attribute (#76691)
MemorySanitizer assumes that the definition and declaration of a
function will be consistent. If we add `noundef` for some definitions,
it will break msan.

Fix buildbot failure caused by #76553.
2024-01-02 06:59:56 +08:00
Yingwei Zheng
1228becf7d
[FuncAttrs] Deduce noundef attributes for return values (#76553)
This patch deduces `noundef` attributes for return values.
IIUC, a function returns `noundef` values iff all of its return values
are guaranteed not to be `undef` or `poison`.
Definition of `noundef` from LangRef:
```
noundef
This attribute applies to parameters and return values. If the value representation contains any 
undefined or poison bits, the behavior is undefined. Note that this does not refer to padding 
introduced by the type’s storage representation.
```
Alive2: https://alive2.llvm.org/ce/z/g8Eis6

Compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=30dcc33c4ea3ab50397a7adbe85fe977d4a400bd&to=c5e8738d4bfbf1e97e3f455fded90b791f223d74&stat=instructions:u
|stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang|
|--|--|--|--|--|--|--|
|+0.01%|+0.01%|-0.01%|+0.01%|+0.03%|-0.04%|+0.01%|

The motivation of this patch is to reduce the number of `freeze` insts
and enable more optimizations.
2023-12-31 20:44:48 +08:00
Yingwei Zheng
4358e6e0c5
[FuncAttrs] Infer norecurse for funcs with calls to nocallback callees (#76372)
This patch adds missing `norecurse` attrs to funcs that only call intrinsics with `nocallback` attrs.
Fixes the regression found in https://github.com/dtcxzyw/llvm-opt-benchmark/pull/45#discussion_r1436148743.
The function loses `norecurse` attr because it calls `@llvm.fabs.f64`, which is not marked as `norecurse`.

Since `norecurse` is not a default attribute of intrinsics and it is
ambiguous for intrinsics, I decided to use the existing `callback`
attributes.

> nocallback
This attribute indicates that the function is only allowed to jump back
into caller’s module by a return or an exception, and is not allowed to
jump back by invoking a callback function, a direct, possibly
transitive, external function call, use of longjmp, or other means. It
is a compiler hint that is used at module level to improve dataflow
analysis, dropped during linking, and has no effect on functions defined
in the current module.

See also https://llvm.org/docs/LangRef.html#function-attributes.
2023-12-27 03:16:43 +08:00
Nikita Popov
6b8ed78719 [IR] Add writable attribute
This adds a writable attribute, which in conjunction with
dereferenceable(N) states that a spurious store of N bytes is
introduced on function entry. This implies that this many bytes
are writable without trapping or introducing data races. See
https://llvm.org/docs/Atomics.html#optimization-outside-atomic for
why the second point is important.

This attribute can be added to sret arguments. I believe Rust will
also be able to use it for by-value (moved) arguments. Rust likely
won't be able to use it for &mut arguments (tree borrows does not
appear to allow spurious stores).

In this patch the new attribute is only used by LICM scalar promotion.
However, the actual motivation for this is to fix a correctness issue
in call slot optimization, which needs this attribute to avoid
optimization regressions.

Followup to the discussion on D157499.

Differential Revision: https://reviews.llvm.org/D158081
2023-11-01 10:46:31 +01:00
Krzysztof Drewniak
93f8e52d1f
[FunctionAttrs] Improve handling of alias-preserving intrinsic calls (#68453)
Fixes #68270

The function attribute analysis handles many instructions, like
addrspacecast, which do not themselves read or write memory but which
transform pointers into other values in the same alias set.

There are intrinsic functions, such as ptrmask or the AMDGPU-specific
make.buffer.rsrc, which also preserve membership in alias sets without
capturing. This commit adds the addrspacecast-like behavior to these
calls.
2023-10-24 11:16:54 -05:00
Nikita Popov
2ad41fa736 [FunctionAttrs] Regenerate test checks (NFC) 2023-10-20 09:59:32 +02:00
Nikita Popov
104c01eb31
[FunctionAttrs] Only check ArgMem effects when inferring argument attrs (#69571)
When inferring readonly/writeonly on arguments, if the argument is
passed to a call, we should only check the ArgMem effects implied by the
call -- we don't care whether the call reads/writes non-arg memory
(captured pointers are not relevant here, because they will abort the
analysis entirely).

This also fixes a regression that was introduced when moving to
MemoryEffects: The code was still checking the old WriteOnly attribute
on functions, which no longer exists.
2023-10-20 08:56:09 +02:00
Nikita Popov
9ea2fd2457 [FunctionAttrs] Add additional tests for writeonly (NFC)
Add tests with argmem variations.
2023-10-19 10:32:18 +02:00
Anton Korobeynikov
51d5d7bbae
Extend retcon.once coroutines lowering to optionally produce a normal result (#66333)
One of the main user of these kind of coroutines is swift. There yield-once (`retcon.once`) coroutines are used to temporary "expose" pointers to internal fields of various objects creating borrow scopes.

However, in some cases it might be useful also to allow these coroutines to produce a normal result, but there is no convenient way to represent this (as compared to switched-resume kind of coroutines where C++ `co_return`
is transformed to a member / callback call on promise object).

The extension is simple: we allow continuation function to have a non-void result and accept optional extra arguments via a special `llvm.coro.end.result` intrinsic that would essentially forward them as normal results.
2023-09-15 09:54:38 -07:00
Noah Goldstein
39e9862e6b [ValueTracking] Use predicates for incoming phi-edges to deduce non-zero
This is basically a copy and paste of the same logic we do in
`computeKnownBits` but adapts it for just `isKnownNonZero`.

Differential Revision: https://reviews.llvm.org/D157801
2023-08-22 10:59:02 -05:00
Nikita Popov
86f3dc83e1 [FunctionAttrs] Consider recursive argmem effects (PR63936)
When inspecting the function body, we can't simply ignore effects
of functions in the SCC entirely, because an argmem access of a
recursive call might result in an access to another location in
the callee.

Fix this by separately tracking memory effects that would occur if
the SCC accesses argmem, and then later add those.

Fixes https://github.com/llvm/llvm-project/issues/63936.

Differential Revision: https://reviews.llvm.org/D155956
2023-08-14 14:39:54 +02:00
Nikita Popov
9d33c467b7 [FunctionAttrs] Fix argmemonly.ll test (NFC)
This test was incorrectly updated in D152081.
2023-08-09 11:13:19 +02:00
Florian Hahn
400fde9296
[Attributor] Add lightweight version for attribute deduction only.
This patch adds a lightweight instance of Attributor that only deduces
attributes.

This is just an initial version with the goal to have a version that
only focuses on attributes to replace the function-attrs pass.

The initial version has a few open issues pending until default
enablement, the main one probably being compile time. The main
additional functionality this will provide in general is propagating
attributes to call sites.

Open issues:

* compile time
  The current version increase O3 +2.67% and ThinLTO +6.18% when replacing FunctionAttr
   https://llvm-compile-time-tracker.com/compare.php?from=c4bb3e073548cf436d5fa0406e3ae75e94684dec&to=d992630a69c79a2587d736e6a88f448850413bd1&stat=instructions%3Au
   Both are with an additional change to preserve more analysis, like FunctionAttrs CGSCC run.

* some missed attribute inference

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D152081
2023-08-05 11:47:28 +01:00