Commit Graph

411 Commits

Author SHA1 Message Date
Philip Reames 72415d3093 [Tests] Add cases where we're failing to discharge provably loop exits (tests for D63733)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364220 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-24 19:26:17 +00:00
Philip Reames d77254d26e [Tests] Autogen and improve test readability
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364156 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-23 17:13:53 +00:00
Philip Reames 91371a5153 [IndVars] Remove dead instructions after folding trivial loop exit
In rL364135, I taught IndVars to fold exiting branches in loops with a zero backedge taken count (i.e. loops that only run one iteration).  This extends that to eliminate the dead comparison left around.  



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364155 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-23 17:06:57 +00:00
Philip Reames 32acc1f62e Exploit a zero LoopExit count to eliminate loop exits
This turned out to be surprisingly effective. I was originally doing this just for completeness sake, but it seems like there are a lot of cases where SCEV's exit count reasoning is stronger than it's isKnownPredicate reasoning.

Once this is in, I'm thinking about trying to build on the same infrastructure to eliminate provably untaken checks. There may be something generally interesting here.

Differential Revision: https://reviews.llvm.org/D63618



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364135 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-22 17:54:25 +00:00
Nikita Popov 761589542d [LFTR] Add tests for PR41998; NFC
The limit for the pointer case is incorrect.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364128 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-22 09:57:59 +00:00
Philip Reames 79b609c7e5 [Tests] Add a tricky LFTR case for documentation purposes
Thought of this case while working on something else.  We appear to get it right in all of the variations I tried, but that's by accident.  So, add a test which would catch the potential bug.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363953 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-20 17:16:53 +00:00
Philip Reames c48c6af149 LFTR for multiple exit loops
Teach IndVarSimply's LinearFunctionTestReplace transform to handle multiple exit loops. LFTR does two key things 1) it rewrites (all) exit tests in terms of a common IV potentially eliminating one in the process and 2) it moves any offset/indexing/f(i) style logic out of the loop.

This turns out to actually be pretty easy to implement. SCEV already has all the information we need to know what the backedge taken count is for each individual exit. (We use that when computing the BE taken count for the loop as a whole.) We basically just need to iterate through the exiting blocks and apply the existing logic with the exit specific BE taken count. (The previously landed NFC makes this super obvious.)

I chose to go ahead and apply this to all loop exits instead of only latch exits as originally proposed. After reviewing other passes, the only case I could find where LFTR form was harmful was LoopPredication. I've fixed the latch case, and guards aren't LFTRed anyways. We'll have some more work to do on the way towards widenable_conditions, but that's easily deferred.

I do want to note that I added one bit after the review.  When running tests, I saw a new failure (no idea why didn't see previously) which pointed out LFTR can rewrite a constant condition back to a loop varying one.  This was theoretically possible with a single exit, but the zero case covered it in practice.  With multiple exits, we saw this happening in practice for the eliminate-comparison.ll test case because we'd compute a ExitCount for one of the exits which was guaranteed to never actually be reached.  Since LFTR ran after simplifyAndExtend, we'd immediately turn around and undo the simplication work we'd just done.  The solution seemed obvious, so I didn't bother with another round of review.

Differential Revision: https://reviews.llvm.org/D62625



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363883 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-19 21:58:25 +00:00
Philip Reames cf5225b141 [Tests] Autogen a test so that future changes are understandable
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363882 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-19 21:39:07 +00:00
Philip Reames 10c34d1b8d Teach getSCEVAtScope how to handle loop phis w/invariant operands in loops w/taken backedges
This patch really contains two pieces:
    Teach SCEV how to fold a phi in the header of a loop to the value on the backedge when a) the backedge is known to execute at least once, and b) the value is safe to use globally within the scope dominated by the original phi.
    Teach IndVarSimplify's rewriteLoopExitValues to allow loop invariant expressions which already exist (and thus don't need new computation inserted) even in loops where we can't optimize away other uses.

Differential Revision: https://reviews.llvm.org/D63224



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363619 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-17 21:06:17 +00:00
Philip Reames d773cb7e1c Fix a bug w/inbounds invalidation in LFTR (recommit)
Recommit r363289 with a bug fix for crash identified in pr42279.  Issue was that a loop exit test does not have to be an icmp, leading to a null dereference crash when new logic was exercised for that case.  Test case previously committed in r363601.

Original commit comment follows:

