41 Commits

Author SHA1 Message Date
Florian Hahn
dce77a3579
[IndVars] Preserve flags of narrow IV inc if replacing with wider inc. (#80446)
We are replacing a narrow IV increment with a wider one. If the original
(narrow) increment did not wrap, the wider one should not wrap either.
Set the flags to be the union of both wide increment and original
increment; this ensures we preserve flags SCEV could infer for the wider
increment.

Fixes https://github.com/llvm/llvm-project/issues/71517.
2024-02-10 18:11:17 +00:00
Nikita Popov
2d69827c5c [Transforms] Convert tests to opaque pointers (NFC) 2024-02-05 11:57:34 +01:00
John Brawn
a04d4a03f7
[LoopFlatten] Use loop versioning when overflow can't be disproven (#78576)
Implement the TODO in loop flattening to version the loop when we can't
prove that the trip count calculation won't overflow.
2024-01-25 13:57:19 +00:00
John Brawn
ae978baaf6
[LoopFlatten] Recognise gep+gep (#72515)
Now that InstCombine canonicalises add+gep to gep+gep, LoopFlatten needs
to recognise (gep (gep ptr (i*M)), j) as being something it can
optimise.
2024-01-10 14:32:59 +00:00
Philip Reames
5adf6ab7ff Revert "[IndVars] Generate zext nneg when locally obvious"
This reverts commit a6c8e27b3a052913a15a13ee0d4ac466c5ab3f92.  It appears likely to have caused https://lab.llvm.org/buildbot/#/builders/57/builds/30988.
2023-11-03 11:19:14 -07:00
Philip Reames
1ffea97ffd
[indvars] Support known positive extends in getExtendedOperandRecurrence (#70990)
IndVars has the existing notion of a narrow definition which is known to
positive and thus both sign and zero extension kinds are actually the
same operations. There's existing logic for forming a SCEV based on the
extension kind and the no-wrap flags. This change extends that logic to
form the opposite extension kind for a positive def if doing so is
allowed by the flags. Note that we already do something analogous for
the getWideRecurrence case as well.
2023-11-03 10:21:30 -07:00
Philip Reames
a6c8e27b3a [IndVars] Generate zext nneg when locally obvious
zext nneg was recently added to the IR in #67982.  This patch teaches
SimplifyIndVars to prefer zext nneg over *both* sext and plain zext,
when a local SCEV query indicates the source is non-negative.

The choice to prefer zext nneg over sext looks slightly aggressive
here, but probably isn't so much in practice.  For cases where we'd
"remember" the range fact, instcombine would convert the sext into
a zext nneg anyways.  The only cases where this produces a different
result overall are when SCEV knows a non-local fact, and it doesn't
get materialized into the IR.  Those are exactly the cases where
using zext nneg are most useful.  We do run the risk of e.g. a
missing combine - since we haven't updated most of them yet - but
that seems like a manageable risk.

Note that there are much deeper algorithmic changes we could make
to this code to exploit zext nneg, but this seemed like a reasonable
and low risk starting point.
2023-11-03 09:20:59 -07:00
Philip Reames
442da60a3f Run DCE after a LoopFlatten test to reduce spurious output [nfc]
LoopFlatten uses IndVars mechanics to widen induction variables, but then
fails to cleanup the dead instructions returned via the API.  This isn't
a functional problem, but means that this test is highly sensative to
indvars internals in an unhelpful way.  Use DCE to "normalize" the test
output to avoid false positives in a later change.
2023-11-01 12:06:10 -07:00
Nikita Popov
edb2fc6dab [llvm] Remove explicit -opaque-pointers flag from tests (NFC)
Opaque pointers mode is enabled by default, no need to explicitly
enable it.
2023-07-12 14:35:55 +02:00
David Green
161bfa5f53 [LoopFlattening] Check for extra uses on Mul
Similar to D138404, we were not guarding against extra uses of the Mul.
In most cases other checks would catch the issue due to unsupported
instructions in the outer loop, but certain non-canonical loop forms
could still get through.

Fixes #59339

Differential Revision: https://reviews.llvm.org/D141114
2023-01-06 15:32:38 +00:00
David Green
8cc9530ebc [LoopFlatten][NFC] Run instnamer on pr59339.ll 2023-01-06 15:32:38 +00:00
Nikita Popov
5867241eac [Transforms] Convert some tests to opaque pointers (NFC) 2023-01-06 12:14:45 +01:00
Nikita Popov
055fb7795a [Transforms] Convert some tests to opaque pointers (NFC)
These are all tests where conversion worked automatically, and
required no manual fixup.
2023-01-05 12:43:45 +01:00
Roman Lebedev
72482c5167
[NFC] Port all LoopFlatten tests to -passes= syntax 2022-12-08 02:38:46 +03:00
Sjoerd Meijer
1515308a54 [LoopFlatten] Precommit test for GH issue #59339. NFC. 2022-12-05 15:38:47 +00:00
David Green
8e9e22f07b [LoopFlatten] Fix IV increment use count
The add from the IV in the inner loop was always checking for 2 uses,
the phi and the compare. The compare could be based on the phi though,
leaving one valid use of the compare. In the testcase we could be left
with the phi and a lcssa phi as the two users, invalidly allowing
flattening where we shouldn't.

Fixes 58441

Differential Revision: https://reviews.llvm.org/D138404
2022-11-22 07:23:56 +00:00
David Green
c7a53421cd [LoopFlatten] Add a test for incorrect IV increment uses. NFC
These are a couple of test cases from 58441, showing LCSSA uses on
the IV increment. Part of D138404.
2022-11-21 15:05:44 +00:00
luxufan
98eb917939 [LoopFlatten] Forget all block and loop dispositions after flatten
Method forgetLoop only forgets expression of phi or its users. SCEV
expressions except the above mentioned may still has loop dispositions
that point to the destroyed loop, which might cause a crash.

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

Reviewed By: nikic, fhahn

Differential Revision: https://reviews.llvm.org/D137651
2022-11-14 10:19:11 +08:00
Max Kazantsev
0867f23dcf [Test] Regenerate tests using update_tests.py 2022-08-19 14:51:19 +07:00
Craig Topper
d73684e223 [LoopFlatten] Fix crash if the inner loop trip count comes from a sext instruction.
If we look through a truncate in matchLinearIVUser, it's possible
we find a sext/zext instruction that didn't come from widening.
This will fail the MatchedItCount->getType() == InnerInductionPHI->getType()
assertion.

Fix this by checking that we did not look through a truncate already.

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D127149
2022-06-07 08:21:21 -07:00
Sjoerd Meijer
367df18050 [LoopFlatten] Bail if we can't perform flattening after IV widening
It can happen that after widening of the IV, flattening may not be possible,
e.g. when it is deemed unprofitable. We were not properly checking this, which
resulted in flattening being applied when it shouldn't, also leading to
incorrect results (miscompilation).

This should fix PR51980 (https://bugs.llvm.org/show_bug.cgi?id=51980)

Differential Revision: https://reviews.llvm.org/D110712
2021-09-29 19:53:34 +01:00
Sjoerd Meijer
0ea77502e2 [LoopFlatten] Updating Phi nodes after IV widening
In rG6a076fa9539e, a problem with updating the old/narrow phi nodes after IV
widening was introduced. If after widening of the IV the transformation is
*not* applied, the narrow phi node was incorrectly modified, which should only
happen if flattening happens. This can be seen in the added test widen-iv2.ll,
which incorrectly had 1 incoming value, but should have its original 2 incoming
values, which is now restored.

Differential Revision: https://reviews.llvm.org/D110234
2021-09-28 15:09:20 +01:00
Sjoerd Meijer
a588ae482b [LoopFlatten] Precommit new test widen-iv2.ll for D110234. 2021-09-27 14:37:44 +01:00
Sjoerd Meijer
6a076fa953 [LoopFlatten] Make the analysis more robust after IV widening
LoopFlatten wasn't triggering on this motivating case after IV widening:

  void foo(int *A, int N, int M) {
    for (int i = 0; i < N; ++i)
      for (int j = 0; j < M; ++j)
        f(A[i*M+j]);
  }

The reason was that the old induction phi nodes were getting in the way. These
narrow and dead induction phis are not always trivially dead, and having both
the narrow and wide IVs confused the analysis and caused it to bail. This adds
some extra bookkeeping for these old phis, so we can filter them out when
checks on phi nodes are performed. Other clean up passes will get rid of these
old phis and increment instructions.

As this was one of the motivating examples from the beginning, it was
surprising this wasn't triggering from C/C++ code. It looks like the IR and CFG
is just slightly different.

Differential Revision: https://reviews.llvm.org/D109309
2021-09-10 12:34:04 +01:00
Rosie Sumpter
d1aa075129 [LoopFlatten] Fix assertion failure
There is an assertion failure in computeOverflowForUnsignedMul
(used in checkOverflow) due to the inner and outer trip counts
having different types. This occurs when the IV has been widened,
but the loop components are not successfully rediscovered.
This is fixed by some refactoring of the code in findLoopComponents
which identifies the trip count of the loop.

Differential Revision: https://reviews.llvm.org/D108107
2021-08-19 13:18:57 +01:00
Rosie Sumpter
46abd1fbe8 [LoopFlatten] Fix assertion failure in checkOverflow
There is an assertion failure in computeOverflowForUnsignedMul
(used in checkOverflow) due to the inner and outer trip counts
having different types. This occurs when the IV has been widened,
but the loop components are not successfully rediscovered.
This is fixed by some refactoring of the code in findLoopComponents
which identifies the trip count of the loop.
2021-08-13 10:07:49 +01:00
Rosie Sumpter
f117ed542f [LoopFlatten] Fix missed LoopFlatten opportunity
When the limit of the inner loop is a known integer, the InstCombine
pass now causes the transformation e.g. imcp ult i32 %inc, tripcount ->
icmp ult %j, tripcount-step (where %j is the inner loop induction
variable and %inc is add %j, step), which is now accounted for when
identifying the trip count of the loop. This is also an acceptable use
of %j (provided the step is 1) so is ignored as long as the compare
that it's used in is also the condition of the inner branch.

Differential Revision: https://reviews.llvm.org/D105802
2021-08-02 11:09:54 +01:00
Rosie Sumpter
fab5659c79 Revert "[LoopFlatten] Fix missed LoopFlatten opportunity"
This reverts commit 2df8bf9339e43de63d8d28e07182e1d6d7ffb843.

Reverting because it causes an assertion failure.
2021-07-29 15:52:45 +01:00
Rosie Sumpter
2df8bf9339 [LoopFlatten] Fix missed LoopFlatten opportunity
When the trip count of the inner loop is a constant, the InstCombine
pass now causes the transformation e.g. imcp ult i32 %inc, tripcount ->
icmp ult %j, tripcount-step (where %j is the inner loop induction
variable and %inc is add %j, step), which is now accounted for when
identifying the trip count of the loop. This is also an acceptable use
of %j (provided the step is 1) so is ignored as long as the compare
that it's used in is also the condition of the inner branch.

Differential Revision: https://reviews.llvm.org/D105802
2021-07-29 09:47:41 +01:00
Sjoerd Meijer
bc43078fe8 [LoopFlatten] Fix bug where SCEVCouldNotCompute object is used
The SCEV method getBackedgeTakenCount() returns a SCEVCouldNotCompute
object if the backedge-taken count is unpredictable. This fix ensures
there is no longer an attempt to use such an object to find the trip
count.

Patch by: Rosie Sumpter.

Differential Revision: https://reviews.llvm.org/D106970
2021-07-28 18:35:08 +01:00
Rosie Sumpter
491ac28028 [LoopFlatten] Use SCEV and Loop APIs to identify increment and trip count
Replace pattern-matching with existing SCEV and Loop APIs as a more
robust way of identifying the loop increment and trip count. Also
rename 'Limit' as 'TripCount' to be consistent with terminology.

Differential Revision: https://reviews.llvm.org/D106580
2021-07-27 08:42:59 +01:00
Stelios Ioannou
1124ad2f5d [LoopFlatten] Simplify loops so that the pass can operate on unsimplified loops.
The loop flattening pass requires loops to be in simplified form. If the
loops are not in simplified form, the pass cannot operate. This patch
simplifies all loops before flattening. As a result, all loops will be
simplified regardless of whether anything ends up being flattened.

This change was inspired by observing a certain loop that was not flatten
because the loops were not in simplified form. This loop is added as a
test to verify that it is now flattened.

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

Change-Id: I45bcabe70fb99b0d89f0effafc82eb9e0585ec30
2021-05-12 19:22:01 +01:00
Ta-Wei Tu
4d9d736875 [NFC] Improve debug message and test description in 4c1f74a 2021-03-24 18:21:13 +08:00
Ta-Wei Tu
4c1f74a76c [LoopFlatten] Fix invalid assertion (PR49571)
The `InductionPHI` is not necessarily the increment instruction, as
demonstrated in pr49571.ll.
This patch removes the assertion and instead bails out from the
`LoopFlatten` pass if that happens.

This fixes https://bugs.llvm.org/show_bug.cgi?id=49571

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D99252
2021-03-24 18:08:27 +08:00
Arthur Eubanks
deac8b1f45 [test] Fix widen-iv.ll under NPM
The -loop-flatten legacy pass preserves loop analyses. The legacy PM
will check all passes that preserve loop analyses that they preserve
LCSSA. This implicitly involves running -loop-simplify. The test
shouldn't depend on verify flags being set in order to run
-loop-simplify, so explicitly add it. The new PM ends up not running it
otherwise.
2020-12-07 19:34:31 -08:00
Sjoerd Meijer
33b2c88fa8 [LoopFlatten] Widen IV, support ZExt.
I disabled the widening in fa5cb4b because it run in an assert, which was
related to replacing values with different types. I forgot that an extend could
also be a zero-extend, which I have added now. This means that the approach now
is to create and insert a trunc value of the outerloop for each user, and use
that to replace IV values.

Differential Revision: https://reviews.llvm.org/D91690
2020-11-23 08:57:19 +00:00
Sjoerd Meijer
fa5cb4b936 [LoopFlatten] Disable IV widening
Disable widening of the IV in LoopFlatten while I investigate an assertion
failures. Please note that the pass is also not yet enabled by default.
2020-11-16 22:30:52 +00:00
Sjoerd Meijer
9aa773381b [LoopFlatten] Widen the IV
Widen the IV to the widest available and legal integer type, which makes this
transformations always safe so that we can skip overflow checks.

Motivation is to let this pass trigger on 64-bit targets too, and this is the
last patch in a serie to achieve this: D90402 moves pass LoopFlatten to just
before IndVarSimplify so that IVs are not already widened, D90421 factors out
widening from IndVarSimplify into Utils/SimplifyIndVar so that we can also use
it in LoopFlatten.

Differential Revision: https://reviews.llvm.org/D90640
2020-11-16 10:20:13 +00:00
Sjoerd Meijer
706ead0e87 [LoopFlatten] Make it a FunctionPass
This converts LoopFlatten from a LoopPass to a FunctionPass so that we don't
run into problems of a loop pass deleting a (inner)loop.

Differential Revision: https://reviews.llvm.org/D90940
2020-11-10 20:03:31 +00:00
Sjoerd Meijer
20c7ab87a7 [LoopFlatten] Precommit new test cases. NFC. 2020-10-14 10:09:40 +01:00
Sjoerd Meijer
d53b4bee0c [LoopFlatten] Add a loop-flattening pass
This is a simple pass that flattens nested loops.  The intention is to optimise
loop nests like this, which together access an array linearly:

  for (int i = 0; i < N; ++i)
    for (int j = 0; j < M; ++j)
      f(A[i*M+j]);

into one loop:

  for (int i = 0; i < (N*M); ++i)
    f(A[i]);

It can also flatten loops where the induction variables are not used in the
loop. This can help with codesize and runtime, especially on simple cpus
without advanced branch prediction.

This is only worth flattening if the induction variables are only used in an
expression like i*M+j. If they had any other uses, we would have to insert a
div/mod to reconstruct the original values, so this wouldn't be profitable.

This partially fixes PR40581 as this pass triggers on one of the two cases. I
will follow up on this to learn LoopFlatten a few more (small) tricks. Please
note that LoopFlatten is not yet enabled by default.

Patch by Oliver Stannard, with minor tweaks from Dave Green and myself.

Differential Revision: https://reviews.llvm.org/D42365
2020-10-01 13:54:45 +01:00