258 Commits

Author SHA1 Message Date
Nikita Popov
c23b4fbdbb
[IR] Remove size argument from lifetime intrinsics (#150248)
Now that #149310 has restricted lifetime intrinsics to only work on
allocas, we can also drop the explicit size argument. Instead, the size
is implied by the alloca.

This removes the ability to only mark a prefix of an alloca alive/dead.
We never used that capability, so we should remove the need to handle
that possibility everywhere (though many key places, including stack
coloring, did not actually respect this).
2025-08-08 11:09:34 +02:00
Nikita Popov
2c6eec219d [Tests] Avoid lifetime intrinsics on non-allocas (NFC)
Don't rely on auto-upgrade, instead either remove unnecessary
casts or remove no longer applicable tests.
2025-07-23 15:05:43 +02:00
Nikita Popov
92c55a315e
[IR] Only allow lifetime.start/end on allocas (#149310)
lifetime.start and lifetime.end are primarily intended for use on
allocas, to enable stack coloring and other liveness optimizations. This
is necessary because all (static) allocas are hoisted into the entry
block, so lifetime markers are the only way to convey the actual
lifetimes.

However, lifetime.start and lifetime.end are currently *allowed* to be
used on non-alloca pointers. We don't actually do this in practice, but
just the mere fact that this is possible breaks the core purpose of the
lifetime markers, which is stack coloring of allocas. Stack coloring can
only work correctly if all lifetime markers for an alloca are
analyzable.

* If a lifetime marker may operate on multiple allocas via a select/phi,
we don't know which lifetime actually starts/ends and handle it
incorrectly (https://github.com/llvm/llvm-project/issues/104776).
* Stack coloring operates on the assumption that all lifetime markers
are visible, and not, for example, hidden behind a function call or
escaped pointer. It's not possible to change this, as part of the
purpose of lifetime markers is that they work even in the presence of
escaped pointers, where simple use analysis is insufficient.

I don't think there is any way to have coherent semantics for lifetime
markers on allocas, while also permitting them on arbitrary pointer
values.

This PR restricts lifetimes to operate on allocas only. As a followup, I
will also drop the size argument, which is superfluous if we always
operate on an alloca. (This change also renders various code handling
lifetime markers on non-alloca dead. I plan to clean up that kind of
code after dropping the size argument as well.)

In practice, I've only found a few places that currently produce
lifetimes on non-allocas:

* CoroEarly replaces the promise alloca with the result of an intrinsic,
which will later be replaced back with an alloca. I think this is the
only place where there is some legitimate loss of functionality, but I
don't think this is particularly important (I don't think we'd expect
the promise in a coroutine to admit useful lifetime optimization.)
* SafeStack moves unsafe allocas onto a separate frame. We can safely
drop lifetimes here, as SafeStack performs its own stack coloring.
* Similar for AddressSanitizer, it also moves allocas into separate
memory.
* LSR sometimes replaces the lifetime argument with a GEP chain of the
alloca (where the offsets ultimately cancel out). This is just
unnecessary. (Fixed separately in
https://github.com/llvm/llvm-project/pull/149492.)
* InferAddrSpaces sometimes makes lifetimes operate on an addrspacecast
of an alloca. I don't think this is necessary.
2025-07-21 15:04:50 +02:00
Shan Huang
853c343b45
[DebugInfo][NewGVN] Salvage debug values of trivially dead instructions (#149304)
fix #149301
2025-07-21 10:50:11 +08:00
Shan Huang
268c44f9ea
[DebugInfo][NewGVN] Fix debug value loss (#147634)
Fix #147511
2025-07-21 10:49:43 +08:00
Mariusz Sikora
33be70af9f
[NewGVN] Check intrinsic ID before accessing operands (#141571)
This patch is fixing assertions in downstream tests
2025-05-30 07:57:01 +02:00
ManuelJBrito
34d381f39d
[NewGVN] Fix lifetime coercion (#141477)
Before commit 14dee0a, NewGVN would not miscompile the function foo,
because `isMustAlias` would return false for non-pointers, particularly
for `lifetime.start`. We need to check whether the loaded pointer is
defined by`lifetime.start` in order to safely simplify the load to
uninitialized memory.

For `getInitialValueOfAllocation`, the behavior depends on the
allocation function. Therefore, we take a conservative approach: we
check whether it's a pointer type. If it is, then—based on the earlier
check—we know that the allocation function defines the loaded pointer.
2025-05-26 17:34:26 +01:00
ManuelJBrito
d69ffe6e48
[NewGVN] Precommit test (#141362)
Following 14dee0a and 3416d4f  the first function gets miscompiled.
2025-05-26 11:29:41 +01:00
Nikita Popov
d8b2e432d6
[IR] Remove mul constant expression (#127046)
Remove support for the mul constant expression, which has previously
already been marked as undesirable. This removes the APIs to create mul
expressions and updates tests to stop using mul expressions.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2025-02-14 09:28:57 +01:00
Nikita Popov
b7baf2ee8d [IR] Mark mul constant expression as undesirable
This is a (very belated) reland of 0a362f12ec60a49a054befec8620a8e69523af54,
which I originally reverted due to flang test failures.

This marks mul constant expressions as undesirable, which means that
we will no longer create them by default, but they can still be
created explicitly.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2025-02-13 10:27:36 +01:00
Lou
c75b251103
[GVN] Load-store forwaring of scalable store to fixed load. (#124748)
When storing a scalable vector and loading a fixed-size vector, where
the
scalable vector is known to be larger based on vscale_range, perform
store-to-load forwarding through temporary @llvm.vector.extract calls.
InstCombine then folds the insert/extract pair away.

The usecase is shown in https://godbolt.org/z/KT3sMrMbd, which shows
that clang generates IR that matches this pattern when the
"arm_sve_vector_bits" attribute is used:

```c
typedef svfloat32_t svfloat32_fixed_t
__attribute__((arm_sve_vector_bits(512)));

struct svfloat32_wrapped_t {
  svfloat32_fixed_t v;
};

static inline svfloat32_wrapped_t
add(svfloat32_wrapped_t a, svfloat32_wrapped_t b) {
  return {svadd_f32_x(svptrue_b32(), a.v, b.v)};
}

svfloat32_wrapped_t
foo(svfloat32_wrapped_t a, svfloat32_wrapped_t b) {
  // The IR pattern this patch matches is generated for this return:
  return add(a, b);
}
```
2025-01-30 11:49:42 +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
David Green
6d4e72abb8 [GVN] Add extra vscale tests with different types. NFC 2025-01-23 17:36:06 +00:00
Nikita Popov
10f315dc9c
[ConstantFolding] Infer getelementptr nuw flag (#119214)
Infer nuw from nusw and nneg. This is the constant expression variant of
https://github.com/llvm/llvm-project/pull/111144.

Proof: https://alive2.llvm.org/ce/z/ihztLy
2024-12-09 16:44:05 +01:00
Lee Wei
cefc1b0c21
[llvm] Remove br i1 undef from some regression tests [NFC] (#117292)
This PR removes tests with `br i1 undef` under
`llvm/tests/Transforms/MemCpyOpt, MergedLoadStoreMotion, NewGVN`.
2024-11-26 20:50:54 +00:00
Florian Hahn
46a08579f2
[Local] Only intersect alias.scope,noalias & parallel_loop if inst moves (#117716)
Preserve !alias.scope, !noalias and !mem.parallel_loop_access metadata
on the replacement instruction, if it does not move. In that case, the
program would be UB, if the aliasing property encoded in the metadata
does not hold. This makes use of the clarification re aliasing metadata
implying UB if the property does not hold: #116220

Same as #115868, but for !alias.scope, !noalias and
!mem.parallel_loop_access.


PR: https://github.com/llvm/llvm-project/pull/117716
2024-11-26 20:39:53 +00:00
Florian Hahn
0bb1b68330
[Local] Only intersect tbaa metadata if instr moves. (#116682)
Preserve tbaa metadata on the replacement instruction, if it does not
move. In that case, the program would be UB, if the aliasing property
encoded in the metadata does not hold.

This makes use of the clarification re tbaa metadata implying UB if the
property does not hold: https://github.com/llvm/llvm-project/pull/116220

Same as https://github.com/llvm/llvm-project/pull/115868, but for !tbaa

PR: https://github.com/llvm/llvm-project/pull/116682
2024-11-20 19:31:16 +00:00
Yingwei Zheng
984bca9d1f
[GVN][NewGVN] Take call attributes into account in expressions (#114545)
Drop `canBeReplacedBy` and take call attributes into account in
expressions.
Address comment
https://github.com/llvm/llvm-project/pull/114011#pullrequestreview-2409772313.
2024-11-08 16:00:48 +08:00
Paul Walker
38fffa630e
[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548) 2024-11-06 11:53:33 +00:00
Yingwei Zheng
f16bff1261
[GVN][NewGVN][Local] Handle attributes for function calls after CSE (#114011)
This patch intersects attributes of two calls to avoid introducing UB.
It also skips incompatible call pairs in GVN/NewGVN. However, I cannot
provide negative tests for these changes.

Fixes https://github.com/llvm/llvm-project/issues/113997.
2024-11-01 12:44:33 +08:00
ManuelJBrito
829992cf21
[NewGVN] Prevent cyclic dependencies by ensuring Leader has min RPO number (#82110)
Cyclic dependencies in NewGVN can result in miscompilation and
termination issues.

This patch ensures that the Class Leader is always the member with the
lowest RPO number. This ensures that the Class Leader is processed
before all other members, making the cyclic dependence impossible.

This fixes #35683.

Regressions: 

- 'simp-to-self.ll' regresses due to a known limitation in the way
NewGVN and InstSimplify interact. With the new leader, InstSimplify does
not know that %conv is 1 and fails to simplify.
2024-08-14 08:18:33 +01:00
ManuelJBrito
5b0dba13a5
[NewGVN] Fix caching for OpIsSafeForPhiOfOps (#98340)
The caching mechanism for 'OpIsSafeForPhiOfOps' is unsound. An operand
is deemed unsafe for PhiOfOps if it depends on a phi that resides in the
same block as the Phi block, i.e., where we are performing the PhiOfOps.
This is to avoid having to materialize the translated subexpressions. To
avoid redundant code walking, a cache is used to store these results.
Note, however, that since the safety is specific to the Phi block, we
cannot, in general, use the cached results for other blocks.

This patch addresses this by having a cache per block instead of a
single one for the entire function. closes #63335
2024-07-12 11:17:45 +01:00
Noah Goldstein
7c96469ea8 [ValueTracking] Extend LHS/RHS with matching operand to work without constants.
Previously we only handled the `L0 == R0` case if both `L1` and `R1`
where constant.

We can get more out of the analysis using general constant ranges
instead.

For example, `X u> Y` implies `X != 0`.

In general, any strict comparison on `X` implies that `X` is not equal
to the boundary value for the sign and constant ranges with/without
sign bits can be useful in deducing implications.

Closes #85557
2024-07-03 20:18:51 +08:00
Nikita Popov
d10b76552f
[ConstantFold] Remove notional over-indexing fold (#93697)
The data-layout independent constant folding currently has some rather
gnarly code for canonicalizing GEP indices to reduce "notional
overindexing", and then infers inbounds based on that canonicalization.

Now that we canonicalize to i8 GEPs, this canonicalization is
essentially useless, as we'll discard it as soon as the GEP hits the
data-layout aware constant folder anyway. As such, I'd like to remove
this code entirely.

This shouldn't have any impact on optimization capabilities.
2024-05-30 08:36:44 +02:00
Nikita Popov
8e8d2595da
[ConstantFolding] Canonicalize constexpr GEPs to i8 (#89872)
This patch canonicalizes constant expression GEPs to use i8 source
element type, aka ptradd. This is the ConstantFolding equivalent of the
InstCombine canonicalization introduced in #68882.

I believe all our optimizations working on constant expression GEPs
(like GlobalOpt etc) have already been switched to work on offsets, so I
don't expect any significant fallout from this change.

This is part of:
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699
2024-05-20 11:47:30 +02:00
Alex Voicu
10edb4991c
[Clang][CodeGen] Start migrating away from assuming the Default AS is 0 (#88182)
At the moment, Clang is rather liberal in assuming that 0 (and by extension unqualified) is always a safe default. This does not work for targets that actually use a different value for the default / generic AS (for example, the SPIRV that obtains from HIPSPV or SYCL). This patch is a first, fairly safe step towards trying to clear things up by querying a modules' default AS from the target, rather than assuming it's 0, alongside fixing a few places where things break / we encode the 0 == DefaultAS assumption. A bunch of existing tests are extended to check for non-zero default AS usage.
2024-05-19 14:59:03 +01:00
Alex Voicu
ab7dba233a
[CodeGen][LLVM] Make the va_list related intrinsics generic. (#85460)
Currently, the builtins used for implementing `va_list` handling
unconditionally take their arguments as unqualified `ptr`s i.e. pointers
to AS 0. This does not work for targets where the default AS is not 0 or
AS 0 is not a viable AS (for example, a target might choose 0 to
represent the constant address space). This patch changes the builtins'
signature to take generic `anyptr` args, which corrects this issue. It
is noisy due to the number of tests affected. A test for an upstream
target which does not use 0 as its default AS (SPIRV for HIP device
compilations) is added as well.
2024-03-27 11:41:34 +00:00
ManuelJBrito
229640343e
[NewGVN][NFC]Regenerate test checks (#85280)
Regenerate test checks for NewGVN.
2024-03-14 21:49:45 +00:00
Nikita Popov
2d69827c5c [Transforms] Convert tests to opaque pointers (NFC) 2024-02-05 11:57:34 +01:00
Alex Richardson
0359a78f77 Add target REQUIRES to 3 more tests
These tests all need an x86 backend for the correct data layout.
2023-10-26 17:41:05 -07:00
Alex Richardson
e39f6c1844 [opt] Infer DataLayout from triple if not specified
There are many tests that specify a target triple/CPU flags but no
DataLayout which can lead to IR being generated that has unusual
behaviour. This commit attempts to use the default DataLayout based
on the relevant flags if there is no explicit override on the command
line or in the IR file.

One thing that is not currently possible to differentiate from a missing
datalayout `target datalayout = ""` in the IR file since the current
APIs don't allow detecting this case. If it is considered useful to
support this case (instead of passing "-data-layout=" on the command
line), I can change IR parsers to track whether they have seen such a
directive and change the callback type.

Differential Revision: https://reviews.llvm.org/D141060
2023-10-26 12:07:37 -07:00
Nikita Popov
8e353fb6e9 [NewGVN] Patch replacement instruction even for removed instructions
When removing an instruction, we still need to merge its IR flags
into the leader, because there may have been a transitive use.

Fixes https://github.com/llvm/llvm-project/issues/53218.
2023-09-28 11:45:19 +02:00
Nikita Popov
fb8ce45a03 [NewGVN] Add another test for #53218 (NFC) 2023-09-26 15:06:19 +02:00
Nikita Popov
a09e32e5fe [InstSimplify] Respect UseInstrInfo in more folds
Some folds using m_NUW, m_NSW style matchers were missed, make
sure they respect UseInstrInfo.

This is part of #53218, but not a complete fix for the issue.
2023-09-26 13:54:03 +02:00
Nikita Popov
78c7201d68 [NewGVN] Regenerate test checks (NFC) 2023-09-26 13:54:03 +02:00
Nikita Popov
1d3e38bfb7 [NewGVN] Add test for #53218 (NFC) 2023-09-26 13:54:03 +02:00
Konstantina Mitropoulou
3583d40b3c
[NFC][NewGVN] Update assume_dominating_icmp.ll (#66711) 2023-09-18 23:47:48 -07:00
Konstantina Mitropoulou
135e5216ba
[NewGVN] Set parent to the temporal instructions that are generated during phi-of-ops optimization (#66314)
- Test for future commit in NewGVN
- [NewGVN] Set parent to the temporal instructions that are generated
during phi-of-ops optimization
2023-09-18 10:13:44 -07:00
Konstantina Mitropoulou
798f2465f3 [NewGVN] Decrement UseCount only if SSA copy has one use
Committing on behalf of @vladimirradosavljevic (Vladimir Radosavljevic)

Differential Revision : https: // reviews.llvm.org/D157267
2023-09-11 18:08:14 -07:00
ManuelJBrito
a1f5ea5b5f Revert "[NewGVN][PHIOFOPS] Relax conditions when checking safety of memory accesses"
NewGVN isn't enabled by default so some test failures were being missed.
Reverting to do more testing offline.

This reverts commit c59bc230e738036050f4c9b1ebde88699eec74bf.
2023-08-28 15:25:16 +01:00
Alina Sbirlea
89fa0dd1fb [MemorySSA] Handle queries with empty memory location. 2023-08-10 09:57:32 -07:00
ManuelJBrito
c59bc230e7 [NewGVN][PHIOFOPS] Relax conditions when checking safety of memory accesses
Currently, we consider any instruction that might read from memory to be unsafe for phi-of-ops.
This patch refines that by walking the clobbering memDefs until we either hit a block that
strictly dominates the phi block (safe) or we hit a clobbering memPhi (unsafe).

Differential Revision: https://reviews.llvm.org/D156055
2023-08-01 08:51:57 +01:00
ManuelJBrito
fb4a836b5c [NewGVN] Regenerate test checks (NFC)
Regenerate some test checks in  preparation for a patch that
fixes https://github.com/llvm/llvm-project/issues/53218.
2023-07-26 17:24:39 +01:00
ManuelJBrito
ace9b6bbf5 [NewGVN] Canonicalize expressions for commutative intrinsics
Ensure that commutative intrinsics that only differ by a permutation
of their operands get the same value number by sorting the operand value
numbers.

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

Differential Revision: https://reviews.llvm.org/D155309
2023-07-16 17:24:17 +01:00
Jay Foad
c0ad1b4597 [NewGVN] Fold equivalent freeze instructions
Differential Revision: https://reviews.llvm.org/D152529
2023-06-09 20:57:36 +01:00
Jay Foad
b27b5dcc00 [NewGVN] Precommit test for folding freeze
Differential Revision: https://reviews.llvm.org/D152528
2023-06-09 20:57:36 +01:00
Jay Foad
c86a1e6903 [GVN] Do not combine convergent calls in GVN/NewGVN
Note that this is very conservative since it will not even combine
convergent calls that appear in the same basic block, but EarlyCSE will
handle that case.

Differential Revision: https://reviews.llvm.org/D150974
2023-05-19 21:27:35 +01:00
Jay Foad
41a2c66aee [GVN] Precommit tests for convergent calls in GVN/NewGVN 2023-05-19 16:39:53 +01:00
Nikita Popov
11eb8d88d8 [NewGVN] Convert tests to opaque pointers (NFC) 2023-04-21 12:43:05 +02:00
Nikita Popov
1de68667eb [NewGVN] Regenerate test checks (NFC) 2023-04-21 12:43:05 +02:00