This contains fixes for two cases where we might invalidate inbounds and leave it stale in the IR (a miscompile). Case 1 is when switching to an IV with no dynamically live uses, and case 2 is when doing pre-to-post conversion on the same pointer type IV.

The basic scheme used is to prove that using the given IV (pre or post increment forms) would have to already trigger UB on the path to the test we're modifying. As such, our potential UB triggering use does not change the semantics of the original program.

As was pointed out in the review thread by Nikita, this is defending against a separate issue from the hasConcreteDef case. This is about poison, that's about undef. Unfortunately, the two are different, see Nikita's comment for a fuller explanation, he explains it well.

(Note: I'm going to address Nikita's last style comment in a separate commit just to minimize chance of subtle bugs being introduced due to typos.)

Differential Revision: https://reviews.llvm.org/D62939



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363613 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-17 20:32:22 +00:00
Philip Reames 185d55ed9f Reduced test case for pr42279 in advance of the relevant re-commit + fix
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363601 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-17 19:27:45 +00:00
Nikita Popov bf4a9f7325 [SimplifyIndVar] Simplify non-overflowing saturating add/sub
If we can detect that saturating math that depends on an IV cannot
overflow, replace it with simple math. This is similar to the CVP
optimization from D62703, just based on a different underlying
analysis (SCEV vs LVI) that catches different cases.

Differential Revision: https://reviews.llvm.org/D62792

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363489 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-15 08:48:52 +00:00
Florian Hahn 6c7043a228 Revert Fix a bug w/inbounds invalidation in LFTR
Reverting because it breaks a green dragon build:
    http://green.lab.llvm.org/green/job/clang-stage2-Rthinlto/18208

This reverts r363289 (git commit eb88badff96dacef8fce3f003dec34c2ef6900bf)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363427 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-14 17:23:09 +00:00
Sam Parker d021f415d1 [SCEV] Pass NoWrapFlags when expanding an AddExpr
InsertBinop now accepts NoWrapFlags, so pass them through when
expanding a simple add expression.

This is the first re-commit of the functional changes from rL362687,
which was previously reverted.

Differential Revision: https://reviews.llvm.org/D61934


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363364 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-14 09:19:41 +00:00
Philip Reames b8ff4408f1 Fix a bug w/inbounds invalidation in LFTR
This contains fixes for two cases where we might invalidate inbounds and leave it stale in the IR (a miscompile). Case 1 is when switching to an IV with no dynamically live uses, and case 2 is when doing pre-to-post conversion on the same pointer type IV.

The basic scheme used is to prove that using the given IV (pre or post increment forms) would have to already trigger UB on the path to the test we're modifying.  As such, our potential UB triggering use does not change the semantics of the original program.

As was pointed out in the review thread by Nikita, this is defending against a separate issue from the hasConcreteDef case. This is about poison, that's about undef. Unfortunately, the two are different, see Nikita's comment for a fuller explanation, he explains it well.

(Note: I'm going to address Nikita's last style comment in a separate commit just to minimize chance of subtle bugs being introduced due to typos.)

Differential Revision: https://reviews.llvm.org/D62939



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363289 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-13 18:23:13 +00:00
Philip Reames aac3847fc2 [Tests] Highlight impact of multiple exit LFTR (D62625) as requested by reviewer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363217 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-12 23:39:49 +00:00
Philip Reames 58c9643afb [Tests] Autogen RLEV test and add tests for a future enhancement
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363193 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-12 19:23:10 +00:00
Philip Reames 5ea6536b43 [Tests] Add tests to highlight sibling loop optimization order issue for exit rewriting
The issue addressed in r363180 is more broadly relevant.  For the moment, we don't actually get any of these cases because we a) restrict SCEV formation due to SCEExpander needing to preserve LCSSA, and b) don't iterate between loops.




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363192 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-12 19:04:51 +00:00
Philip Reames 4298a2dd20 [SCEV] Teach computeSCEVAtScope benefit from one-input Phi. PR39673
SCEV does not propagate arguments through one-input Phis so as to make it easy for the SCEV expander (and related code) to preserve LCSSA.  It's not entirely clear this restriction is neccessary, but for the moment it exists.   For this reason, we don't analyze single-entry phi inputs.  However it is possible that when an this input leaves the loop through LCSSA Phi, it is a provable constant.  Missing that results in an order of optimization issue in loop exit value rewriting where we miss some oppurtunities based on order in which we visit sibling loops.

