110 Commits

Author SHA1 Message Date
Max Kazantsev
ad3b1fe472 [SCEV] Do not erase LoopUsers. PR53969
This patch fixes a logical error in how we work with `LoopUsers` map.
It maps a loop onto a set of AddRecs that depend on it. The Addrecs
are added to this map only once when they are created and put to
the UniqueSCEVs` map.

The only purpose of this map is to make sure that, whenever we forget
a loop, all (directly or indirectly) dependent SCEVs get forgotten too.

Current code erases SCEVs from dependent set of a given loop whenever
we forget this loop. This is not a correct behavior due to the following scenario:

1. We have a loop `L` and an AddRec `AR` that depends on it;
2. We modify something in the loop, but don't destroy it. We still call forgetLoop on it;
3. `AR` is no longer dependent on `L` according to `LoopUsers`. It is erased from
    ValueExprMap` and `ExprValue map, but still exists in UniqueSCEVs;
4. We can later request the very same AddRec for the very same loop again, and get existing
    SCEV `AR`.
5. Now, `AR` exists and is used again, but its notion that it depends on `L` is lost;
6. Then we decide to delete `L`. `AR` will not be forgotten because we have lost it;
7. Just you wait when you run into a dangling pointer problem, or any other kind of problem
   because an active SCEV is now referecing a non-existent loop.

The solution to this is to stop erasing values from `LoopUsers`. Yes, we will maybe forget something
that is already not used, but it's cheap.

This fixes a functional bug and potentially may have negative compile time impact on methods with
huge or numerous loops.

Differential Revision: https://reviews.llvm.org/D120303
Reviewed By: nikic
2022-02-22 17:24:39 +07:00
Max Kazantsev
9453cda088 [Test] Move test for PR53969 to LoopDeletion folder where it truly belongs 2022-02-21 18:39:31 +07:00
Philip Reames
523573e90d [LoopDeletion] Revert 3af8a11 and add test coverage for breakage
This reverts 3af8a11 because I'd used an upper bound where an lower bound was required.  The included reduced test case demonstrates the issue.
2022-01-17 11:44:03 -08:00
Nick Desaulniers
79ebc3b0dd [llvm][test] rewrite callbr to use i rather than X constraint NFC
In D115311, we're looking to modify clang to emit i constraints rather
than X constraints for callbr's indirect destinations. Prior to doing
so, update all of the existing tests in llvm/ to match.

Reviewed By: void, jyknight

Differential Revision: https://reviews.llvm.org/D115410
2022-01-11 11:31:08 -08:00
Max Kazantsev
4c0da23663 [LoopDeletion] Support selects when symbolically evaluating 1st iteration
Adds support for selects for which we know value on the 1st iteration.

Differential Revision: https://reviews.llvm.org/D104111
Reviewed By: nikic
2021-10-09 14:47:44 +07:00
Arthur Eubanks
37e6a27da7 [test] Fixup tests with -analyze in llvm/test/Transforms 2021-09-04 16:45:51 -07:00
Philip Reames
c3b3aa277a Fix a missing MemorySSA update in breakLoopBackedge
This is a case I'd missed in 6a8237. The odd bit here is that missing the edge removal update seems to produce MemorySSA which verifies, but is still corrupt in a way which bothers following passes. I wasn't able to reduce a single pass test case, which is why the reported test case is taken as is.

Differential Revision: https://reviews.llvm.org/D109068
2021-09-01 16:59:01 -07:00
Philip Reames
c7b25e4359 [LoopDeletion] Use max trip count to break backedge in addition to exact one
We'd added support a while back from breaking the backedge if SCEV can prove the trip count is zero. However, we used the exact trip count which requires *all* exits be analyzeable. I noticed while writing test cases for another patch that this disallows cases where one exit is provably taken paired with another which is unknown. This patch adds the upper bound case.

We could use a symbolic max trip count here instead, but we use an isKnownNonZero filter (presumably for compile time?) for the first-iteration reasoning. I decided this was a more obvious incremental step, and we could go back and untangle the schemes separately.

Differential Revision: https://reviews.llvm.org/D108833
2021-08-27 14:19:44 -07:00
Philip Reames
6a82376012 Special case common branch patterns in breakLoopBackedge (try 2)
Changes since aec08e:
* Adjust placement of a closing brace so that the general case actually runs.  Turns out we had *no* coverage of the switch case.  I added one in eae90fd.
* Drop .llvm.loop.* metadata from the new branch as there is no longer a loop to annotate.

Original commit message:

This special cases an unconditional latch and a conditional branch latch exit to improve codegen and test readability. I am hoping to reuse this function in the runtime unroll code, but without this change, the test diffs are far too complex to assess.
2021-08-27 10:27:16 -07:00
Philip Reames
eae90fdc75 [test] exercise breakLoopBackedge with a switch latch cond
This was reduced from a test case which triggered a revert to my recent change to same function.  It turns out we didn't have *any* coverage of the non-branch latch and my patch was blatantly broken.
2021-08-27 10:11:13 -07:00
Philip Reames
1e07f19bfc Revert "Special case common branch patterns in breakLoopBackedge"
This reverts commit aec08e86004bb3b8a7c5a86992945c936593db59.

Several problems have been reported with malformed loopinfo after this change, see discussion on https://reviews.llvm.org/rGaec08e86004b.
2021-08-24 08:53:42 -07:00
Philip Reames
aec08e8600 Special case common branch patterns in breakLoopBackedge
This special cases an unconditional latch and a conditional branch latch exit to improve codegen and test readability.  I am hoping to reuse this function in the runtime unroll code, but without this change, the test diffs are far too complex to assess.
2021-08-22 10:42:23 -07:00
Nikita Popov
33146857e9 [IR] Consider non-willreturn as side effect (PR50511)
This adjusts mayHaveSideEffect() to return true for !willReturn()
instructions. Just like other side-effects, non-willreturn calls
(aka "divergence") cannot be removed and cannot be reordered relative
to other side effects. This fixes a number of bugs where
non-willreturn calls are either incorrectly dropped or moved. In
particular, it also fixes the last open problem in
https://bugs.llvm.org/show_bug.cgi?id=50511.

I performed a cursory review of all current mayHaveSideEffect()
uses, which convinced me that these are indeed the desired default
semantics. Places that do not want to consider non-willreturn as a
sideeffect generally do not want mayHaveSideEffect() semantics at
all. I identified two such cases, which are addressed by D106591
and D106742. Finally, there is a use in SCEV for which we don't
really have an appropriate API right now -- what it wants is
basically "would this be considered forward progress". I've just
spelled out the previous semantics there.

Differential Revision: https://reviews.llvm.org/D106749
2021-07-26 16:35:14 +02:00
Nikita Popov
c7e69e46c8 [Tests] Add additional tests for incorrect willreturn handling (NFC)
Highlight a few of the places that don't handle non-willreturn
calls correctly right now.
2021-07-24 17:27:29 +02:00
Roman Lebedev
d7378259aa
[SimplifyCFG] SimplifyCondBranchToTwoReturns(): really only deal with different ret blocks
This function is called when some predecessor of an empty return block
ends with a conditional branch, with both successors being empty ret blocks.

Now, because of the way SimplifyCFG works, it might happen to simplify
one of the blocks in a way that makes a conditional branch
into an unconditional one, since it's destinations are now identical,
but it might not have actually simplified said conditional branch
into an unconditional one yet.

So, we have to check that ourselves first,
especially now that SimplifyCFG aggressively tail-merges
all ret and resume blocks.

Even if it was an unconditional branch already,
`SimplifyCFGOpt::simplifyReturn()` doesn't call `FoldReturnIntoUncondBranch()`
by default.
2021-07-23 00:36:59 +03:00
Roman Lebedev
0d4f2de303
[NFC][LoopDeletion] Autogenerate checlines in simplify-then-delete.ll test 2021-07-23 00:36:59 +03:00
Nikita Popov
f59209a86e [AsmParser] Unify parsing of attributes
Continuing on from D105780, this should be the last major bit of
attribute cleanup. Currently, LLParser implements attribute parsing
for functions, parameters and returns separately, enumerating all
supported (and unsupported) attributes each time. This patch
extracts the common parsing logic, and performs a check afterwards
whether the attribute is valid in the given position. Parameters
and returns are handled together, while function attributes need
slightly different logic to support attribute groups.

Differential Revision: https://reviews.llvm.org/D105938
2021-07-15 17:51:11 +02:00
Max Kazantsev
9c5e65691e [LoopDeletion] Handle switch in proving that loop exits on first iteration
Added check for switch-terminated blocks in loops.
Now if a block is terminated with a switch, we try to find out which of the
cases is taken on 1st iteration and mark corresponding edge from the block
to the case successor as live.

Patch by Dmitry Makogon!

Differential Revision: https://reviews.llvm.org/D105688
Reviewed By: nikic, mkazantsev
2021-07-09 18:03:34 +07:00
Max Kazantsev
767eb9f9d5 [Test] Add loop deletion switch tests
Patch by Dmitry Makogon!

Differential Revision: https://reviews.llvm.org/D105543
2021-07-08 17:28:08 +07:00
Max Kazantsev
7c73c2ede8 [LoopDeletion] Benefit from branches by undef conditions when symbolically executing 1st iteration
We can exploit branches by `undef` condition. Frankly, the LangRef says that
such branches are UB, so we can assume that all outgoing edges of such blocks
are dead.

However, from practical perspective, we know that this is not supported correctly
in some other places. So we are being conservative about it.

Branch by undef is treated in the following way:
- If it is a loop-exiting branch, we always assume it exits the loop;
- If not, we arbitrarily assume it takes `true` value.

Differential Revision: https://reviews.llvm.org/D104689
Reviewed By: nikic
2021-06-28 11:39:46 +07:00
Max Kazantsev
842b4c83cb [LoopDeletion] Exploit undef Phi inputs when symbolically executing 1st iteration
Follow-up on Roman's idea expressed in D103959.
- If a Phi has undefined inputs from live blocks:
   - and no other inputs, assume it is undef itself;
   - and exactly one non-undef input, we can assume that all undefs are equal to this input.

Differential Revision: https://reviews.llvm.org/D104618
Reviewed By: lebedev.ri, nikic
2021-06-23 11:53:48 +07:00
Max Kazantsev
976926e8ee [Test] Clear out br i1 undef from tests to avoid UB
We don't want to test possible unexpected impact of such
branches. Replacing them with regular conditions. Idea by
Nikita Popov.
2021-06-23 11:33:57 +07:00
Max Kazantsev
4c4f1ae93e Re-land "[LoopDeletion] Handle Phis with similar inputs from different blocks"
Patch was reverted due to a bug that existed before it and was exposed
by it. Returning after the underlying bug has been fixed.

Differential Revision: https://reviews.llvm.org/D103959
2021-06-22 12:28:46 +07:00
Max Kazantsev
575253887b [LoopDeletion] Require loop to have a predecessor when executing 1st iteration symbolically
Two predecessors break the further logic, and the loop may come to the
opt in non-canonicalized state.
2021-06-22 12:20:55 +07:00
Nathan Chancellor
f52666985d
Revert "[LoopDeletion] Handle Phis with similar inputs from different blocks"
This reverts commit bb1dc876ebb8a2eef38d5183d00c2db1437f1c91.

This patch causes an assertion failure when building an arm64 defconfig
Linux kernel.

See https://reviews.llvm.org/D103959 for a link to the original bug
report and a reduced reproducer.
2021-06-21 10:18:55 -07:00
Max Kazantsev
3f2ff7cc8c [Test] Add some tests showing room for optimization exploiting undef and UB 2021-06-21 13:11:46 +07:00
Max Kazantsev
bb1dc876eb [LoopDeletion] Handle Phis with similar inputs from different blocks
This patch lifts the requirement to have the only incoming live block
for Phis. There can be multiple live blocks if the same value comes to
phi from all of them.

Differential Revision: https://reviews.llvm.org/D103959
Reviewed By: nikic, lebedev.ri
2021-06-21 11:37:06 +07:00
Max Kazantsev
de92287cf8 [LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration (try 3)
This patch handles one particular case of one-iteration loops for which SCEV
cannot straightforwardly prove BECount = 1. The idea of the optimization is to
symbolically execute conditional branches on the 1st iteration, moving in topoligical
order, and only visiting blocks that may be reached on the first iteration. If we find out
that we never reach header via the latch, then the backedge can be broken.

This implementation uses InstSimplify. SCEV version was rejected due to high
compile time impact.

Differential Revision: https://reviews.llvm.org/D102615
Reviewed By: nikic
2021-06-18 17:31:57 +07:00
Florian Hahn
f7fc8927c0
[LoopDeletion] Check for irreducible cycles when deleting loops.
Loops with irreducible cycles may loop infinitely. Those cannot be
removed, unless the loop/function is marked as mustprogress.

Also discussed in D103382.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D104238
2021-06-15 12:56:12 +01:00
Florian Hahn
ee9bb258bb
[LoopDeletion] Add test with irreducible control flow in loop.
Currently the irreducible cycles in the loops are ignored. The
irreducible cycle may loop infinitely in
irreducible_subloop_no_mustprogress, which is allowed and the loop
should not be removed.

Discussed in D103382.
2021-06-14 17:42:32 +01:00
Max Kazantsev
8840c94a33 [Test] One more elaborate test with selects for loop deletion 2021-06-11 18:41:34 +07:00
Max Kazantsev
8dc2c1a0ab [Test] Add loop deletion test with switch 2021-06-11 18:05:07 +07:00
Max Kazantsev
0120e6c295 [Test] Add more elaborate case of symbolic execution of 1-iteration loop 2021-06-09 19:08:54 +07:00
Florian Hahn
1b84acb23a
[LoopDeletion] Consider infinite loops alive, unless mustprogress.
The current loop or any of its sub-loops may be infinite. Unless the
function or the loops are marked as mustprogress, this in itself makes
the loop *not* dead.

This patch moves the logic to check whether the current loop is finite
or mustprogress to `isLoopDead` and also extends it to check the
sub-loops. This should fix PR50511.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D103382
2021-06-01 13:07:36 +01:00
Max Kazantsev
4ef47eaed9 [Test] Add one more loop deletion irreducible CFG test 2021-06-01 11:11:15 +07:00
Florian Hahn
5c9fe816e3
[LoopDeletion] Add additional test cases with more nested loops.
Also remove mustprogress function attribute from one of the tests

Extends test coverage for D103382.
2021-05-31 20:27:07 +01:00
Florian Hahn
268e24a46a
[LoopDeletion] Add more tests with infinite sub-loops & mustprogress.
A couple of additional tests inspired by PR50511.
2021-05-30 16:41:57 +01:00
Stefan Pintilie
0159652058 Revert "Return "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration" (try 2)"
This reverts commit be1a23203b1de655b8c7dac7549818d975a0cbbf.
2021-05-28 12:21:22 -05:00
Florian Hahn
2ee59f75fe
[LoopDeletion] Add test with potentially infinite sub-loop.
Tests for PR50511.
2021-05-28 17:45:44 +01:00
Max Kazantsev
be1a23203b Return "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration" (try 2)
The patch was reverted due to compile time impact of contextual SCEV
queries. It also appeared that it introduced a miscompile on irreducible CFG.

Changes made:
1. isKnownPredicateAt is replaced with more lightweight isKnownPredicate;
2. Irreducible CFG in live code is now detected and excluded from processing.

Differential Revision: https://reviews.llvm.org/D102615
2021-05-26 19:47:14 +07:00
Max Kazantsev
0de553dce0 Revert "Return "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration""
This reverts commit 43d2e51c2e86788b9e2a582fdd3d8ffa7829328a.

Commited wrong version.
2021-05-26 19:29:07 +07:00
Max Kazantsev
43d2e51c2e Return "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration"
The patch was reverted due to compile time impact of contextual SCEV
queries. It also appeared that it introduced a miscompile on irreducible CFG.

Changes made:
1. isKnownPredicateAt is replaced with more lightweight isKnownPredicate;
2. Irreducible CFG in live code is now detected and excluded from processing.

Differential Revision: https://reviews.llvm.org/D102615
2021-05-26 19:23:21 +07:00
Max Kazantsev
5fb58d4598 [Test] Add Loop Deletion test with irreducible CFG
Authored by Mikael Holmén. It demonstrated miscompile on irreducible
CFG with patch "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration".
The patch is reverted. Checking in the test to make sure this bug
does not return.
2021-05-26 18:40:14 +07:00
Max Kazantsev
7ee863b8eb [Test] Add simplified versions of tests for loop deletion that don't need context 2021-05-26 16:39:00 +07:00
Matt Morehouse
832c99f727 Revert "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration"
This reverts commit 2531fd70d19aa5d61feb533bbdeee7717a4129eb due to
performance regression on the PPC buildbot.
2021-05-25 13:58:42 -07:00
Max Kazantsev
2531fd70d1 [LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration
This patch handles one particular case of one-iteration loops for which SCEV
cannot straightforwardly prove BECount = 1. The idea of the optimization is to
symbolically execute conditional branches on the 1st iteration, moving in topoligical
order, and only visiting blocks that may be reached on the first iteration. If we find out
that we never reach header via the latch, then the backedge can be broken.

Differential Revision: https://reviews.llvm.org/D102615
Reviewed By: reames
2021-05-25 12:43:31 +07:00
Max Kazantsev
ce24524604 [Test] Add test for unreachable backedge with duplicating predecessors 2021-05-25 12:43:31 +07:00
Max Kazantsev
26b1df8b72 [Test] Auto-generate checks in a test (prepring to update) 2021-05-17 18:26:47 +07:00
Max Kazantsev
557906d3be [Test] Fix test to make the transform for which is was added legal
%limit in these tests is supposed to be positive.
2021-05-17 17:19:01 +07:00
Max Kazantsev
e51ef7f070 [Test] Add test on missing opportunity in Loop Deletion
We can break the backedge in some cases when we can evaluate some of the
values and conditions on the 1st iteration.
2021-05-14 16:57:50 +07:00