327 Commits

Author SHA1 Message Date
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
Nikita Popov
4bb2234a5d [FunctionAttrs] Add tests for PR63936 (NFC) 2023-07-21 16:46:29 +02:00
Nikita Popov
f3d0613d85 [CaptureTracking] Don't consider comparison of inbounds GEP with nonnull non-capturing
This is required to bring CaptureTracking in line with the new
semantics from D154051, as gep inbounds p, 0 is now always non-poison.

There are many ways in which the inbounds special case could be
preserved: If the index is known non-zero, or there is an inbounds
chain down to an identified object, etc. However, I have opted to
drop the special case entirely, as it appears to be low value:
In cases where we can determine such things (e.g. the affected test
cases) we would end up removing the compare via isGEPKnownNonNull()
logic anyway.

Differential Revision: https://reviews.llvm.org/D154054
2023-07-06 16:48:43 +02:00
Nikita Popov
f5f5c4726c [FunctionAttrs] Regenerate test checks (NFC) 2023-06-29 09:59:16 +02:00
Noah Goldstein
3391bdc255 Revert "[FunctionAttrs] Propagate some func/arg/ret attributes from caller to callsite (WIP)"
Accidental commit/push!

This reverts commit 4fa971ff62c3c48c606b792c572c03bd4d5906ee.
2023-06-13 00:53:31 -05:00
Noah Goldstein
4fa971ff62 [FunctionAttrs] Propagate some func/arg/ret attributes from caller to callsite (WIP)
This is the consolidation of D151644 and D151943 moved from
InstCombine to FunctionAttrs. This is based on discussion in the above
patches as well as D152081 (Attributor). This patch was written in a
way so it can have an immediate impact in currently active passes
(FunctionAttrs), but should be easy to port elsewhere (Attributor or
Inliner) if that makes more sense later on.

Some function attributes imply the attribute for all/some instructions
in the function. These attributes can be safely propagated to
callsites within the function that are missing the attribute. This can
be useful when 1) analyzing individual instructions in a function
and 2) if the original caller is later inlined, as if the attributes are
not propagated, they will be lost.

This patch implements propagation in a new class/file
`InferCallsiteAttrs` which can hypothetically be included elsewhere.

At the moment this patch infers the following:

Function Attributes:
    - mustprogress
    - nofree
    - willreturn
    - All memory attributes (readnone, readonly, writeonly, argmem,
      etc...)
        - The memory attributes are only propagated IFF the set of
          pointers available to the callsite is the same as the set
          available outside the caller (i.e no local memory arguments
          from alloca or local malloc like functions).

Argument Attributes:
    - noundef
    - nonnull
    - nofree
    - readnone
    - readonly
    - writeonly
    - nocapture
        - nocapture is only propagated IFF the set of pointers
          available to the callsite is the same as the set available
          outside the caller and its guranteed that between the
          callsite and function return, the state of any capture
          pointers will not change (so the nocaptured gurantee of the
          caller has been met by the instruction preceding the
          callsite and will not changed).

Argument are only propagated to callsite arguments that are also function
arguments, but not derived values.

Return Attributes:
    - noundef
    - nonnull

Return attributes are only propagated if the callsite's return value
is used as the caller's return and execution is guranteed to pass from
callsite to return.

The compile time hit of this for -O3 and -O3+thinLTO is ~[.02, .37]%
regression. Proper LTO, however, has more significant regressions (up
to 3.92%):
https://llvm-compile-time-tracker.com/compare.php?from=94407e1bba9807193afde61c56b6125c0fc0b1d1&to=79feb6e78b818e33ec69abdc58c5f713d691554f&stat=instructions:u