This patch teaches computeSCEVAtScope about this case. We can generalize it later, but so far we can only replace LCSSA Phis with their constant loop-exiting values.  We should probably also add similiar logic directly in the SCEV construction path itself.

Patch by: mkazantsev (with revised commit message by me)
Differential Revision: https://reviews.llvm.org/D58113



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363180 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-12 17:21:47 +00:00
Philip Reames 28bea3dbfe Generalize icmp matching in IndVars' eliminateTrunc
We were only matching RHS being a loop invariant value, not the inverse. Since there's nothing which appears to canonicalize loop invariant values to RHS, this means we missed cases.

Differential Revision: https://reviews.llvm.org/D63112



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363108 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-11 22:43:25 +00:00
Philip Reames 85a2f58ba7 [Tests] Adjust LFTR dead-iv tests to bypass undef cases
As pointed out by Nikita in review, undef and poison need to be handled separately.  Since we're no longer expecting any test improvements - just fixes for miscompiles - update the tests to bypass the existing undef check.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363002 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-10 23:17:10 +00:00
Philip Reames 150fff8ce4 [Tests] Split an LFTR dead-iv case
There are two interesting sub-cases here.  1) Switching IVs is legal, but only in pre-increment form.  and 2) Switching IVs is legal, and so is post-increment form.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362993 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-10 22:33:20 +00:00
Philip Reames 656142808a [Tests] Add tests for D62939 (miscompiles around dead pointer IVs)
Flesh out a collection of tests for switching to a dead IV within LFTR, both for the current miscompile, and for some cases which we should be able to handle via simple reasoning.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362976 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-10 19:45:59 +00:00
Philip Reames 4d44152a0f [LFTR] Use recomputed BE count
This was discussed as part of D62880.  The basic thought is that computing BE taken count after widening should produce (on average) an equally good backedge taken count as the one before widening.  Since there's only one test in the suite which is impacted by this change, and it's essentially equivelent codegen, that seems to be a reasonable assertion.  This change was separated from r362971 so that if this turns out to be problematic, the triggering piece is obvious and easily revertable.

For the nestedIV example from elim-extend.ll, we end up with the following BE counts:
BEFORE: (-2 + (-1 * %innercount) + %limit)
AFTER: (-1 + (sext i32 (-1 + %limit) to i64) + (-1 * (sext i32 %innercount to i64))<nsw>)

Note that before is an i32 type, and the after is an i64.  Truncating the i64 produces the i32. 



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362975 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-10 19:18:53 +00:00
Benjamin Kramer 600f7b5a8d Revert "[SCEV] Use wrap flags in InsertBinop"
This reverts commit r362687. Miscompiles llvm-profdata during selfhost.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362699 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-06 12:35:46 +00:00
Sam Parker 6892c31cf9 [SCEV] Use wrap flags in InsertBinop
If the given SCEVExpr has no (un)signed flags attached to it, transfer
these to the resulting instruction or use them to find an existing
instruction.

Differential Revision: https://reviews.llvm.org/D61934


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362687 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-06 08:56:26 +00:00
Philip Reames 999ea6229b [Tests] Add poison inference tests for indvars showing both existing transforms, and some room for improvement
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362628 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-05 18:00:59 +00:00
Philip Reames 2b5c011fba [Tests] Autogen a test so future changes are visible
Oddly, I had to change a value name from "tmp0" to "bc0" to get the autogened test to pass.  I'm putting this down to an oddity of update_test_checks or FileCheck, but don't understand it.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362532 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-04 17:29:55 +00:00
Philip Reames 453fdb5df4 [Tests] Update a test to consistently use new pass manager and FileCheck the result
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362518 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-04 16:19:34 +00:00
Philip Reames 782c705555 [Tests] Autogen tests so that diffs for a future change are understandable
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362516 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-04 16:15:19 +00:00
Philip Reames b58d51e15c [Tests] Add LFTR tests for multiple exit loops (try 2)
(Recommit after fixing a keymash in the run line.  Sorry for breakage.)

