175 Commits

Author SHA1 Message Date
Hari Limaye
4da4fac322
[ArgPromotion] Consider InvokeInst in Caller alias analysis (#110335)
Check that all users of a Function are CallBase rather than CallInst
when performing alias analysis using actual arguments in the calling
function, as this check is also valid for Invoke instructions.

This allows replacing the existing check with an assert, as the Function
only being used by CallBase derived instructions is a precondition of
the transform.

This addresses post-commit review on #106216.
2024-10-04 14:33:04 +01:00
Hari Limaye
1c26e2b6f9
[ArgPromotion] Perform alias analysis on actual arguments of Calls (#106216)
Teach Argument Promotion to perform alias analysis on actual arguments
of Calls to a Function, to try to prove that all Calls to the Function
do not modify the memory pointed to by an argument. This surfaces more
opportunities to perform Argument Promotion in cases where simply
looking at a Function's instructions is insufficient to prove that the
pointer argument is not invalidated before all loads from it.
2024-09-27 11:06:59 +01:00
Yonghong Song
becc02ce93 Revert "[Transforms][IPO] Add func suffix in ArgumentPromotion and DeadArgume… (#105742)"
This reverts commit 959448fbd6bc6f74fb3f9655b1387d0e8a272ab8.
Reverting because multiple test failures e.g.
  https://lab.llvm.org/buildbot/#/builders/187/builds/1290
  https://lab.llvm.org/buildbot/#/builders/153/builds/9389
and maybe a few others.
2024-09-19 03:54:13 -07:00
yonghong-song
959448fbd6
[Transforms][IPO] Add func suffix in ArgumentPromotion and DeadArgume… (#105742)
…ntElimination

ArgumentPromotion and DeadArgumentElimination passes could change
function signatures but the function name remains the same as before the
transformation. This makes it hard for tracing with bpf programs where
user tends to use function signature in the source. See discussion [1]
for details.

This patch added suffix to functions whose signatures are changed. The
suffix lets users know that function signature has changed and they need
to impact the IR or binary to find modified signature before tracing
those functions.

The suffix for ArgumentPromotion is ".argprom" and the suffixes for
DeadArgumentElimination are ".argelim" and ".retelim". The suffix also
gives user hints about what kind of transformation has been done.

With this patch, I built a recent linux kernel with full LTO enabled. I
got 4 functions with only argpromotion like
```
  set_track_update.argelim.argprom
  pmd_trans_huge_lock.argprom
  ...
```
I got 1058 functions with only deadargelim like
```
  process_bit0.argelim
  pci_io_ecs_init.argelim
  ...
```
I got 3 functions with both argpromotion and deadargelim
```
  set_track_update.argelim.argprom
  zero_pud_populate.argelim.argprom
  zero_pmd_populate.argelim.argprom
```

  [1] https://github.com/llvm/llvm-project/issues/104678
2024-09-19 10:21:58 +02:00
yonghong-song
470f55facd
[Transforms][IPO] Add remarks for ArgumentPromotion and DeadArgumentE… (#105740)
…limination

ArgumentPromotion and DeadArgumentElimination passes may change function
signature. This makes bpf tracing difficult since users either not aware
of signature change or need to poke into IR or assembly to understand
the function signature change.

This patch enabled to emit some remarks so if recompiling with
-foptimization-record-file=<file>, users can check remarks to see what
kind of signature changes for a particular function. The following are
some examples for implemented remarks:
```
  Pass:            deadargelim
  Name:            ReturnValueRemoved
  DebugLoc:        { File: 'bpf-next/net/mptcp/protocol.c', Line: 572, Column: 0 }
  Function:        mptcp_check_data_fin
  Args:
    - String:          'removing return value '
    - String:          '0'

  Pass:            deadargelim
  Name:            ArgumentRemoved
  DebugLoc:        { File: 'bpf-next/kernel/bpf/syscall.c', Line: 1670, Column: 0 }
  Function:        map_delete_elem
  Args:
      - String:          'eliminating argument '
      - ArgName:         uattr.coerce0
      - String:          '('
      - ArgIndex:        '1'
      - String:          ')'

  Pass:            argpromotion
  Name:            ArgumentPromoted
  DebugLoc:        { File: 'bpf-next/net/mptcp/protocol.h', Line: 570, Column: 0 }
  Function:        mptcp_subflow_ctx
  Args:
    - String:          'promoting argument '
    - ArgName:         sk
    - String:          '('
    - ArgIndex:        '0'
    - String:          ')'
    - String:          ' to pass by value'
```
  [1] https://github.com/llvm/llvm-project/issues/104678
2024-08-31 10:41:54 -07:00
Hari Limaye
44d527c8d7 NFC: precommit test for [ArgPromotion] Perform alias analysis on actual arguments of Calls 2024-08-27 13:00:34 +00:00
Vedant Paranjape
78266ab0dc
[ArgPromotion] Remove redundant logic from recursive argpromotion code (#98657)
This patch further cleans up the implementation by removing some
redundant checks and replacing cast<> with get() calls.

This contribution is based on the discussion in #78735
2024-07-14 09:52:44 +05:30
Vedant Paranjape
10df988e48
[ArgPromotion] Handle pointer arguments of recursive calls (#78735)
Argument promotion doesn't handle recursive function calls to promote
arguments. This patch adds functionality to handle self recursive
function calls, i.e. whose SCC size is 1. Due to complexity of
ValueTracking in recursive calls with SCC size greater than 1, we bail
out in such cases.
2024-07-12 10:56:07 +05:30
Stephen Tozer
094572701d
[RemoveDIs] Print IR with debug records by default (#91724)
This patch makes the final major change of the RemoveDIs project, changing the
default IR output from debug intrinsics to debug records. This is expected to
break a large number of tests: every single one that tests for uses or
declarations of debug intrinsics and does not explicitly disable writing
records. 

If this patch has broken your downstream tests (or upstream tests on a
configuration I wasn't able to run):
1. If you need to immediately unblock a build, pass
`--write-experimental-debuginfo=false` to LLVM's option processing for all
failing tests (remember to use `-mllvm` for clang/flang to forward arguments to
LLVM).
2. For most test failures, the changes are trivial and mechanical, enough that
they can be done by script; see the migration guide for a guide on how to do
this: https://llvm.org/docs/RemoveDIsDebugInfo.html#test-updates
3. If any tests fail for reasons other than FileCheck check lines that need
updating, such as assertion failures, that is most likely a real bug with this
patch and should be reported as such.

For more information, see the recent PSA:
https://discourse.llvm.org/t/psa-ir-output-changing-from-debug-intrinsics-to-debug-records/79578
2024-06-14 15:07:27 +01:00
Florian Hahn
bba4a1daff
[ArgPromotion] Remove incorrect TranspBlocks set for loads. (#84835)
The TranspBlocks set was used to cache aliasing decision for all
processed loads in the parent loop. This is incorrect, because each load
can access a different location, which means one load not being modified
in a block doesn't translate to another load not being modified in the
same block.

All loads access the same underlying object, so we could perhaps use a
location without size for all loads and retain the cache, but that would
mean we loose precision.

For now, just drop the cache.

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

PR: https://github.com/llvm/llvm-project/pull/84835
2024-03-12 09:47:42 +00:00
Florian Hahn
31ffdb56b4
[ArgPromotion] Add test case for #84807.
Test case for https://github.com/llvm/llvm-project/issues/84807,
showing a mis-compile in ArgPromotion.
2024-03-11 21:06:15 +00:00
Nikita Popov
2d69827c5c [Transforms] Convert tests to opaque pointers (NFC) 2024-02-05 11:57:34 +01:00
Jeremy Morse
d2d9dc8eb4
[DebugInfo][RemoveDIs] Make debugify pass convert to/from RemoveDIs mode (#73251)
Debugify is extremely useful as a testing and debugging tool, and a good
number of LLVM-IR transform tests use it. We need it to support "new"
non-instruction debug-info to get test coverage, but it's not important
enough to completely convert right now (and it'd be a large
undertaking). Thus: convert to/from dbg.value/DPValue mode on entry and
exit of the pass, which gives us the functionality without any further
work. The cost is compile-time, but again this is only happening during
tests.

Tested by: the large set of debugify tests enabled here. Note the
InstCombine test (cast-mul-select.ll) that hasn't been fully enabled:
this is because there's a debug-info sinking piece of code there that
hasn't been instrumented.
2023-11-29 13:19:50 +00:00
Nikita Popov
c7aacbb5b6 [ArgPromotion] Update allocsize indices after promotion
Promotion can add/remove arguments. We need to update the
indices in the allocsize attribute accordingly.

Fixes https://github.com/llvm/llvm-project/issues/66103.
2023-09-18 16:15:16 +02:00
Matt Arsenault
25bc999d1f Intrinsics: Add type overload to stacksave and stackstore
This allows use with non-0 address space stacks. llvm_ptr_ty should
never be used. This could use some more percolation up through mlir,
but this is enough to fix existing tests.

https://reviews.llvm.org/D156666
2023-08-09 18:33:11 -04:00
Matt Arsenault
f3c9e5807f Analysis: Fix assertion when load alignment exceeds address space size
Apparently the maximum alignment no longer fits in 32-bits now, which
overflows a 32-bit offset and would fail on the isPowerOf2 assert.
2023-06-30 12:31:32 -04:00
Tobias Hieta
f84bac329b
[NFC][Py Reformat] Reformat lit.local.cfg python files in llvm
This is a follow-up to b71edfaa4ec3c998aadb35255ce2f60bba2940b0
since I forgot the lit.local.cfg files in that one.

Reformatting is done with `black`.

If you end up having problems merging this commit because you
have made changes to a python file, the best way to handle that
is to run git checkout --ours <yourfile> and then reformat it
with black.

If you run into any problems, post to discourse about it and
we will try to help.

RFC Thread below:

https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style

Reviewed By: barannikov88, kwk

Differential Revision: https://reviews.llvm.org/D150762
2023-05-17 17:03:15 +02:00
Shoaib Meenai
0e2b4b2dba Revert "[ArgumentPromotion] Bail if any callers are minsize"
This reverts commit 8b8466fd31e5a194fd8ba7a73a0f23d32f164318.

This is causing size regressions with -Oz and FullLTO. Revert while I
come up with a repro.
2023-05-05 14:26:57 -07:00
Arthur Eubanks
8b8466fd31 [ArgumentPromotion] Bail if any callers are minsize
Argument promotion mostly works on functions with more than one caller (otherwise the function would be inlined or is dead), so there's a good chance that performing this increases code size since we introduce loads at every call site. If any caller is marked minsize, bail.

We could compare the number of loads/stores removed from the function with the number of loads introduced in callers, but that's TODO.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D149768
2023-05-03 11:29:15 -07:00
Yonghong Song
da816c2985 [TTI][BPF] Ensure ArgumentPromotion Not Exceeding Target MaxArgs
With LLVM patch https://reviews.llvm.org/D148269, we hit a linux kernel
bpf selftest compilation failure like below:
  ...
  progs/test_xdp_noinline.c:739:8: error: too many args to t8: i64 = GlobalAddress<ptr @encap_v4> 0, progs/test_xdp_noinline.c:739:8
              if (!encap_v4(xdp, cval, &pckt, dst, pkt_bytes))
                   ^
  ...
  progs/test_xdp_noinline.c:321:6: error: defined with too many args
  bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval,
       ^
  ...

Note that bpf selftests are compiled with -O2 which is
the recommended flag for bpf community.

The bpf backend calling convention is only allowing 5
parameters in registers and does not allow pass arguments
through stacks. In the above case, ArgumentPromotionPass
replaced parameter '&pckt' as two parameters, so the total
number of arguments after ArgumentPromotion pass becomes 6
and this caused later compilation failure during instruction
selection phase.

This patch added a TargetTransformInfo hook getMaxNumArgs()
which returns 5 for BPF and UINT_MAX for other targets.

Differential Revision: https://reviews.llvm.org/D148551
2023-04-19 09:09:20 -07:00
Nikita Popov
b066505d88 [ArgPromotion] Require noundef to copy poison-generating metadata
For poison-generating (rather than IUB) metadata, only copy it
from the dominating must-exec load if it is combined with !noundef.
This could be further extended by additionall intersecting the
metadata from all loads, which does not require !noundef.
2023-04-05 14:34:33 +02:00
Nikita Popov
4923b4dbac [Local] Check for null VH in RecursivelyDeleteTriviallyDeadInstructionsPermissive()
Peculiarly, the non-permissive variant handled this gracefully,
but the permissive one did not.
2023-03-24 12:56:06 +01:00
Jeff Byrnes
7739be7c6b [ArgPromotion] Remove dead code produced by removing dead arguments
ArgPromotion currently produces phantom / dead loads. A good example of this is store-into-inself.ll. First, ArgPromo finds the promotable argument %p in @l. Then it inserts a load of %p in the caller, and passes instead the loaded value / transforms the function body. PromoteMem2Reg is able to optimize out the entire function body, resulting in an unused argument. In a subsequent ArgPromotion pass, it removes the dead argument, resulting in a dead load in the caller. These dead loads may reduce effectiveness of other transformations (e.g. SimplifyCFG, MergedLoadStoreMotion).

This patch removes loads and geps that are made dead in the caller after removal of dead args.

Differential Revision: https://reviews.llvm.org/D146327
2023-03-23 09:43:35 -07:00
Jeff Byrnes
08622314d2 Precommit tests for D146327 2023-03-22 12:23:28 -07:00
Nikita Popov
e6241cbdcb [Mem2Reg] Only convert !nonnull to assume if !noundef present
After D141386 !nonnull violation returns poison rather than
resulting in immediate undefined behavior. However, converting
it into an assume would result in IUB. As such, we can only
perform this transform if !noundef is also present.
2023-01-20 16:38:26 +01:00
Nikita Popov
bcbc615164 [ArgPromotion] Convert tests to opaque pointers (NFC)
update_test_checks was rerun for some of those, because we use
a different GEP representation with opaque pointers.
2022-12-23 09:53:50 +01:00
Roman Lebedev
679eaeb2f6
[NFC] Port all ArgumentPromotion tests to -passes= syntax 2022-12-08 02:38:40 +03:00
Phoebe Wang
19c5638e4f [ArgPromotion] Transfer metadata nontemporal to promoted loads
Fixes #56703

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D130536
2022-07-26 16:30:08 +08:00
Pavel Samolysov
170c4d21bd [ArgPromotion] Unify byval promotion with non-byval
It makes sense to handle byval promotion in the same way as non-byval
but also allowing `store` instructions. However, these should
use the same checks as the `load` instructions do, i.e. be part of the
`ArgsToPromote` collection. For these instructions, the check for
interfering modifications can be disabled, though. The promotion
algorithm itself has been modified a lot: all the accesses (i.e. loads
and stores) are rewritten to the emitted `alloca` instructions. To
optimize these new `alloca`s out, the `PromoteMemToReg` function from
`Transforms/Utils/PromoteMemoryToRegister.cpp` file is invoked after
promotion.

In order to let the `PromoteMemToReg` promote as many `alloca`s as it
is possible, there should be no `GEP`s from the `alloca`s. To
eliminate the `GEP`s, its own `alloca` is generated for every argument
part because a single `alloca` for the whole argument (that
significantly simplifies the code of the pass though) unfortunately
cannot be used.

The idea comes from the following discussion:
https://reviews.llvm.org/D124514#3479676

Differential Revision: https://reviews.llvm.org/D125485
2022-06-28 15:19:58 +03:00
Nikita Popov
217e85761c [ArgPromotion] Remove legacy PM support
Support for the legacy pass manager in ArgPromotion causes
complications in D125485. As the legacy pass manager for middle-end
optimizations is unsupported, drop ArgPromotion from the legacy
pipeline, rather than introducing additional complexity to deal
with it.

Differential Revision: https://reviews.llvm.org/D128536
2022-06-27 09:42:17 +02:00
Pavel Samolysov
d81064949f [ArgPromotion] Add unused-argument.ll test (NFC)
If a pointer argument is unused within the callee, this argument should
be removed from the function's signature while all used pointer
arguments should be promoted as it is expected. The ArgumentPromotion
pass doesn't touch unused non-pointer arguments at all.
2022-05-18 10:05:13 +03:00
Pavel Samolysov
d6852155b9 [ArgPromotion] Add tests for already seen offsets (NFC)
If a load with the same offset has already been seen but the load had
a lower alignment, the pass has to check whether the pointer is
dereferenceable and is sufficiently aligned (so, the new alignment must
be taken into account).
2022-05-13 13:29:38 +03:00
Pavel Samolysov
098afdb0a0 [ArgPromotion] Make a non-byval promotion attempt first
It makes sense to make a non-byval promotion attempt first and then
fall back to the byval one. The non-byval ('usual') promotion is
generally better, for example it does promotion even when a structure
has more elements than 'MaxElements' but not all of them are actually
used in the function.

Differential Revision: https://reviews.llvm.org/D124514
2022-05-12 16:44:52 +02:00
Phoebe Wang
7c04454227 [ArgPromotion][Attributor] Update min-legal-vector-width when do promotion
X86 codegen uses function attribute `min-legal-vector-width` to select the proper ABI. The intention of the attribute is to reflect user's requirement when they passing or returning vector arguments. So Clang front-end will iterate the vector arguments and set `min-legal-vector-width` to the width of the maximum for both caller and callee.

It is assumed any middle end optimizations won't care of the attribute expect inlining and argument promotion.
- For inlining, we will propagate the attribute of inlined functions because the inlining functions become the newer caller.
- For argument promotion, we check the `min-legal-vector-width` of the caller and callee and refuse to promote when they don't match.

The problem comes from the optimizations' combination, as shown by https://godbolt.org/z/zo3hba8xW. The caller `foo` has two callees `bar` and `baz`. When doing argument promotion, both `foo` and `bar` has the same `min-legal-vector-width`. So the argument was promoted to vector. Then the inlining inlines `baz` to `foo` and updates `min-legal-vector-width`, which results in ABI mismatch between `foo` and `bar`.

This patch fixes the problem by expanding the concept of `min-legal-vector-width` to indicator of functions arguments. That says, any passes touch functions arguments have to set `min-legal-vector-width` to the value reflects the width of vector arguments. It makes sense to me because any arguments modifications are ABI related and should response for the ABI compatibility.

Differential Revision: https://reviews.llvm.org/D123284
2022-05-02 14:13:05 +08:00
Pavel Samolysov
6b825e50f7 [ArgPromotion] Change the condition to check the promotion limit
The condition should be 'ArgParts.size() > MaxElements', so that if we
have exactly 3 elements in the 'ArgParts' vector, the promotion should
be allowed because the 'MaxElement' threshold is not exceeded yet.

The default value for 'MaxElement' has been decreased to 2 in order
to avoid an actual change in argument promoting behavior. However,
this changes byval argument transformation behavior by allowing
adding not more than 2 arguments to the function instead of 3 allowed
before.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D124178
2022-04-28 09:42:58 -07:00
Arthur Eubanks
51561b5e80 [ArgPromo][OpaquePointer] Don't promote mismatched function types
Mismatched call/callee function types is considered an indirect call.

Fixes crash in https://reviews.llvm.org/D123300#3446023.
2022-04-12 15:17:45 -07:00
Valery Pykhtin
152325d2f3 [ArgPromotion] Regenerate test checks for crash.ll – restored ALL_OLDPM prefix,
add –allow-unused-prefixes.

This test has two runs that differ in what functions are left after the inliner,
for example: barney exists on OLDPM path but don’t exist on NEWPM path.
I restored prefixes this test had had after automatic checks were introduced
for this test.

For now there are no checks left for ALL_NEWPM path, but the behavior seem to
change over time so I added –allow-unused-prefixes to ease following check updates.

Renamed %tmp => %temp IR values to avoid update warning.

Differential revision: https://reviews.llvm.org/D120207
2022-02-23 13:39:46 +03:00
Nico Weber
c31ef42530 Revert "[ArgPromotion] Regenerate test checks for crash.ll - removed ALL_NEWPM prefix."
This reverts commit 52577cd26f26f6428c72395e7337af3fc84bc6f6.
Breaks check-llvm, see comments on https://reviews.llvm.org/D120207
2022-02-21 13:29:37 -05:00
Valery Pykhtin
52577cd26f [ArgPromotion] Regenerate test checks for crash.ll - removed ALL_NEWPM prefix.
Rename %tmp => %temp IR values to avoid update warning.

Reviewed by Nikita Popov

Differential revision: https://reviews.llvm.org/D120207
2022-02-21 19:18:39 +03:00
Valery Pykhtin
29d2ae59e4 [ArgPromotion] Regenerate test checks for dead-gep-no-promotion.ll
with --function-signature option (otherwise filecheck gets confused).
2022-02-20 15:00:18 +03:00
Valery Pykhtin
a2ce8df49b [ArgPromotion] auto-update test checks.
Rename %tmp => %temp IR values to avoid update warning.
2022-02-20 13:23:12 +03:00
Nikita Popov
e24067819f [ArgPromotion] Protect harder against recursive promotion (PR42028)
In addition to the self-recursion check, also check whether there
is more than one node in the SCC, which implies that there is a
larger cycle. I believe checking SCC structure (rather than
something like norecurse) is the right thing to do here, because
this is specifically about preventing infinite loops over the SCC.

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

Differential Revision: https://reviews.llvm.org/D119418
2022-02-11 09:30:39 +01:00
Nikita Popov
8018d6be34 [ArgPromotion] Transfer metadata to promoted loads
Also transfer selected non-AA metadata to the promoted load.
Only metadata from guaranteed to execute loads is transferred.
2022-02-10 11:28:07 +01:00
Nikita Popov
e76c697106 [ArgPromotion] Add test for metadata on promoted loads (NFC) 2022-02-10 11:28:07 +01:00
Nikita Popov
68c1eeb4ba [ArgPromotion] Make implementation offset based
This rewrites ArgPromotion to be based on offsets rather than GEP
structure. We inspect all loads at constant offsets and remember
which types are loaded at which offsets. Then we promote based on
those types.

This generalizes ArgPromotion to work with bitcasted loads, and
is compatible with opaque pointers.

This patch also fixes incorrect handling of alignment during
argument promotion. Previously, the implementation only checked
that the pointer is dereferenceable, but was happy to speculate
overaligned loads. (I would have fixed this separately in advance,
but I found this hard to do with the previous implementation
approach).

Differential Revision: https://reviews.llvm.org/D118685
2022-02-09 09:35:01 +01:00
Nikita Popov
b896334834 [ArgPromotion] Check dereferenceability on argument as well
Before walking all the callers, check whether we have a
dereferenceable attribute directly on the argument.

Also make it clearer that the code currently does not treat
alignment correctly.
2022-02-08 10:29:51 +01:00
Nikita Popov
c2b476767e [ArgPromotion] Test dereferenceable annotation on callee (NFC)
While we check dereferenceability of all callers, we don't check
dereferenceability annotations on the callee.
2022-02-08 10:27:17 +01:00
Nikita Popov
8af8119177 [ArgPromotion] Add test with bitcasts (NFC)
Argument promotion currently doesn't handle these.
2022-02-02 14:46:27 +01:00
Nikita Popov
be20ee67e5 [ArgPromotion] Add test for volatile and atomic loads (NFC)
Argument promotion does handle these correctly (by not promoting
them), but there were no tests to ensure this.
2022-02-02 09:44:28 +01:00
Nikita Popov
a24cc48bc6 [ArgPromotion] Add alignment test (NFC)
This shows a miscompile in the current argpromotion implementation:
We may speculatively execute overaligned loads.
2022-02-01 10:45:14 +01:00