202 Commits

Author SHA1 Message Date
Benjamin Maxwell
cd16c706ba
[IRCE] Use function_ref<> instead of optional<function_ref<>> (NFC) (#151308)
llvm::function_ref<> is nullable.
2025-07-31 07:56:05 +01:00
Jan Ječmen
60d9e6fba8
[IRCE] Relax profitability check (#104659)
IRCE currently has two profitability checks:

1. min number of iterations (10 by default)
2. branch is highly biased (> 15/16)

However, it may still be profitable to eliminate range checks even if
the branch isn't as biased. Consider, for example, a loop with 100
iterations, where IRCE currently eliminates all 100 range checks. The
same range checks performed over a loop with 200 iterations aren't
eliminated because the branch is 50-50.

This patch proposes to relax the profitability checks of IRCE. Namely,
instead of the two checks currenly in place, consider IRCE profitable if
the branch probability scaled by the expected number of iterations
(i.e., the estimated number of eliminated checks) is over a threshold.
This covers the minimum number of iterations check (there are at least
as many iterations as eliminated range checks), and changes the bias
check from a percent of iterations to at least a constant threshold of
eliminated checks.

If the number of iterations can't be estimated, the check falls back to
the current 15/16 likelihood check.
2024-12-12 17:11:07 +01:00
Jan Ječmen
78db4e9f7b
[NFC][IRCE] Don't require LoopStructure to determine IRCE profitability (#116384)
This refactoring hoists the profitability check earlier in the pipeline,
so that for loops that are not profitable to transform there is no
iteration over the basic blocks or LoopStructure computation.

Motivated by PR #104659 that tweaks how the profitability of individual
branches is evaluated.
2024-12-04 11:09:19 +01:00
Kazu Hirata
94f9cbbe49
[Scalar] Remove unused includes (NFC) (#114645)
Identified with misc-include-cleaner.
2024-11-02 08:32:26 -07:00
Yingwei Zheng
22da5a6e34
[IRCE] Skip icmp ptr in InductiveRangeCheck::parseRangeCheckICmp (#89967)
Fixes https://github.com/llvm/llvm-project/issues/89959.
2024-04-26 16:25:33 +08:00
Kazu Hirata
a16429365c [Transforms] Remove unnecessary includes (NFC) 2023-12-09 18:23:06 -08:00
Kazu Hirata
92c2529ccd [llvm] Stop including vector (NFC)
Identified with clangd.
2023-12-03 22:32:21 -08:00
Mehdi Amini
23c24ed4bc Remove unused variable in lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
Fixing build warning.
2023-10-31 10:40:21 -07:00
Aleksandr Popov
483e92468e
[NFC] Extract LoopConstrainer from IRCE to reuse it outside the pass (#70508)
Co-authored-by: Aleksandr Popov <apopov@azul.com>
2023-10-31 18:16:59 +01:00
Fangrui Song
111fcb0df0 [llvm] Fix duplicate word typos. NFC
Those fixes were taken from https://reviews.llvm.org/D137338
2023-09-01 18:25:16 -07:00
Aleksandr Popov
236e6787de [IRCE] Add NSW to OverflowingBinaryOperator but not BinaryOperator
Fix incorrect setting NSW flag to non-overflowing indvar base (D154954)

Reviewed By: danilaml

Differential Revision: https://reviews.llvm.org/D156577
2023-07-30 11:14:26 +02:00
Aleksandr Popov
bca5501869 [IRCE] Add NSW flag to main loop's indvar base
We have guarantees that induction variable will not overflow in the main
loop after the loop constrained. Therefore we can add no wrap flags on
its base in order not to miss info that loop is countable.

Add NSW flag now, since adding NUW flag requires a bit more complicated
analysis.

Reviewed By: skatkov

Differential Revision: https://reviews.llvm.org/D154954
2023-07-17 01:03:52 +02:00
Aleksandr Popov
cdcefd2f9a [IRCE] Implement runtime overflow check for computed range's end
Here is activated check elimination which was parsed previously in
https://reviews.llvm.org/D154069

* Added runtime check that computed range's boundary doesn't overflow in
terms of range type.

* From the statement INT_MIN <= END <= INT_MAX is inferred check:
isNonNegative(INT_MAX - END) * isNonNegative(END - INT_MIN).

* If overflow happens, check will return 0 and the safe interval will be
empty.

Reviewed By: skatkov

Differential Revision: https://reviews.llvm.org/D154188
2023-07-12 11:19:25 +02:00
Aleksandr Popov
8b19cbfd77 Reland "[IRCE] Parse range checks in the form of 'LHS - RHS vs Limit'"
This reverts commit 4c6f95be29c6ce0f89663a5103c58ee63d76cda3

and relands e16c5c092205f68825466c25a1dd30783c4820f3

https://reviews.llvm.org/D154069
2023-07-11 18:48:14 +02:00
Aleksandr Popov
4c6f95be29 Revert "[IRCE] Parse range checks in the form of 'LHS - RHS vs Limit'"
This reverts commit e16c5c092205f68825466c25a1dd30783c4820f3.

Revert due to Buildbot failure https://lab.llvm.org/buildbot/#/builders/193
2023-07-10 13:59:22 +02:00
Aleksandr Popov
e16c5c0922 [IRCE] Parse range checks in the form of 'LHS - RHS vs Limit'
Introduced the following range checks forms parsing:
* IV - Offset vs Limit
* Offset - IV vs Limit

Range's end boundary is computed as (Offset +/- Limit ).

If it's not possible to prove at compile time that computed upper bound
will not overflow, then scale boundary computation to a wider type to
perform overflow check at runtime.

Runtime overflow will be implemented in the next patch. In the meantime
safe range for such kind of checks isn't computed.

Reviewed By: skatkov

Differential Revision: https://reviews.llvm.org/D154069
2023-07-10 13:00:38 +02:00
Aleksandr Popov
64e289cf51 [IRCE] Support inverted range check's predicate
IRCE expects true edge of range check's branch comes to loop.
If it meets reverse case - invert the branch.

Reviewed By: skatkov

Differential Revision: https://reviews.llvm.org/D148244
2023-07-03 23:20:17 +02:00
Aleksandr Popov
e7f48d735d [NFC][IRCE] Extract 'IV vs Limit' parsing to a separate method
Next step of the preparatory refactoring for the upcoming support of new
new range check form to parse.

This change isolates logic of 'IV vs Limit' range check parsing to
simplify adding parsers for new range checks forms.

Reviewed By: skatkov
Differential Revision: https://reviews.llvm.org/D154160
2023-07-03 10:19:21 +02:00
Aleksandr Popov
69f99f5308 [NFC][IRCE] Check that Index is AddRec in the parseRangeCheckICmp
Next step of the preparatory refactoring for the upcoming support of
new range check form to parse.

Previous one: https://reviews.llvm.org/D154156

With this change we avoid meaningless parsing after realizing that Index
is not AddRec

Reviewed By: skatkov
Differential Revision: https://reviews.llvm.org/D154158
2023-07-03 10:02:42 +02:00
Aleksandr Popov
f56e847362 [IRCE][NFC] Set Index and End together inside parseRangeCheckICmp
Preparatory refactoring for the upcoming support of new range check form
to parse.

With this change we always set Index and End values together in the same
place.

parseRangeCheckICmp specification updated.

Reviewed By: skatkov
Differential Revision: https://reviews.llvm.org/D154156
2023-07-03 05:21:05 +02:00
Aleksandr Popov
7e38ee6765 [NFC][IRCE] Remove dead variables 2023-07-03 02:53:25 +02:00
Nikita Popov
143ed21b26 Revert "[LCSSA] Remove unused ScalarEvolution argument (NFC)"
This reverts commit 5362a0d859d8e96b3f7c0437b7866e17a818a4f7.

In preparation for reverting a dependent revision.
2023-06-05 16:45:38 +02:00
Nikita Popov
5362a0d859 [LCSSA] Remove unused ScalarEvolution argument (NFC)
After D149435, LCSSA formation no longer needs access to
ScalarEvolution, so remove the argument from the utilities.
2023-05-02 12:17:05 +02:00
Max Kazantsev
b86b468731 [IRCE] Support non-strict range check's predicate
Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D148227
2023-04-21 18:33:30 +07:00
Max Kazantsev
88da596820 [IRCE][NFCI] Refactor parseRangeCheckICmp
Simplify parseRangeCheckICmp:
- If RHS is loop-variant, swap LHS/RHS and swap predicate
- all checks are either IV >(=) const or IV <(=) RHS (maybe not const)

Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D148720
2023-04-21 17:32:51 +07:00
Bjorn Pettersson
a20f7efbc5 Remove several no longer needed includes. NFCI
Mostly removing includes of InitializePasses.h and Pass.h in
passes that no longer has support for the legacy PM.
2023-04-17 13:54:19 +02:00
Bjorn Pettersson
0b911a3dc3 [passes] Remove the legacy PM version of IRCE
Differential Revision: https://reviews.llvm.org/D148338
2023-04-14 18:56:20 +02:00
Max Kazantsev
a39b807d41 [IRCE][NFC] Refactor parseRangeCheckICmp to compute SCEVs instead of Values
The motivation is to make an opportunity to compute and return
expressions after parsing ICmp into a range check (e.g. Length + 1).

Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D148205
2023-04-14 12:58:51 +07:00
Max Kazantsev
2124505fe4 [IRCE] Relax restrictions on IRCE's latch exit count
It seems that existing logic is too strict about latch block exit count.
It is required to be computable, however it is not used in any computations,
and effectively the only thing it is used for is to get the type of computed
exit count.

Sometimes the exit count for latch block is not known, but the loop is still
finite because of other exits, and safe bounds are still computable. In this case,
we miss an opportunity to apply IRCE.
We could instead use a more relaxed version - max symbolic exit count, which,
if exists, is enough to say that the loop is finite, and its type should be good enough.

There is a subtlety with type: we do not support latch count type wider than range
check type. Because of that, we want to have the narrowest type available. So if it
can be computed from latch block immediately, take it. Otherwise, take whatever whole
loop provides and hope that it's type isn't too wide.

Differential Revision: https://reviews.llvm.org/D147910
Reviewed By: danilaml
2023-04-13 16:00:19 +07:00
Max Kazantsev
246f8d4be5 [NFC][IRCE] Remove meaningless local variable 2023-04-13 13:04:45 +07:00
Max Kazantsev
d093d34c33 [IRCE][NFC] Remove unused variable IsSigned
Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D148113
2023-04-13 12:08:46 +07:00
Max Kazantsev
d0950d05a6 [NFC][IRCE] Do not store latch exit count
It is not actually used for any computations. Its only purpose is to
check that the loop is finite and find out the type of computed exit
count. Refactor code so that we only store this type.
2023-04-10 14:00:14 +07:00
Nikita Popov
ffe8f47d72 [IR] Add operator<< overload for CmpInst::Predicate (NFC)
I regularly try and fail to use this while debugging.
2023-03-07 15:10:56 +01:00
serge-sans-paille
38818b60c5
Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ part
Use deduction guides instead of helper functions.

The only non-automatic changes have been:

1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*))
2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase.
3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated.
4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that).

Per reviewers' comment, some useless makeArrayRef have been removed in the process.

This is a follow-up to https://reviews.llvm.org/D140896 that introduced
the deduction guides.

Differential Revision: https://reviews.llvm.org/D140955
2023-01-05 14:11:08 +01:00
Fangrui Song
51b685734b [Transforms,CodeGen] 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).
2022-12-16 23:21:27 +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
3152156334 [Transforms/Scalar] llvm::Optional => std::optional 2022-12-13 08:05:14 +00:00
Kazu Hirata
3eebbaf0e2 [llvm] Use std::optional instead of None in comments (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-10 17:09:01 -08:00
Kazu Hirata
f7dffc28b3 Don't include None.h (NFC)
I've converted all known uses of None to std::nullopt, so we no longer
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-10 11:24:26 -08:00
Kazu Hirata
2db77d2d39 [Scalar] Use std::optional in InductiveRangeCheckElimination.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-10 08:29:35 -08:00
Kazu Hirata
9f252e5567 [llvm] Use std::nullopt instead of None in comments (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-04 17:31:17 -08:00
Kazu Hirata
3c09ed006a [llvm] Use std::nullopt instead of None in comments (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-04 17:12:44 -08:00
Kazu Hirata
343de6856e [Transforms] 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 21:11:37 -08:00
Kazu Hirata
7fc772bbdc [Scalar] Use std::optional in InductiveRangeCheckElimination.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-11-25 23:59:45 -08:00
Dmitry Makogon
10ab29ec6e [IRCE] Bail out if AddRec in icmp is for another loop (PR58912)
When IRCE runs on outer loop and sees a check of an AddRec of
inner loop, it crashes with an assert in SCEV that the AddRec
must be loop invariant.
This adds a bail out if the AddRec which is checked in icmp
is for another loop.

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

Differential Revision: https://reviews.llvm.org/D137822
2022-11-14 15:06:13 +07:00
Max Kazantsev
0e465c0c2f [IRCE] Bail in case of pointer types. PR40539
We should not unconditionally expect that SCEVable types are all integers
because SCEV can also be computed for pointers. Bail in this case.
2022-09-12 16:01:25 +07:00
Max Kazantsev
ccf788a565 [IRCE] Drop SCEV of a Phi after adding a new input. PR57335
Since SCEV learned to look through single value phis with
20d798bd47ec5191de1b2a8a031da06a04e612e1, whenever we add
a new input to a Phi, we should make sure that the old cached
value is dropped. Otherwise, it may lead to various miscompiles,
such as breach of dominance as shown in the bug
https://github.com/llvm/llvm-project/issues/57335
2022-08-25 18:14:29 +07:00
Kazu Hirata
6b1bc80188 [Scalar] Qualify auto in range-based for loops (NFC)
Identified with readability-qualified-auto.
2022-08-20 21:18:25 -07:00
Fangrui Song
de9d80c1c5 [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.
2022-08-08 11:24:15 -07:00
Nikita Popov
dcf4b733ef [SCEVExpander] Make CanonicalMode handing in isSafeToExpand() more robust (PR50506)
isSafeToExpand() for addrecs depends on whether the SCEVExpander
will be used in CanonicalMode. At least one caller currently gets
this wrong, resulting in PR50506.

Fix this by a) making the CanonicalMode argument on the freestanding
functions required and b) adding member functions on SCEVExpander
that automatically take the SCEVExpander mode into account. We can
use the latter variant nearly everywhere, and thus make sure that
there is no chance of CanonicalMode mismatch.

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

Differential Revision: https://reviews.llvm.org/D129630
2022-07-14 14:41:51 +02:00