This is preparation for D62625 <https://reviews.llvm.org/D62625>



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362426 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-03 17:41:12 +00:00
Dmitri Gribenko 4e8306274d Revert "[Tests] Add LFTR tests for multiple exit loops"
This reverts commit r362417.  There's a syntax error in the RUN line.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362418 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-03 16:58:11 +00:00
Philip Reames 66a14657fe [Tests] Add LFTR tests for multiple exit loops
This is preparation for D62625



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362417 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-03 16:46:03 +00:00
Nikita Popov c813a34137 [IndVarSimplify] Add tests for saturating math on IV; NFC
These saturating math ops can be replaced with simple math.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362320 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-02 08:49:35 +00:00
Nikita Popov 7a3adb340c [IndVarSimplify] Fixup nowrap flags during LFTR (PR31181)
Fix for https://bugs.llvm.org/show_bug.cgi?id=31181 and partial fix
for LFTR poison handling issues in general.

When LFTR moves a condition from pre-inc to post-inc, it may now
depend on value that is poison due to nowrap flags. To avoid this,
we clear any nowrap flag that SCEV cannot prove for the post-inc
addrec.

Additionally, LFTR may switch to a different IV that is dynamically
dead and as such may be arbitrarily poison. This patch will correct
nowrap flags in some but not all cases where this happens. This is
related to the adoption of IR nowrap flags for the pre-inc addrec.
(See some of the switch_to_different_iv tests, where flags are not
dropped or insufficiently dropped.)

Finally, there are likely similar issues with the handling of GEP
inbounds, but we don't have a test case for this yet.

Differential Revision: https://reviews.llvm.org/D60935

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362292 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-01 09:40:18 +00:00
Nikita Popov a3372ba9d1 [IndVarSimplify] Add additional PR33181 tests; NFC
Two more tests with a switch to a dynamically dead IV, with poison
occuring on the first or second iteration.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362291 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-01 09:40:09 +00:00
Nikita Popov 19823a1fcf [LFTR] Add additional PR31181 test cases
One case where overflow happens in the first loop iteration, and
two cases where we switch to a dynamically dead IV with post/pre
increment, respectively.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361189 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-20 19:13:04 +00:00
Philip Reames 85725de61f [Tests] Consolidate more lftr tests
These are all of the ones involving the same data layout string.  Remainder take a bit more consideration, but at least everything can be auto-updated now.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360961 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-17 00:19:28 +00:00
Philip Reames e3c69b2f50 [Tests] Expand basic lftr coverage
Newly written tests to cover the simple cases.  We don't appear to have broad coverage of this transform anywhere.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360957 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 23:41:28 +00:00
Philip Reames b0d16dea25 [Tests] More consolidation of lftr tests
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360936 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 20:42:00 +00:00
Philip Reames 4497208d41 [Test] Remove a bunch of cruft from a test
This test hadn't been fully reduced, so do so.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360935 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 20:37:20 +00:00
Philip Reames 66f0cce052 [Tests] Start consolidating lftr tests into a single file
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360934 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 20:33:41 +00:00
Philip Reames c6a8d32225 [Tests] Autogen the last lftr test
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360933 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 20:24:57 +00:00
Philip Reames 390a063d12 [Tests] Autogen a few more lftr tests for readability
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360932 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 20:19:02 +00:00
Philip Reames abb5c3714d [Tests] Autogen a few lftr test in preparation for merging
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360931 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-16 20:15:25 +00:00
Philip Reames d2a49ce9fc [IndVars] Extend reasoning about loop invariant exits to non-header blocks
Noticed while glancing through the code for other reasons.  The extension is trivial enough, decided to just do it.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360694 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-14 17:20:10 +00:00
Philip Reames 705ed45080 [Test] Autogen a test for ease of later changing
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360690 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-14 16:37:29 +00:00
Keno Fischer 35a5cc8b49 [SCEV] Add explicit representations of umin/smin
Summary:
Currently we express umin as `~umax(~x, ~y)`. However, this becomes
a problem for operands in non-integral pointer spaces, because `~x`
is not something we can compute for `x` non-integral. However, since
comparisons are generally still allowed, we are actually able to
express `umin(x, y)` directly as long as we don't try to express is
as a umax. Support this by adding an explicit umin/smin representation
to SCEV. We do this by factoring the existing getUMax/getSMax functions
into a new function that does all four. The previous two functions were
largely identical.

Reviewed By: sanjoy
Differential Revision: https://reviews.llvm.org/D50167

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360159 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-07 15:28:47 +00:00
Nikita Popov f925f4a471 [IndVarSimplify] Generate full checks for some LFTR tests; NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358813 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-20 12:05:53 +00:00
Nikita Popov e886e07a6e [IndVarSimplify] Add tests for PR31181; NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358812 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-20 12:05:43 +00:00