743 Commits

Author SHA1 Message Date
Max Kazantsev
dc9833067d [Test] Regenerate checks in some tests using auto-update script 2023-04-12 13:42:31 +07:00
Max Kazantsev
915a45c0a2 [Test] Add some more IndVars canonicalization tests 2023-04-11 12:37:10 +07:00
Florian Hahn
484c622760
[SCEV] Do not strengthen nuw/nsw flags during get[Zero,Sign]ExtendedExpr.
Modifying AddRecs when constructing other expressions can lead to
surprising changes. It also seems like it is not really beneficial i
most cases.

At the moment, there's a single regression, but we still might be able
to improve the flags at AddRec construction.

Might help with the issue discussed in D143409.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D144051
2023-03-15 20:57:34 +00:00
Nikita Popov
660403940c [SCEV] Fix finite loop non-strict predicate simplification (PR60944)
There are a number of issues with the current code for converting
ule -> ult (etc) predicates for comparisons controlling finite loops:

* It sets nowrap flags, which may only hold for that particular
  comparison, not globally. (PR60944)
* It doesn't check that the RHS is invariant. (I'm not sure this
  can cause practical issues independently of the previous point.)
* It runs before simplifications that may be more profitable. (PR54191)

This patch moves the handling for this into computeExitLimitFromICmp(),
because it is somewhat tightly coupled with assumptions in that code,
and addresses the aforementioned issues.

Fixes https://github.com/llvm/llvm-project/issues/60944.
Fixes https://github.com/llvm/llvm-project/issues/54191.

Differential Revision: https://reviews.llvm.org/D145510
2023-03-14 10:55:02 +01:00
Nikita Popov
f893d35c0d [IndVars] Add test for PR60944 (NFC) 2023-03-07 15:33:35 +01:00
Max Kazantsev
90f5176ab2 [Test] Add tests where we can replace IV check with invariant check basing on predicated backedge cond 2023-02-10 13:57:39 +07:00
Max Kazantsev
f3e2f26378 [IndVars] Expand icmp in preheader rather than in loop
The motivation is that 'createInvariantCond' unconditionally
builds icmp in the loop block,  while it could always do it
in preheader. Build it in preheader instead.

Patch by Aleksandr Popov!

Differential Revision: https://reviews.llvm.org/D141994
Reviewed By: nikic
2023-01-25 14:41:29 +07:00
Max Kazantsev
932ae48c27 [IndVars] Improve handling of multi-exit loops with known symbolic counts
This patch does two things, both related to support of multi-exit loops with
many exits that have known symbolic max exit count. They can theoretically
go independently, but I don't know how to write a test showing separate
impact.

Part 1: `SkipLastIter` can be set to `true` not when a particular exit has exit
count same as the whole loop (and therefore it must exit on the last iteration),
but when the aggregate of first few exits has umin same as whole loop exit count.
It means that it's not known which of them will exit exactly, but one of them will.

Part 2: when `SkipLastIter` is set, and exit count is `umin(a, b, c)`, instead of
`umin(a, b, c) - 1` use `umin(a - 1, b - 1, c - 1)`. We don't care about overflows
here, but the further logic knows how to deal with umin by element, but the
`SCEVAddExpr` node will confuse it.

Differential Revision: https://reviews.llvm.org/D141361
Reviewed By: nikic
2023-01-24 12:46:48 +07:00
Max Kazantsev
602916d2de [IndVars] Apply more optimistic SkipLastIter for AND/OR conditions
When exit by condition `C1` dominates exit by condition `C2`, and
max symbolic exit count for `C1` matches those for loop, we will
apply more optimistic logic to `C2` by setting `SkipLastIter` for it,
meaning that it will do 1 iteration less because the dominating branch
must exit on the last loop iteration.

But when we have a single exit by condition `C1 & C2`, we cannot
apply the same logic, because there is no dominating condition.

However, if we can prove that the symbolic max exit count of `C1 & C2`
matches those of `C1`, it means that for `C2` we can assume that it
doesn't matter on the last iteration (because the whole thing is `false`
because `C1` must be `false`). Therefore, in this situation, we can handle
`C2` as if it had `SkipLastIter`.

Differential Revision: https://reviews.llvm.org/D139934
Reviewed By: nikic
2023-01-24 12:26:22 +07:00
Jannik Silvanus
986029c164 [Transforms] Fix i8 alignment in datalayout of lit test
A lit test used overaligned i8, apparently due to an old copy-paste
error, intending to specify i16 alignment.

