324 Commits

Author SHA1 Message Date
Ramkumar Ramachandra
b40e4ceaa6
[ValueTracking] Make Depth last default arg (NFC) (#142384)
Having a finite Depth (or recursion limit) for computeKnownBits is very
limiting, but is currently a load-bearing necessity, as all KnownBits
are recomputed on each call and there is no caching. As a prerequisite
for an effort to remove the recursion limit altogether, either using a
clever caching technique, or writing a easily-invalidable KnownBits
analysis, make the Depth argument in APIs in ValueTracking uniformly the
last argument with a default value. This would aid in removing the
argument when the time comes, as many callers that currently pass 0
explicitly are now updated to omit the argument altogether.
2025-06-03 17:12:24 +01:00
黃國庭
f37ab15254
[InstCombine] Infer exact for lshr by cttz (#136696)
Infer the 'exact' flag on an 'lshr' or 'ashr' instruction when the shift
amount is computed via a 'cttz' intrinsic on the same operand.
 
Proof: https://alive2.llvm.org/ce/z/CQR2PG

Fixes #131444.
2025-04-29 17:50:53 +02:00
Matthew Devereau
251377c47d
[InstCombine] Fold shift+cttz with power of 2 operands (#127055)
#121386 Introduced cttz intrinsics which caused a regression where
vscale/vscale divisions could no longer be constant folded.

This fold was suggested as a fix in #126411.
https://alive2.llvm.org/ce/z/gWbtPw
2025-02-18 07:06:56 +00:00
Jeremy Morse
8e70273509
[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a
debug-info bit that's needed when getFirstNonPHI and similar feed into
instruction insertion positions. Call-sites where that's necessary were
updated a year ago; but to ensure some type safety however, we'd like to
have all calls to moveBefore use iterators.

This patch adds a (guaranteed dereferenceable) iterator-taking
moveBefore, and changes a bunch of call-sites where it's obviously safe
to change to use it by just calling getIterator() on an instruction
pointer. A follow-up patch will contain less-obviously-safe changes.

We'll eventually deprecate and remove the instruction-pointer
insertBefore, but not before adding concise documentation of what
considerations are needed (very few).
2025-01-24 10:53:11 +00:00
Maurice Heumann
27eaa8a40e
[InstCombine] Prevent infinite loop with two shifts (#118806)
The following pattern: `(C2 << X) << C1` will usually be transformed
into `(C2 << C1) << X`, essentially swapping `X` and `C1`.

However, this should only be done when `C1` is an immediate constant,
otherwise thiscan lead to both constants being swapped forever.

This fixes #118798.
2024-12-05 16:57:27 +01:00
Yingwei Zheng
52fac608bd
[InstCombine] Fold [l|a]shr iN (X-1)&~X, N-1 -> [z|s]ext(X==0) (#107259)
Alive2: https://alive2.llvm.org/ce/z/kwvTFn
Closes #107228.

`ashr iN (X-1)&~X, N-1` also exists. See
https://github.com/dtcxzyw/llvm-opt-benchmark/issues/1274.
2024-09-06 21:37:50 +08:00
Volodymyr Vasylkun
d68d2172f9
[InstCombine] Fold ucmp/scmp(x, y) >> N to zext/sext(x < y) when N is one less than the width of the result of ucmp/scmp (#104009)
Proof: https://alive2.llvm.org/ce/z/4diUqN

---------

Co-authored-by: Nikita Popov <github@npopov.com>
2024-08-15 18:08:23 +01:00
AtariDreams
7a969ec1e1
[PatternMatch] Use m_Not instead of m_c_Xor with m_AllOnes() (#96837) 2024-06-27 10:14:45 +02:00
Nikita Popov
e64ed1db46 [InstCombine] Avoid use of ConstantExpr::getShl()
Either use IRBuilder or the constant folding API instead. For
the IRBuilder uses, also switch to ImmConstant to make sure that
folding will succeed.
2024-06-18 16:39:32 +02:00
c8ef
1d4e857acd
[InstCombine] simplify average of lsb (#95684)
close: #94737
alive2: https://alive2.llvm.org/ce/z/WF_7mX

In this patch, we combine `(X + Y) / 2` into `(X & Y)` only when both X
and Y are less than or equal to 1.
2024-06-17 13:18:04 +08:00
Noah Goldstein
2900d035f4 [InstCombine] Propagate flags when folding consecutative shifts
When we fold `(shift (shift C0, x), C1)` we can propagate flags that
are common to both shifts.

Proofs: https://alive2.llvm.org/ce/z/LkEzXD

Closes #94872
2024-06-08 16:46:45 -05:00
AtariDreams
10e7671d9a
Reland "[InstCombine] Fold (sub nuw X, (Y << nuw Z)) >>u exact Z --> (X >>u exact Z) sub nuw Y" (#93571)
This is the same fold as ((X << nuw Z) sub nuw Y) >>u exact Z --> X sub
nuw (Y >>u exact Z), but with the sub operands swapped.

Alive2 Proof:
https://alive2.llvm.org/ce/z/pT-RxG
2024-06-03 08:24:54 +02:00
AtariDreams
1034b4d38d
[InstCombine] lshr (mul (X, 2^N + 1)), N -> X when X is half-width (#93677)
Alive2 Proof:
https://alive2.llvm.org/ce/z/Yd2CKF
2024-05-30 09:39:32 +02:00
AtariDreams
718ba5a584 Reapply [InstCombine] lshr (mul (X, 2^N + 1)), N -> add (X, lshr(X, N)) (#92907)
Alive2 Proofs:
https://alive2.llvm.org/ce/z/eSinJY
https://alive2.llvm.org/ce/z/vyKvde
https://alive2.llvm.org/ce/z/dRFsfV

I mistakenly reverted this commit as part of a larger set of
reverts. Reapplied without changes.
2024-05-29 12:11:35 +02:00
Nikita Popov
83370e4878 Revert "[InstCombine] lshr (mul (X, 2^N + 1)), N -> add (X, lshr(X, N)) (#92907)"
This reverts commit 6d484965ca96b616c3cce0d08eed358b97dbc39b.

PR merged without review.
2024-05-27 08:31:28 +02:00
Nikita Popov
2be8bea1b7 Revert "[InstCombine] Add reverse of ((X << nuw Z) sub nuw Y) >>u exact Z --> X sub nuw (Y >>u exact Z) (#91386)"
This reverts commit c42c32088bdb03e39ed24f4800a447d4cbb788f2.

PR merged without review.
2024-05-27 08:28:35 +02:00
AtariDreams
c42c32088b
[InstCombine] Add reverse of ((X << nuw Z) sub nuw Y) >>u exact Z --> X sub nuw (Y >>u exact Z) (#91386)
This is the same fold as ((X << nuw Z) sub nuw Y) >>u exact Z --> X sub
nuw (Y >>u exact Z), which we already have and approved in the codebase, but with the sub operands
swapped.

Proof it works in reverse, so we could have a wider generalization of this pattern: https://alive2.llvm.org/ce/z/2cRcdx
2024-05-26 20:02:42 -04:00
AtariDreams
64bba2178f
[InstCombine] Propagate disjoint flags during shl-binop transform (#91333)
Alive2 Proof:
https://alive2.llvm.org/ce/z/D2jHrn
2024-05-26 19:46:37 -04:00
AtariDreams
6d484965ca
[InstCombine] lshr (mul (X, 2^N + 1)), N -> add (X, lshr(X, N)) (#92907)
Alive2 Proofs:
https://alive2.llvm.org/ce/z/eSinJY
https://alive2.llvm.org/ce/z/vyKvde
https://alive2.llvm.org/ce/z/dRFsfV
2024-05-26 17:28:29 -04:00
AtariDreams
409ff97aac
[InstCombine] Fix comment from #88193 (NFC) (#91427)
It is inaccurate and needs to be corrected.
2024-05-09 09:26:36 +09:00
AtariDreams
1e36c96dc0
[InstCombine] Fold ((X << nuw Z) binop nuw Y) >>u Z --> X binop nuw (Y >>u Z) (#88193)
Proofs:
https://alive2.llvm.org/ce/z/N9dRzP
https://alive2.llvm.org/ce/z/Xrpc-Y
https://alive2.llvm.org/ce/z/BagBM6
2024-05-07 21:17:56 +02:00
Nikita Popov
8bfdbb9570
[InstCombine] Remove redundant shift folds (NFCI) (#90016)
These are already handled by canEvaluateShifted/getShiftedValue (one-use
only), and also in reassociateShiftAmtsOfTwoSameDirectionShifts (also
multi-use), so let's at least get rid of the *third* implementation...
2024-04-25 16:14:54 +09:00
Nikita Popov
1baa385065
[IR][PatternMatch] Only accept poison in getSplatValue() (#89159)
In #88217 a large set of matchers was changed to only accept poison
values in splats, but not undef values. This is because we now use
poison for non-demanded vector elements, and allowing undef can cause
correctness issues.

This patch covers the remaining matchers by changing the AllowUndef
parameter of getSplatValue() to AllowPoison instead. We also carry out
corresponding renames in matchers.

As a followup, we may want to change the default for things like m_APInt
to m_APIntAllowPoison (as this is much less risky when only allowing
poison), but this change doesn't do that.

There is one caveat here: We have a single place
(X86FixupVectorConstants) which does require handling of vector splats
with undefs. This is because this works on backend constant pool
entries, which currently still use undef instead of poison for
non-demanded elements (because SDAG as a whole does not have an explicit
poison representation). As it's just the single use, I've open-coded a
getSplatValueAllowUndef() helper there, to discourage use in any other
places.
2024-04-18 15:44:12 +09:00
Noah Goldstein
b3ee127e7d [InstCombine] integrate N{U,S}WAddLike into existing folds
Just went a quick replacement of `N{U,S}WAdd` with the `Like` variant
that old matches `or disjoint`

Closes #86082
2024-03-21 13:03:38 -05:00
Noah Goldstein
79ce933114 [InstCombine] Extend (lshr/shl (shl/lshr -1, x), x) -> (lshr/shl -1, x) for multi-use
We previously did this iff the inner `(shl/lshr -1, x)` was
one-use. No instructions are added even if the inner `(shl/lshr -1,
x)` is multi-use and this canonicalization both makes the resulting
instruction easier to analyze and shrinks its dependency chain.

Closes #81576
2024-02-13 12:53:16 -06:00
Craig Topper
55c6d91034
[InstCombine] Preserve nuw/nsw/exact flags when transforming (C shift (A add nuw C1)) --> ((C shift C1) shift A). (#79490)
If we weren't shifting out any non-zero bits or changing the sign before the transform, we
shouldn't be after.

Alive2: https://alive2.llvm.org/ce/z/mB-rWz
2024-01-26 11:33:53 -08:00
AtariDreams
96adf69ba9
[InstCombine] Remove one-use check if other logic operand is constant (#77973)
By using `match(W, m_ImmConstant())`, we do not need to worry about
one-time use anymore.
2024-01-23 12:10:59 +01:00
Yingwei Zheng
741975df92
[InstCombine][InstSimplify] Pass SimplifyQuery to computeKnownBits directly. NFC. (#74246)
This patch passes `SimplifyQuery` to `computeKnownBits` directly in
`InstSimplify` and `InstCombine`.
As the `DomConditionCache` in #73662 is only used in `InstCombine`, it
is inconvenient to introduce a new argument `DC` to `computeKnownBits`.
2023-12-04 02:26:39 +08:00
Yingwei Zheng
a2cf44b72c
[InstCombine] Propagate NUW flags for shl (lshr X, C1), C2 -> shl X, C2-C1 (#72525)
Alive2: https://alive2.llvm.org/ce/z/KNXNQA
2023-11-20 23:29:44 +08:00
Yingwei Zheng
6da4ecdf92
[InstCombine] Infer shift flags with unknown shamt (#72535)
Alive2: https://alive2.llvm.org/ce/z/82Wr3q

Related patch:
2dd52b4527
2023-11-18 15:15:14 +08:00
Yingwei Zheng
26ce3e4239
[InstCombine] Preserve NSW flags for lshr (mul nuw X, C1), C2 -> mul nuw nsw X, (C1 >> C2) (#72625)
Alive2: https://alive2.llvm.org/ce/z/TU_V9M

This missed optimization is discovered with the help of
https://github.com/AliveToolkit/alive2/pull/962.
2023-11-17 21:50:21 +08:00
Yingwei Zheng
e8fe15ccf1
[InstCombine] Add exact flags for ext idiom shr (shl X, Y), Y (#72483)
This patch adds exact flags for sext/zext idiom `shr (shl X, Y), Y`.
Alive2: https://alive2.llvm.org/ce/z/xYFpfB

We can generalize it to handle pattern `shr (shl X, Y), Z` with `Y u>=
Z` (e.g., non-splat vectors). But I don't think it's worth the effort.

This missed optimization is discovered with the help of
https://github.com/AliveToolkit/alive2/pull/962.
2023-11-16 17:30:01 +08:00
Yingwei Zheng
4fdc289d4a
[InstCombine] Infer nsw flag for (X <<nuw C1) >>u C --> X << (C1 - C) (#72407)
Alive2: https://alive2.llvm.org/ce/z/nnHAPy
This missed optimization is discovered with the help of
https://github.com/AliveToolkit/alive2/pull/962.
2023-11-16 02:34:59 +08:00
Nikita Popov
002da67d01 [InstCombine] Require ImmConstant in shift of shift fold
This fixes an infinite loop reported at:
82f68a992b (commitcomment-132406739)
2023-11-13 14:56:06 +01:00
Nikita Popov
707bb42163 [InstCombine] Require immediate constant in canEvaluateShifted()
Otherwise we risk infinite loops when shift constant expressions
are no longer supported.
2023-11-10 16:12:49 +01:00
Nikita Popov
8391f405cb [InstCombine] Avoid uses of ConstantExpr::getLShr()
Use the constant folding API instead.
2023-11-10 15:50:42 +01:00
Noah Goldstein
2dd52b4527 [InstCombine] Improve logic for adding flags to shift instructions.
Instead of relying on constant operands, use known bits to do the
computation.

Proofs: https://alive2.llvm.org/ce/z/M-aBnw

Differential Revision: https://reviews.llvm.org/D157532
2023-10-12 16:05:19 -05:00
Nikita Popov
b4afade175 [InstCombine] Avoid use of ConstantExpr::getZExtOrBitcast() (NFC)
Use the constant folding API instead. In the second case using
IR builder should also work, but the way the instructions are
created an inserted there is very unusual, so I've left it alone.
2023-09-29 09:44:43 +02:00
Nikita Popov
7eda63b814 [InstCombine] Avoid use of ConstantExpr::getZExt() (NFC)
Check the result of constant folding here, as I'm not confident
that no constant expressions can make it in here.
2023-09-28 17:13:49 +02:00
Jeremy Morse
d529943a27 [NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
As per my proposal for how to eliminate debug intrinsics [0], for various
places in InstCombine prefer to insert using an instruction iterator rather
than an instruction pointer. This is so that we can eventually pass more
information in the iterator class. These call-sites where I've changed the
spelling are those that necessary to build a stage2clang to produce an
identical binary in the coming no-debug-intrinsics mode.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152543
2023-09-11 15:04:51 +01:00
Nikita Popov
357a002c7c [InstCombine] Remove old add in foldLShrOverflowBit()
Explicitly remove the old add instruction, so we don't need a
separate InstCombine iteration to DCE it.
2023-06-01 15:30:24 +02:00
Noah Goldstein
5a3d9e0617 [InstCombine] Transform (shift X,Or(Y,BitWidth-1)) -> (shift X,BitWidth-1)
shl : https://alive2.llvm.org/ce/z/_B7Qca
lshr: https://alive2.llvm.org/ce/z/6eXz_W
ashr: https://alive2.llvm.org/ce/z/oGEx-q

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D145326
2023-03-06 20:30:06 -06:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Sanjay Patel
8e8467d9d8 [InstCombine] canonicalize "extract lowest set bit" away from cttz intrinsic
1 << (cttz X) --> -X & X
https://alive2.llvm.org/ce/z/qv3E9e

This creates an extra use of the input value, so that's generally
not preferred, but there are advantages to this direction:
1. 'negate' and 'and' allow for better analysis than 'cttz'.
2. This is more likely to induce follow-on transforms (in the
   example from issue #60801, we'll get the decrement pattern).
3. The more basic ALU ops are more likely to result in better
   codegen across a variety of targets.

This won't solve the motivating bugs (see issue #60799) because
we do not recognize the redundant icmp+sel, and the x86 backend
may not have the pattern-matching to produce the optimal BMI
instructions.

Differential Revision: https://reviews.llvm.org/D144329
2023-02-19 17:29:40 -05:00
Noah Goldstein
c17ccced4b Recommit "Reorder (shl (add/sub (shl x, C0), y), C1) -> (add/sub (shl x, C0 + C1), (shl y, C1))" 2nd Try
First time caused build failure:
    https://lab.llvm.org/buildbot/#/builders/183/builds/10447
but after investigating it seems to be unrelated. The same
test/build passed later with the original commit here:
    https://lab.llvm.org/buildbot/#/builders/183/builds/10448

This is just expanding the existing pattern that exists for AND/XOR/OR
and gets a bit more parallelism in from the instruction sequence.

Alive2:
Add  - https://alive2.llvm.org/ce/z/dSmPkV
Sub1 - https://alive2.llvm.org/ce/z/6rpi5V
Sub2 - https://alive2.llvm.org/ce/z/UfYeUd

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D141875
2023-01-27 20:35:40 -06:00
Noah Goldstein
423bcf89f1 Revert "Reorder (shl (add/sub (shl x, C0), y), C1) -> (add/sub (shl x, C0 + C1), (shl y, C1))"
This reverts commit edd80befeeb92000800ded2a6f3dcdfd672d95ea.

Caused test failures in Clangd: https://lab.llvm.org/buildbot/#/builders/183/builds/10447
reverting while investigating.
2023-01-27 18:44:45 -06:00
Noah Goldstein
edd80befee Reorder (shl (add/sub (shl x, C0), y), C1) -> (add/sub (shl x, C0 + C1), (shl y, C1))
This is just expanding the existing pattern that exists for AND/XOR/OR
and gets a bit more parallelism in from the instruction sequence.

Alive2:
Add  - https://alive2.llvm.org/ce/z/dSmPkV
Sub1 - https://alive2.llvm.org/ce/z/6rpi5V
Sub2 - https://alive2.llvm.org/ce/z/UfYeUd

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D141875
2023-01-27 17:45:36 -06:00
Sanjay Patel
c2ab7e2abd [InstCombine] simplify code for matching shift-logic-shift pattern; NFC
We can match and capture in one statement. Also, make the
code more closely resemble the description comment by using
the constant name of an operand value.
2023-01-18 08:13:37 -05:00
Pierre van Houtryve
b3fdb7b0cb [InstCombine] Combine lshr of add -> (a + b < a)
Tries to perform
  (lshr (add (zext X), (zext Y)), K)
  ->  (icmp ult (add X, Y), X)
  where
    - The add's operands are zexts from a K-bits integer to a bigger type.
    - The add is only used by the shr, or by iK (or narrower) truncates.
    - The lshr type has more than 2 bits (other types are boolean math).
    - K > 1

This seems to be a pattern that just comes from OpenCL front-ends, so adding DAG/GISel combines doesn't seem to be worth the complexity.

Original patch D107552 by @abinavpp - adapted to use (a + b < a) instead of uaddo following discussion on the review.
See this issue https://github.com/RadeonOpenCompute/ROCm/issues/488

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D138814
2023-01-10 03:37:23 -05:00
Sanjay Patel
21d3871b7c [InstCombine] fold not-shift of signbit to icmp+zext, part 2
Follow-up to:
6c39a3aae1dc

That converted a pattern with ashr directly to icmp+zext, and
this updates the pattern that we used to convert to.

This canonicalizes to icmp for better analysis in the minimum case
and shortens patterns where the source type is not the same as dest type:
https://alive2.llvm.org/ce/z/tpXJ64
https://alive2.llvm.org/ce/z/dQ405O

This requires an adjustment to an icmp transform to avoid infinite looping.
2023-01-08 12:04:09 -05:00