Differential Revision: https://reviews.llvm.org/D152226
2023-06-13 00:47:43 -05:00
Nikita Popov
9fe78db4cd [FunctionAttrs] Fix nounwind inference for landingpads
Currently, FunctionAttrs treats landingpads as non-throwing, and
will infer nounwind for functions with landingpads (assuming they
can't unwind in some other way, e.g. via resum). There are two
problems with this:

* Non-cleanup landingpads with catch/filter clauses do not
  necessarily catch all exceptions. Unless there are catch ptr null
  or filter [0 x ptr] zeroinitializer clauses, we should assume
  that we may unwind past this landingpad. This seems like an
  outright bug.
* Cleanup landingpads are skipped during phase one unwinding, so
  we effectively need to support unwinding past them. Marking these
  nounwind is technically correct, but not compatible with how
  unwinding works in reality.

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

Differential Revision: https://reviews.llvm.org/D147694
2023-04-14 11:46:00 +02:00
Nikita Popov
e0639695d3 [FunctionAttrs] Add another nounwind test (NFC) 2023-04-13 09:56:01 +02:00
Nikita Popov
af960a772d [FunctionAttrs] Add cleanuppad test (NFC) 2023-04-11 16:30:33 +02:00
Nikita Popov
e3f5cbd9c0 [FunctionAttrs] Add more nounwind tests (NFC)
Test variations where catch/filter catch all exceptions.
2023-04-06 10:54:15 +02:00
Nikita Popov
709cafb10d [FunctionAttrs] Add additional nounwind inference tests (NFC)
For PR61945.
2023-04-06 10:41:40 +02:00
Bjorn Pettersson
3528e63d89 [test] Remove duplicate RUN lines in Transform tests 2022-12-08 11:47:16 +01:00
Roman Lebedev
091aabc181
[NFC] Port all FunctionAttrs tests to -passes= syntax 2022-12-08 02:38:43 +03:00
Nikita Popov
304f1d59ca [IR] Switch everything to use memory attribute
This switches everything to use the memory attribute proposed in
https://discourse.llvm.org/t/rfc-unify-memory-effect-attributes/65579.
The old argmemonly, inaccessiblememonly and inaccessiblemem_or_argmemonly
attributes are dropped. The readnone, readonly and writeonly attributes
are restricted to parameters only.

The old attributes are auto-upgraded both in bitcode and IR.
The bitcode upgrade is a policy requirement that has to be retained
indefinitely. The IR upgrade is mainly there so it's not necessary
to update all tests using memory attributes in this patch, which
is already large enough. We could drop that part after migrating
tests, or retain it longer term, to make it easier to import IR
from older LLVM versions.

High-level Function/CallBase APIs like doesNotAccessMemory() or
setDoesNotAccessMemory() are mapped transparently to the memory
attribute. Code that directly manipulates attributes (e.g. via
AttributeList) on the other hand needs to switch to working with
the memory attribute instead.

Differential Revision: https://reviews.llvm.org/D135780
2022-11-04 10:21:38 +01:00
Nikita Popov
6aa672f141 [IR] Take operand bundles into account for call argument readonly/writeonly
We currently only take operand bundle effects into account when
querying the function-level memory attributes. However, I believe
that we also need to do the same for parameter attributes. For
example, a call with deopt bundle to a function with readnone
parameter attribute cannot treat that parameter as readnone,
because the deopt bundle may read it.

Differential Revision: https://reviews.llvm.org/D136834
2022-11-01 09:30:03 +01:00
Nikita Popov
7154f89c1a [FunctionAttrs] Add additional tests with operand bundles (NFC) 2022-10-27 12:39:15 +02:00
Nikita Popov
f2fe289374 [FunctionAttrs] Volatile operations can access inaccessible memory
Per LangRef, volatile operations are allowed to access the location
of their pointer argument, plus inaccessible memory:

> Any volatile operation can have side effects, and any volatile
> operation can read and/or modify state which is not accessible
> via a regular load or store in this module.
> [...]
> The allowed side-effects for volatile accesses are limited. If
> a non-volatile store to a given address would be legal, a volatile
> operation may modify the memory at that address. A volatile
> operation may not modify any other memory accessible by the
> module being compiled. A volatile operation may not call any
> code in the current module.

FunctionAttrs currently does not model this and ends up marking
functions with volatile accesses on arguments as argmemonly,
even though they should be inaccessiblemem_or_argmemonly.

Differential Revision: https://reviews.llvm.org/D135863
2022-10-20 11:57:10 +02:00
Nikita Popov
436fb27186 [BasicAA] Support loop phis in pointsToConstantMemory()
When looking for underlying objects, if we encounter one that we
have already seen, then we should skip it (as it has already been
checked) rather than bail out. In particular, this adds support
for the case where we have a loop use of a phi recurrence.
2022-10-17 12:34:55 +02:00
Nikita Popov
aa89f08afa [BasicAA] Add tests for constant memory with loop phi (NFC) 2022-10-17 12:32:15 +02:00
Nikita Popov
86126dbc15 [FunctionAttrs] Regenerate test checks (NFC) 2022-10-13 11:24:07 +02:00
Nikita Popov
e74390cc96 [FunctionAttrs] Convert tests to use opaque pointers (NFC)
Conversion performed using the script at:
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34
2022-10-13 10:38:11 +02:00
Nikita Popov
45e595880a [FunctionAttrs] Regenerate test checks (NFC) 2022-10-13 10:35:38 +02:00
Nikita Popov
5b3776842f [FunctionAttrs] Account for memory effects of inalloca/preallocated
The code for inferring memory attributes on arguments claims that
inalloca/preallocated arguments are always clobbered:
d71ad41080/llvm/lib/Transforms/IPO/FunctionAttrs.cpp (L640-L642)

However, we would still infer memory attributes for the whole
function without taking this into account, so we could still end
up inferring readnone for the function. This adds an argument
clobber if there are any inalloca/preallocated arguments.

Differential Revision: https://reviews.llvm.org/D135783
2022-10-13 10:20:17 +02:00
Nikita Popov
dbd29ed54b [FunctionAttrs] Regenerate test checks (NFC) 2022-10-12 17:11:48 +02:00