Change the datalayout string to use naturally aligned i8.
2023-01-20 15:52:07 +01:00
Max Kazantsev
32aea4bb84 [Test] Add test showing one more missing case of turn-to-invariant with widening 2023-01-11 13:07:38 +07:00
Owen Anderson
90c1846629 Do not short circuit hoistIVInc when recomputation of poison flags is needed.
Fixes https://github.com/llvm/llvm-project/issues/59777

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D140836
2023-01-10 23:03:07 -07:00
Max Kazantsev
fae63a9a22 [Test] Give test variables more reasonable names 2023-01-11 12:29:26 +07:00
Max Kazantsev
9f37ecf8fa [IndVars] Support AND/OR in optimizeLoopExitWithUnknownExitCount
This patch allows optimizeLoopExitWithUnknownExitCount to deal with
branches by conditions that are not immediately ICmp's, but aggregates
of ICmp's joined by arithmetic or logical AND/OR. Each ICmp is optimized
independently.

Differential Revision: https://reviews.llvm.org/D139832
Reviewed By: nikic
2023-01-11 11:36:02 +07:00
Max Kazantsev
3602d852a5 [Test] One more test where check is not replaced to invariant
Irrelevant constant check makes things even more difficult, surprisingly.
2023-01-09 19:26:48 +07:00
Max Kazantsev
ba2bb63562 [Test] Add tests with logical AND/OR 2022-12-27 08:58:12 +07:00
Max Kazantsev
5f24f893ca [Test] Update inverse test for turn-to-invariant to what they meant to be
They were supposed to test inverted branches with OR condition, not AND.
Fixed this now.
2022-12-26 16:01:18 +07:00
Max Kazantsev
d02c3b1358 [Test] Add test showing potential conflict b/w AND elimination and IV widening 2022-12-26 14:37:49 +07:00
Max Kazantsev
9a7286b61f [SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex umin exit counts. PR59615
Recent improvements in symbolic exit count computation revealed some problems with
SCEV's ability to find invariant predicate during first iterations. Ultimately it is based on its
ability to prove some facts for value on the last iteration. This last value, when it includes
`umin` as part of exit count, isn't always simplified enough. The motivating example is following:

https://github.com/llvm/llvm-project/issues/59615

Could not prove:
```
        Pred = 36, LHS = (-1 + (-1 * (2147483645 umin (-1 + %var)<nsw>))<nsw> + %var), RHS = %var
        FoundPred = 36, FoundLHS = {1,+,1}<nuw><nsw><%bb3>, FoundRHS = %var
```
Can prove:
```
        Pred = 36, LHS = (-1 + (-1 * (-1 + %var)<nsw>)<nsw> + %var), RHS = %var
        FoundPred = 36, FoundLHS = {1,+,1}<nuw><nsw><%bb3>, FoundRHS = %var
```

Here ` (2147483645 umin (-1 + %var)<nsw>)` is exit count composed of two parts from
two different exits: `2147483645 ` and `(-1 + %var)<nsw>`. When it was only one (latter)
analyzeable exit, for it everything was easily provable. Unfortunately, in general case `umin`
in one of `add`'s operands doesn't guarantee that the whole sum reduces, especially in presence
of negative steps and lack of `nuw`. I don't think there is a generic legal way to somehow play
around this `umin`.

So the ad-hoc solution is following: if we failed to find an equivalent predicate that is invariant
during first `MaxIter` iterations, and `MaxIter = umin(a, b, c...)`, try to find solution for at least one
of `a`, `b`, `c`... Because they all are `uge` than `MaxIter`, whatever is true during `a (b, c)` iterations
is also true during `MaxIter` iterations.

Differential Revision: https://reviews.llvm.org/D140456
Reviewed By: nikic
2022-12-21 18:12:17 +07:00
Max Kazantsev
474c8fe9b7 [Test] Precommit test for PR59615 2022-12-21 11:39:05 +07:00
Roman Lebedev
af1f1b064a
[NFC] Fixup checkline confusion 2022-12-14 17:53:06 +03:00
Roman Lebedev
da80639ee2
[NFC][IndVar] Autogenerate checklines in one test 2022-12-14 17:39:10 +03:00
Nikita Popov
3ce360f15b [IndVarSimplify] Convert more tests to opaque pointers (NFC) 2022-12-14 15:37:58 +01:00
Nikita Popov
8b7b5f9cfe [IndVarSimplify] Regenerate test checks (NFC) 2022-12-14 15:35:58 +01:00
Florian Hahn
6e86b544dd
[SCEV] Cache folded SExt SCEV expressions.
Use FoldID to cache SignExtendExprs that get folded to a different
SCEV.

Depends on D137505.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D137849
2022-12-14 11:59:19 +00:00
Nikita Popov
bf4aeefed4 [IndVarSimplify] Convert last test to opaque pointers (NFC)
After addressing the SCEVExpander issue that caused me pause.

Also delete a redundant test that is no longer needed.
2022-12-13 15:20:35 +01:00
Nikita Popov
5810927dcb [SCEVExpander] Produce canonical constant GEP
Go through IRBuilder to enable DL-based folding, so that we produce
a canonical constant GEP. Noticed while converting tests to opaque
pointers.
2022-12-13 15:08:28 +01:00
Nikita Popov
864bb84a42 [IndVarSimplify] Convert tests to opaque pointers (NFC)
This leaves lftr.ll alone, because there is a suspicious test diff.
2022-12-13 14:50:13 +01:00
Max Kazantsev
4de67273e6 [Test] Regenerate checks in turn-to-invariant.ll
Due to changes in update script, it now has 'define' prefix in every check,
which is distracting.
2022-12-12 19:17:05 +07:00
Max Kazantsev
bb4a955f27 [Test] Add some IndVars test with swapped true/false branches
Just to make sure our transforms work correctly with them.
2022-12-12 19:08:00 +07:00
Florian Hahn
afe3558a0b
[SCEV] Cache ZExt SCEV expressions.
When creating SCEV expressions for ZExt, there's quite a bit of
reasoning done and in many places the reasoning in turn will try to
create new SCEVs for other ZExts.

This can have a huge compile-time impact. The attached test from #58402
takes an excessive amount of compile time; without the patch, the test
doesn't complete in 1500+ seconds, but with the patch it completes in 1
second.

To speed up this case, cache created ZExt expressions for given (SCEV, Ty) pairs.
Caching just ZExts is relatively straight-forward, but it might make
sense to extend it to other expressions in the future.

This has a slight positive impact on CTMark:
* O3: -0.03%
* ReleaseThinLTO: -0.03%
* ReleaseLTO-g: 0.00%

https://llvm-compile-time-tracker.com/compare.php?from=bf9de7464946c65f488fe86ea61bfdecb8c654c1&to=5ac0108553992fb3d58bc27b1518e8cf06658a32&stat=instructions:u

The patch also improves compile-time for some internal real-world workloads
where time spent in SCEV goes from ~300 seconds to ~3 seconds.

There are a few cases where computing & caching the result earlier may
return more pessimistic results, but the compile-time savings seem to
outweigh that.

Fixes #58402.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D137505
2022-12-09 22:14:04 +00:00
Max Kazantsev
262f2fed65 [IndVars] Use symbolic max block exit count to handle the last iter
Old logic: when loop symbolic max exit count matched *exact* block exit count,
assume that all subsequent blocks will do 1 iteration less.

New logic: when loop symbolic max exit count matched *symbolic max* block exit count,
assume that all subsequent blocks will do 1 iteration less.

The new logic is still legal and is more permissive in situations when exact
block exit count is not known.

Differential Revision: https://reviews.llvm.org/D139692
Reviewed By: nikic
2022-12-09 17:06:29 +07:00
Bjorn Pettersson
3528e63d89 [test] Remove duplicate RUN lines in Transform tests 2022-12-08 11:47:16 +01:00
Roman Lebedev
67bbdd05c4
[NFC] Port all IndVarSimplify tests to -passes= syntax 2022-12-08 02:38:44 +03:00
Roman Lebedev
6017d9a628
[NFC] Port all IndVarSimplify tests to -passes= syntax 2022-12-07 22:22:09 +03:00
Roman Lebedev
46db90cc71
[SCEV] MatchBinaryOp(): try to recognize or as add-in-disguise (w/ no common bits set)
LLVM *loves* to convert `add` of operands with no common bits
into an `or`. But SCEV really doesn't deal with `or` that well,
so try extra hard to recognize this `or` as an `add`.

I believe, previously this wasn't being done because of the recursive
of this, but now that the `createSCEV()` is not recursive,
this should be fine. Unless this is *too* costly compile-time wise...

https://alive2.llvm.org/ce/z/EfapCo
2022-12-06 20:26:53 +03:00
Max Kazantsev
798fa4b415 [Test] Add 2 more simplified test with missing opts
These are simplified versions of one existing test, but we cannot deal
with them either.
2022-12-05 15:57:49 +07:00
Bjorn Pettersson
a11faeed44 [test] Switch to use -passes syntax in various test cases 2022-12-01 21:25:59 +01:00
Max Kazantsev
57fd7ffeff [IndVarSimplify] Lift limitations on IV being a Phi for turn-to-invariant
These limitations are too strict, and their only purpose is to avoid code
size explosion. These restrictions seem obsolete, and the size problem
is solved in other places through cheap expansion limits.

The motivation is that the old code cannot deal with comparisons against
induction variant's increment.

Differential Revision: https://reviews.llvm.org/D138412
Reviewed By: lebedev.ri, reames
2022-11-22 12:53:37 +07:00
Florian Hahn
5dad4c6788
[SCEV] Iteratively compute ranges for deeply nested expressions.
At the moment, getRangeRef may overflow the stack for very deeply nested
expressions.

This patch introduces a new getRangeRefIter function, which first builds
a worklist of N-ary expressions and phi nodes, followed by their
operands iteratively.

getRangeRef has been extended to also take a Depth argument and it
switches to use getRangeRefIter once the depth reaches a certain
threshold.

This ensures compile-time is not impacted in general. Note that
the iterative algorithm may lead to a slightly different evaluation
order, which could result in slightly worse ranges for cyclic phis.

https://llvm-compile-time-tracker.com/compare.php?from=23c3eb7cdf3478c9db86f6cb5115821a8f0f5f40&to=e0e09fa338e77e53242bfc846e1484350ad79773&stat=instructions

Fixes #49579.

Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D130728
2022-11-21 21:56:14 +00:00
Max Kazantsev
41e41cc2c4 [Test] Add some test showing limitations of makeIVComparisonInvariant
The transform doesn't work if argument isn't immediately a Phi.
2022-11-21 16:20:36 +07:00
Max Kazantsev
5a62e6b485 [Test] One more test for IndVars, showing imperfect work with context 2022-11-21 15:14:48 +07:00
Max Kazantsev
c61f37b984 [Test] Add some examples where IndVars fails to turn condition into invariant 2022-11-21 13:42:28 +07:00
luxufan
49143f9d14 [IndVars] Forget the SCEV when the instruction has been sunk.
In the past, the SCEV expression of the sunk instruction was not
forgetted. This led to the incorrect block dispositions after the
instruction be sunk.

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

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D137060
2022-11-06 22:46:49 +08:00
Florian Hahn
9a456b7ad3
[IndVars] Forget SCEV for replaced PHI.
Additional SCEV verification highlighted a case where the cached loop
dispositions where incorrect after simplifying a phi node in IndVars.
Fix it by invalidating the phi before replacing it.

Fixes #58750
2022-11-04 18:42:07 +00:00
Florian Hahn
e83e289fd1
[SCEVExpander] Forget SCEV when replacing congruent phi.
Otherwise there may be stale values left over in the cache, causing a
SCEV verification failure.

Fixes #58702.
2022-11-01 17:49:38 +00:00
Florian Hahn
fd236772f5
[IndVars] Forget SCEV for value after simplifying condition.
Additional SCEV verification highlighted a case where the cached loop
dispositions where incorrect after simplifying a condition in IndVars
and moving the user in LoopDeletion. Fix it by invalidating ICmp and all
its users.

Fixes #58515.
2022-10-21 11:18:01 +01:00
Florian Hahn
c65513444b
[IndVars] Forget SCEV for instruction and users before replacing it.
Extra invalidation is needed here to clear stale values to fix a
verification failure.

Fixes #58440.
2022-10-18 17:38:14 +01:00
Florian Hahn
a8e9742bd4
[IndVarSimplify] Clear block and loop dispositions after moving instr.
Moving an instruction can invalidate the cached block dispositions of
the corresponding SCEV. Invalidate the cached dispositions.

Also fixes a copy-paste error in forgetBlockAndLoopDispositions where
the start expression S was removed from BlockDispositions in the loop
but not the current values. This was also exposed by the new test case.

Fixes #58439.
2022-10-18 16:18:14 +01:00
Bjorn Pettersson
f15ed06a65 [test][IndVarSimplify] Use -passes syntax in RUN lines. NFC 2022-10-13 10:44:37 +02:00