984 Commits

Author SHA1 Message Date
Mikhail Gudim
411cba215a
Revert "[InstCombine] Extend foldICmpBinOp to add-like or. (#71… (#76167)
…396)"

This reverts commit 8773c9be3d9868288f1f46957945d50ff58e4e91.
2023-12-21 11:41:09 -05:00
Mikhail Gudim
8773c9be3d
[InstCombine] Extend foldICmpBinOp to add-like or. (#71396)
InstCombine canonicalizes `add` to `or` when possible, but this makes
some optimizations applicable to `add` to be missed because they don't
realize that the `or` is equivalent to `add`.

In this patch we generalize `foldICmpBinOp` to handle such cases.
2023-12-20 17:28:57 -05:00
Yingwei Zheng
b7f50e13d8
[InstCombine] Improve foldICmpWithDominatingICmp with DomConditionCache (#75370)
This patch uses affected values from DomConditionCache(introduced by #73662), instead of a cheap/incomplete check `getSinglePredecessor`.
2023-12-14 21:02:10 +08:00
Kazu Hirata
a16429365c [Transforms] Remove unnecessary includes (NFC) 2023-12-09 18:23:06 -08:00
Nikita Popov
4a2a6397f1 [InstCombine] Relax one-use check for icmp of gep fold
Instead of checking whether the GEP as a whole is constant, only
check whether it has constant incides. This matches what we do in
other places in this code.

This has little practical impact, because it is mostly already
handled through other cases anyway. We see a difference for
non-inbounds equality comparisons.
2023-12-08 15:45:58 +01:00
Nikita Popov
cf47af493b
[InstCombine] Generalize folds for inversion of icmp operands (#74317)
We have a bunch of folds that basically perform X pred Y to ~Y pred ~X
for various special cases where this saves an instruction.

Generalize these folds to use isFreeToInvert(). We have to make sure
that we consume an instruction in either of the inversions, otherwise
we're just going to swap the icmp back and forth.

Fixes https://github.com/llvm/llvm-project/issues/74302.
2023-12-08 11:25:41 +01:00
Nikita Popov
d77067d08a
[ValueTracking] Add dominating condition support in computeKnownBits() (#73662)
This adds support for using dominating conditions in computeKnownBits()
when called from InstCombine. The implementation uses a
DomConditionCache, which stores which branches may provide information
that is relevant for a given value.

DomConditionCache is similar to AssumptionCache, but does not try to do
any kind of automatic tracking. Relevant branches have to be explicitly
registered and invalidated values explicitly removed. The necessary
tracking is done inside InstCombine.

The reason why this doesn't just do exactly the same thing as
AssumptionCache is that a lot more transforms touch branches and branch
conditions than assumptions. AssumptionCache is an immutable analysis
and mostly gets away with this because only a handful of places have to
register additional assumptions (mostly as a result of cloning). This is
very much not the case for branches.

This change regresses compile-time by about ~0.2%. It also improves
stage2-O0-g builds by about ~0.2%, which indicates that this change results
in additional optimizations inside clang itself.

Fixes https://github.com/llvm/llvm-project/issues/74242.
2023-12-06 14:17:18 +01:00
Nikita Popov
d6e8f3b9a2 [ValueTracking] Convert isKnownPositive() to use SimplifyQuery (NFC) 2023-11-29 11:08:39 +01:00
Nikita Popov
d01237c45b
[InstCombine] Make indexed compare fold GEP source type independent (#71663)
The indexed compare fold converts comparisons of GEPs with same
(indirect) base into comparisons of offset. Currently, it only supports
GEPs with the same source element type.

This change makes the transform operate on offsets instead, which
removes the type dependence. To keep closer to the scope of the original
implementation, this keeps the limitation that we should only have at
most one variable index per GEP.

This addresses the main regression from
https://github.com/llvm/llvm-project/pull/68882.

TBH I have some doubts that this is really a useful transform (at least
for the case where there are extra pointer users, so we have to
rematerialize pointers at some point). I can only assume it exists for a
reason...
2023-11-28 09:16:04 +01:00
Noah Goldstein
b7c0f79926 [InstCombine] Replace isFreeToInvert + CreateNot with getFreelyInverted
This is nearly an NFC, the only change is potentially to order that
values are created/names.

Otherwise it is a slight speed boost/simplification to avoid having to
go through the `getFreelyInverted` recursive logic twice to simplify
the extra `not` op.
2023-11-20 17:59:27 -06:00
Noah Goldstein
99387e33dc [InstCombine] Add transforms for (icmp uPred (trunc x),(truncOrZext(y)))->(icmp uPred x,y)
Three transforms (all commutative):
https://alive2.llvm.org/ce/z/Bc-nh4

Closes #71309
2023-11-19 12:15:04 -06:00
elhewaty
daddf402d9
[InstCombine] Fold xored one-complemented operand comparisons (#69882)
- [InstCombine] Add test coverage for comparisons of operands including
one-complemented oparands(NFC).
- [InstCombine] Fold xored one-complemented operand comparisons.
Alive2: https://alive2.llvm.org/ce/z/PZMJeB
Fixes #69803.
2023-11-14 21:54:03 +08:00
Léonard Oest O'Leary
ff36411b23
[InstCombine] Use zext's nneg flag for icmp folding (#70845)
This PR fixes https://github.com/llvm/llvm-project/issues/55013 : the
max intrinsics is not generated for this simple loop case :
https://godbolt.org/z/hxz1xhMPh. This is caused by a ICMP not being
folded into a select, thus not generating the max intrinsics.

For the story :

Since LLVM 14, SCCP pass got smarter by folding sext into zext for
positive ranges : https://reviews.llvm.org/D81756. After this change,
InstCombine was sometimes unable to fold ICMP correctly as both of the
arguments pointed to mismatched zext/sext. To fix this, @rotateright
implemented this fix : https://reviews.llvm.org/D124419 that tries to
resolve the mismatch by knowing if the argument of a zext is positive
(in which case, it is like a sext) by using ValueTracking, however
ValueTracking is not smart enough to infer that the value is positive in
some cases. Recently, @nikic implemented #67982 which keeps the
information that a zext is non-negative. This PR simply uses this
information to do the folding accordingly.

TLDR : This PR uses the recent nneg tag on zext to fold the icmp
accordingly in instcombine.

This PR also contains test cases for sext/zext folding with InstCombine
as well as a x86 regression tests for the max/min case.
2023-11-13 00:53:53 +08:00
Nikita Popov
567c02a80e [InstCombine] Remove inttoptr/ptrtoint handling from indexed compare fold
Looking through inttoptr / ptrtoint intermixed with GEPs is very
questionable from a provenance perspective. We also don't seem to
have any test coverage that shows this is useful (apart from one
test I added to guard against a crash).
2023-11-08 11:13:57 +01:00
Nikita Popov
abc27bd31f [InstCombine] Avoid some FP cast constant expressions (NFCI)
Instead of doing fptoxi and xitofp casts to check for round-trip,
directly check the IsExact flag on the convertToInteger() API.
2023-11-06 14:42:42 +01:00
Nikita Popov
03110ddeb2 [IR] Remove ZExtOperator (NFC)
Now that zext constant expressions are no longer supported,
ZExtInst should be used instead.
2023-11-03 14:52:59 +01:00
Nikita Popov
930bc6c7b5 [InstCombine] Avoid use of ConstantExpr::getSExtOrTrunc()
InstCombine will canonicalize the index type, no need to handle
the non-canonical case.
2023-11-01 16:10:57 +01:00
Nikita Popov
5c8a71d82b [InstCombine] Remove unnecessary icmp of all-zero gep folds (NFC)
All-zero GEPs will be removed anyway, no need to special-case them
here.
2023-10-30 10:01:21 +01:00
Amara Emerson
2228b35f93 Revert "Revert "[InstCombine] Add oneuse checks to shr + cmp constant folds.""
This reverts commit d37b283cdd37feca5ea71456cf350005add268e7.

There was a simple logic bug in the else path. Tests codegen is different with
the fix.
2023-10-28 03:12:15 -07:00
Noah Goldstein
0289dad538 [InstCombine] Add folds for (icmp eq/ne (and (add/sub/xor A, P2), P2), 0/P2)
- `(icmp eq/ne (and (add/sub/xor X, P2), P2), P2)`
    -> `(icmp eq/ne (and X, P2), 0)`
- `(icmp eq/ne (and (add/sub/xor X, P2), P2), 0)`
    -> `(icmp eq/ne (and X, P2), P2)`

Folds like this come up with reasonable regularity in odd/even loops.

Proofs: https://alive2.llvm.org/ce/z/45pq2x

Closes #67836
2023-10-27 17:36:30 -05:00
Amara Emerson
d37b283cdd Revert "[InstCombine] Add oneuse checks to shr + cmp constant folds."
This reverts commit a66051c68a43af39f9fd962f71d58ae0efcf860d.

This seems to have caused issue #70509 so reverting until I have time
to investigate.
2023-10-27 14:27:58 -07:00
Amara Emerson
a66051c68a [InstCombine] Add oneuse checks to shr + cmp constant folds.
This change has virtually no code size regressions on the llvm test suite (+ SPECs)
while having these improvements (measured with -Os on Darwin arm64):

External/S.../CFP2006/450.soplex/450.soplex    214024.00      213920.00     -0.0%
External/S...7speed/641.leela_s/641.leela_s     93412.00       93348.00     -0.1%
External/S...17rate/541.leela_r/541.leela_r     93412.00       93348.00     -0.1%
MultiSourc.../Applications/JM/lencod/lencod    426044.00      425748.00     -0.1%
MultiSourc...rks/mediabench/gsm/toast/toast     20436.00       20416.00     -0.1%
MultiSourc...ench/telecomm-gsm/telecomm-gsm     20436.00       20416.00     -0.1%
MultiSourc...Prolangs-C/assembler/assembler     16172.00       16156.00     -0.1%
MultiSourc...nch/mpeg2/mpeg2dec/mpeg2decode     35332.00       35256.00     -0.2%
SingleSour...Adobe-C++/stepanov_abstraction      6904.00        6888.00     -0.2%
External/SPEC/CINT2000/254.gap/254.gap         366060.00      365132.00     -0.3%
MultiSourc...-ProxyApps-C++/PENNANT/PENNANT     79688.00       79484.00     -0.3%
External/S...NT2006/464.h264ref/464.h264ref    352044.00      351132.00     -0.3%
SingleSour...arks/Adobe-C++/functionobjects     15524.00       15480.00     -0.3%
SingleSour...arks/Adobe-C++/stepanov_vector     10728.00       10696.00     -0.3%
SingleSour...ks/Misc-C++/stepanov_container     16900.00       16848.00     -0.3%
MultiSource/Applications/oggenc/oggenc         124184.00      123780.00     -0.3%
SingleSour...tout-C++/Shootout-C++-wordfreq      7060.00        7036.00     -0.3%
MultiSourc...ity-rijndael/security-rijndael      8976.00        8936.00     -0.4%
MultiSource/Benchmarks/McCat/18-imp/imp          9816.00        9772.00     -0.4%
SingleSour...chmarks/Misc-C++/stepanov_v1p2      1772.00        1764.00     -0.5%
MultiSourc...iabench/g721/g721encode/encode      5492.00        5464.00     -0.5%
MultiSourc...rks/McCat/03-testtrie/testtrie      1364.00        1344.00     -1.5%
SingleSour.../execute/GCC-C-execute-pr42833       400.00         364.00     -9.0%

Doing so also prevents a regression described in https://reviews.llvm.org/D143624

Differential Revision: https://reviews.llvm.org/D149918
2023-10-26 11:36:10 -07:00
Nikita Popov
ea99df2e84 [InstCombine] Rename some variables (NFC)
Split NFC rename out from #69882.
2023-10-25 17:08:40 +02:00
Nikita Popov
c912f88c21 [InstCombine] Remove false commutativity from processUMulZExtIdiom() (NFCI)
This fold requires a fold against a constant, which will always be
on the RHS. If the swapped fold actually did trigger, it would
result in a miscompile, because it did not work with the swapped
predicate when swapping operands.
2023-10-25 11:31:31 +02:00
Nikita Popov
82aeedc852 [InstCombine] Remove unnecessary eq/ne handling from processUMulZExtIdiom() (NFCI)
The eq/ne pattern being matched will get canonicalized to the
ugt/ult form.
2023-10-25 11:18:44 +02:00
Nikita Popov
4baeed803f [InstCombine] Remove unnecessary handling of non-canonical predicates (NFCI)
ule/uge with a constant will be converted to ult/ugt, so there is
no need to handle these variants.
2023-10-25 10:42:25 +02:00
Nikita Popov
3a39346a06 [InstCombine] Remove unnecessary typed pointer handling (NFC) 2023-10-25 10:34:39 +02:00
Nikita Popov
7df92fbe74 [InstCombine] Remove redundant icmp gep fold (NFCI)
Gep with zero indices will be folded away independently. It will
only be retained for splat geps, for which the transform is not
applicable anyway.
2023-10-25 10:31:02 +02:00
Nikita Popov
b901acad54 [InstCombine] Remove unnecessary typed pointer fold (NFCI)
Pointer bitcasts will be optimized away, no need to fold them for
icmps in particular.
2023-10-24 16:43:22 +02:00
XChy
b22917e6e2
[InstCombine] Fold Ext(i1) Pred shr(A, BW - 1) => i1 Pred A s< 0 (#68244)
Resolves #67916 .
This patch folds `Ext(icmp (A, xxx)) Pred shr(A, BW - 1)` into `i1 Pred
A s< 0`.
[Alive2](https://alive2.llvm.org/ce/z/k53Xwa).
2023-10-13 22:02:57 +08:00
Antonio Frighetto
1c12dcc910 [InstCombine] Extend sext/zext boolean additions to vectors
Reported-by: shao-hua-li

Fixes: https://github.com/llvm/llvm-project/issues/68745.
2023-10-12 14:38:54 +00:00
Yingwei Zheng
b3b3336e82
[InstCombine] Simplify the pattern a ne/eq (zext/sext (a ne/eq c)) (#65852)
This patch folds the pattern `a ne/eq (zext/sext (a ne/eq c))` into a boolean constant or a compare.
Clang vs GCC: https://godbolt.org/z/4ro817WE8
Proof for `zext`: https://alive2.llvm.org/ce/z/6z9NRF
Proof for `sext`: https://alive2.llvm.org/ce/z/tv5wuE
Fixes #65073.
2023-10-06 20:57:58 +08:00
elhewaty
5d8fb473d3
[InstCombine] Fold comparison of adding two z/sext booleans (#67895)
- Add test coverage for sext/zext boolean additions
- [InstCombine] Fold comparison of adding two z/sext booleans

Fixes https://github.com/llvm/llvm-project/issues/64859.
2023-10-06 17:29:13 +08:00
Yingwei Zheng
c4e2fcff78
[InstCombine] Don't simplify icmp eq/ne OneUse(A ^ Cst1), Cst2 in foldICmpEquality
This special case will be handled in foldICmpXorConstant later.
See also commit e9cb50a1e351e90be1a8e4ac1a4564cfc44a984b.
2023-09-29 21:21:00 +08:00
Yingwei Zheng
e9cb50a1e3
[InstCombine] Fix infinite loop in #67273
Closes #67783.
2023-09-29 20:26:39 +08:00
Nikita Popov
6ce7461eea [InstCombine] Avoid uses of ConstantExpr::getCast()
Add a generalized getLosslessTrunc() helper to simplify this.
2023-09-29 11:32:41 +02: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
Yingwei Zheng
e158add121
[InstCombine] Canonicalize icmp eq/ne (A ^ C), B to icmp eq/ne (A ^ B), C (#67273)
This patch canonicalizes `icmp eq/ne (A ^ Cst), B` to `icmp eq/ne (A ^ B), Cst` since the latter form exposes more optimizations.
Proof: https://alive2.llvm.org/ce/z/9DbhGc
Fixes #65968.
2023-09-26 19:33:31 +08:00
Yingwei Zheng
416e891d66
[Reland][InstCombine] Fold icmp eq/ne min|max(X, Y), Z (#67087)
This patch further improves the simplification of pattern `icmp eq/ne
min|max(X, Y), Z` as discussed in
[D156238](https://reviews.llvm.org/D156238).
When `X < Z`:
`min(X, Y) == Z -> false`
`min(X, Y) != Z -> true`
`max(X, Y) == Z -> Y == Z`
`max(Y, Z) != Z -> Y != Z`
When `X > Z`:
`max(X, Y) == Z -> false`
`max(X, Y) != Z -> true`
`min(X, Y) == Z -> Y == Z`
`min(Y, Z) != Z -> Y != Z`

Alive2:  https://alive2.llvm.org/ce/z/evkmaq
2023-09-25 15:46:39 +08:00
Vitaly Buka
4c1c96e6fc Revert "[InstCombine] Fold icmp eq/ne min|max(X, Y), Z (#67087)"
Details in https://reviews.llvm.org/D156238

This reverts commit d2abe8dc662a94e6c9aca5b64af53c7f815b5701.
2023-09-24 18:48:02 -07:00
Yingwei Zheng
d2abe8dc66
[InstCombine] Fold icmp eq/ne min|max(X, Y), Z (#67087)
This patch further improves the simplification of pattern `icmp eq/ne
min|max(X, Y), Z` as discussed in
[D156238](https://reviews.llvm.org/D156238).
When `X < Z`:
`min(X, Y) == Z -> false`
`min(X, Y) != Z -> true`
`max(X, Y) == Z -> Y == Z`
`max(Y, Z) != Z -> Y != Z`
When `X > Z`:
`max(X, Y) == Z -> false`
`max(X, Y) != Z -> true`
`min(X, Y) == Z -> Y == Z`
`min(Y, Z) != Z -> Y != Z`

Alive2:  https://alive2.llvm.org/ce/z/evkmaq
2023-09-25 03:59:49 +08:00
Yingwei Zheng
5163319ee2
[InstCombine] Use ConstantInt::getBool instead of Constant::getIntegerValue. NFC.
See also https://reviews.llvm.org/D156238#inline-1546774
2023-09-16 17:41:10 +08:00
Noah Goldstein
119194ada6 [InstCombine] Transform (icmp ult/uge (and X, Y), X) -> (icmp ne/eq (and X, Y), X)
eq/ne are generally easier to reason about elsewhere.

ult -> ne: https://alive2.llvm.org/ce/z/5wxXGt
uge -> eq: https://alive2.llvm.org/ce/z/Dw6kqG

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D145425
2023-09-13 15:50:17 -05:00
Jeremy Morse
e54277fa10 [NFC][RemoveDIs] Use iterators over inst-pointers when using IRBuilder
This patch adds a two-argument SetInsertPoint method to IRBuilder that
takes a block/iterator instead of an instruction, and updates many call
sites to use it. The motivating reason for doing this is given here [0],
we'd like to pass around more information about the position of debug-info
in the iterator object. That necessitates passing iterators around most of
the time.

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

Differential Revision: https://reviews.llvm.org/D152468
2023-09-11 20:01:19 +01:00
Yingwei Zheng
44e5afdb91
[InstCombine] Generalize foldICmpWithMinMax
This patch generalizes the fold of `icmp pred min/max(X, Y), Z` to address the issue https://github.com/llvm/llvm-project/issues/62898.

For example, we can fold `smin(X, Y) < Z` into `X < Z` when `Y > Z` is implied by constant folds/invariants/dom conditions.

Alive2 (with `--disable-undef-input` due to the limitation of --smt-to=10000): https://alive2.llvm.org/ce/z/rB7qLc
You can run the standalone translation validation tool `alive-tv` locally to verify these transformations.
```
alive-tv transforms.ll --smt-to=600000 --exit-on-error
```

Reviewed By: goldstein.w.n

Differential Revision: https://reviews.llvm.org/D156238
2023-09-11 02:26:48 +08:00
bipmis
370880cdcc [InstCombine] Fold icmp into phi beyond the same BB.
The icmp is being folded in phi only if they belong in the same BB.
This patch extends the same beyond the BB.
Have seen scenarios where this seems to be beneficial.

Differential Revision: https://reviews.llvm.org/D157740
2023-09-07 16:53:29 +01:00
Noah Goldstein
3cf54c533d [InstCombine] Add transforms for (icmp upred (or X, Y), X)
We can simplify ule/ugt -> eq/ne and we can remove the `Or` in some
cases of eq/ne.

`icmp (X | Y) u<= X` --> `(X | Y) == X`
    - https://alive2.llvm.org/ce/z/qnbbPv
`icmp (X | Y) u> X` --> `(X | Y) != X`
    - https://alive2.llvm.org/ce/z/fvLqg3
`icmp (X | Y) eq/ne X`
     - --> `(~X & Y) eq/ne 0` iff X is freely invertible
     - --> `(X & ~Y) eq/ne -1` iff Y is freely invertible
          - https://alive2.llvm.org/ce/z/cpPV_W

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D144610
2023-08-16 02:00:15 -05:00
Bjorn Pettersson
fd05c34b18 Stop using legacy helpers indicating typed pointer types. NFC
Since we no longer support typed LLVM IR pointer types, the code can
be simplified into for example using PointerType::get directly instead
of using Type::getInt8PtrTy and Type::getInt32PtrTy etc.

Differential Revision: https://reviews.llvm.org/D156733
2023-08-02 12:08:37 +02:00
Maksim Kita
ac357a4773 [InstCombine] Fold icmp or sub chain ((x1 - y1) | (x2 - y2)) == 0
Improve ((x1 ^ y1) | (x2 ^ y2)) == 0 transform to also support sub ((x1 - y1) | (x2 - y2)) == 0.
Depends D155703.

Differential Revision: https://reviews.llvm.org/D155704
2023-07-26 19:16:41 +03:00
Nikita Popov
8249d6724c [InstCombine] Avoid uses of ConstantExpr::getOr()
Replace these with IRBuilder uses, as we don't (from a type
perspective) care about Constant results.

Switch the predicate to m_ImmConstant() instead of isa<Constant>
to guarantee that these do get folded away and our assumptions
about simplifications hold true.
2023-07-24 16:50:45 +02:00