422 Commits

Author SHA1 Message Date
Craig Topper
56248caa3b
[InstCombine] Explicitly set disjoint flag when converting xor to or. (#74229) 2023-12-06 09:41:59 -08:00
Nikita Popov
e4710872e9 [InstCombine] Use disjoint flag in add of or fold
Use disjoint instead of haveNoCommonBitsSet(), which is slightly
stronger in case the information used to infer disjoint has been
lost.

Introduce the m_DisjointOr() matcher to make handling cases like
this cleaner.
2023-12-05 15:06:40 +01:00
shaojingzhi
9a99a1a39e
[InstCombine] Add one-use limitation to box multiply fold (#72876)
Check the operands of I are used in no more than one place, which can
not be deleted, cause a mul instruction has far more weight than add and
shl instruction in IR, thus this method cannot achieve the goal of
simplifying instructions, just return null.
2023-12-04 14:14:59 +01:00
Antonio Frighetto
7d5f79f13b [InstCombine] Handle equality comparison when flooring by constant 2
Support `icmp eq` when reducing signed divisions by power of 2 to
arithmetic shift right, as `icmp ugt` may have been canonicalized
into `icmp eq` by the time additions are folded into `ashr`.

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

Proof: https://alive2.llvm.org/ce/z/8-eUdb.
2023-11-30 11:57:01 +01:00
Craig Topper
03d4a9d94d
[InstCombine] Set disjoint flag when turning Add into Or. (#72702)
The disjoint flag was recently added to IR in #72583
2023-11-27 12:54:11 -08:00
Noah Goldstein
5271d33077 [InstCombine] Add transform for ~X + ~Y) -> -2 - Y - X
Proof: https://alive2.llvm.org/ce/z/36FySK

Closes #66787.
2023-11-20 17:59:27 -06: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
d01857803f [InstCombine] Make isFreeToInvert check recursively.
Some Instructions (select/min/max) are inverted by just inverting the
operands. So the answer of whether they are free to invert is really
just whether the operands are free to invert.

Differential Revision: https://reviews.llvm.org/D159056
2023-11-20 17:59:26 -06:00
Noah Goldstein
dbf6f30926 [InstCombine] Add folds for (X + Y) - (W + Z)
If `Y` and `Z` are constant then we can simplify to `(X - W) + (Y -
Z)`. If `Y == Z` we can fold to `X - W`.

Note these transform exist outside of InstCombine. The purpose of this
commit is primarily to make it so that folds can generate these
simplifiable patterns without having to worry about creating an inf
loop.
2023-11-20 17:59:26 -06:00
Yingwei Zheng
dfe1d35c62
[InstCombine] Propagate NSW/NUW flags for (X - Y) - Z -> X - (Y + Z) (#72693)
Alive2: https://alive2.llvm.org/ce/z/gqeaVo

Related patch:
31d219d299
2023-11-20 00:02:23 +08:00
Yingwei Zheng
8e516d48fe
[InstCombine] Infer nuw flags for C-(X+C2) -> (C-C2)-X (#72373)
This patch improves https://reviews.llvm.org/D152068 by inferring NUW
flags for sub insts.
It is worth noting that we don't need to check overflow for `C-C2`.
Alive2: https://alive2.llvm.org/ce/z/uutGpS

This missed optimization is discovered with the help of
https://github.com/AliveToolkit/alive2/pull/962.
2023-11-16 02:35:47 +08:00
Z572
76ba660688
[InstCombine] Follow-up to "When -A + B both have nsw flag, set nsw f… (#72282)
…lag."

In 3c037b7306f57039e24a1470687cc39a795584ac, Use cast instead of dyn_cast for cast that cannot fail.
2023-11-15 00:42:02 +08:00
Z572
3c037b7306
[InstCombine] When -A + B both have nsw flag, set nsw flag. (#72127)
Fixes #72119

https://alive2.llvm.org/ce/z/5f_QuC
2023-11-14 13:48:51 +08:00
Nikita Popov
25af06fd7a [InstCombine] Avoid use of FP cast constant expressions (NFC)
Use the constant folding API instead. As we're working on plain
ConstantFP, this should always succeed.
2023-11-06 15:22:33 +01:00
Dhruv Chawla
be57381a4a
[InstCombine] Create a class to lazily track computed known bits (#66611)
This patch adds a new class "WithCache" which stores a pointer to
any type passable to computeKnownBits along with KnownBits
information which is computed on-demand when getKnownBits()
is called. This allows reusing the known bits information when it is
passed as an argument to multiple functions.

It also changes a few functions to accept WithCache(s) so that
known bits information computed in some callees can be propagated to
others from the top level visitAddSub caller.

This gives a speedup of 0.14%:
https://llvm-compile-time-tracker.com/compare.php?from=499d41cef2e7bbb65804f6a815b9fa8b27efce0f&to=fbea87f1f1e6d5552e2bc309f8e201a3af6d28ec&stat=instructions:u
2023-10-17 21:40:18 +05:30
Nikita Popov
80fa5a6377 [ValueTracking] Use SimplifyQuery in haveNoCommonBitsSet() (NFC)
Pass SimplifyQuery instead of unpacked list of arguments.
2023-10-10 11:39:59 +02:00
Nikita Popov
1b8fb1a664 [InstCombine] Avoid some uses of ConstantExpr::getZExt() (NFC)
Let the IRBuilder constant fold instead.
2023-09-28 15:31:42 +02:00
Nikita Popov
1fc73cacb2 [InstCombine] Propagate nsw flag when negating
When pushing a sub nsw 0, %x negation into an expression, try to
preserve the nsw flag for the cases where this is possible. Do this
by passing the flag through recursive Negator::negate() calls.

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

Differential Revision: https://reviews.llvm.org/D158510
2023-09-14 09:09:45 +02:00
Christoph Stiller
3af4590506 [InstCombine] Contracting x^2 + 2*x*y + y^2 to (x + y)^2 (float)
Resolves https://github.com/llvm/llvm-project/issues/61296 if https://reviews.llvm.org/D156026 didn't suffice.

Reviewed By: goldstein.w.n

Differential Revision: https://reviews.llvm.org/D158079
2023-09-01 15:02:12 -05:00
Matt Arsenault
033d6ffb53 IR: Add operator | and & for FastMathFlags
We only had |= and &= which was annoying.
2023-08-28 19:25:54 -04:00
Noah Goldstein
9c375a457e [InstCombine] Transform (add (shl (neg X), Cnt)) -> (sub (shl X, Cnt))
Just a simple instruction save.

Proof: https://alive2.llvm.org/ce/z/Vb484j

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D154807
2023-08-16 22:43:04 -05:00
Matt Arsenault
f7f5d348a3 InstCombine: Fold fneg (ldexp x, n) -> ldexp (fneg x), n
https://reviews.llvm.org/D156579
2023-08-11 19:16:20 -04:00
Christoph Stiller
0bdab96a5a [InstCombine] Contract x^2 + 2*x*y + y^2 to (x + y)^2 (integer)
There are a number of variations on the pattern, depending on
order.

Proof: https://alive2.llvm.org/ce/z/ri5iFw

Differential Revision: https://reviews.llvm.org/D156026
2023-08-09 14:19:21 +02:00
Matt Arsenault
020d2fb771 InstCombine: Avoid repeated m_OneUse checks
The check was repeated for the fmul and fdiv case, and the caller was
already checking anyway.
2023-08-02 10:42:56 -04:00
Matt Arsenault
ed0dbfef7a InstCombine: Remove dead fsub-as-fneg handling
The above combine matching m_FNeg to produce a new fneg always would
hide this.
2023-08-02 10:42:56 -04:00
Antonio Frighetto
f12a5561b2 [InstCombine] Fold binop of select and cast of select condition
Simplify binary operations, whose operands involve a `select`
instruction and a cast of the `select` condition. Specifically,
the binop is canonicalized into a `select` with folded arguments
as follows:

(Binop (zext C), (select C, T, F))
  -> (select C, (binop 1, T), (binop 0, F))

(Binop (sext C), (select C, T, F))
  -> (select C, (binop -1, T), (binop 0, F))

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

Differential Revision: https://reviews.llvm.org/D153963
2023-07-20 19:42:58 +00:00
Nikita Popov
21827268ad [InstCombine] Fold add of zext and sext of i1
(zext a) + (sext a) is 0 if a is a bool.

The regression is in a fuzzer-generated test.

Proof: https://alive2.llvm.org/ce/z/KotnN6
2023-07-14 14:52:13 +02:00
Matt Arsenault
0f4eb557e8 ValueTracking: Replace CannotBeNegativeZero
This is now just a wrapper around computeKnownFPClass.
2023-07-12 13:14:05 -04:00
Nikita Popov
b45a73f4d0 [InstCombine] Fold binop of shifts with related amounts
Fold

  binop(shift(ShiftedC1, ShAmt), shift(ShiftedC2, add(ShAmt, AddC)))
    ->
  shift(binop(ShiftedC1, shift(ShiftedC2, AddC)), ShAmt)

where both shifts are the same and AddC is a valid shift amount.

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

Differential Revision: https://reviews.llvm.org/D152927
2023-06-28 09:54:36 +02:00
Noah Goldstein
91cdffcb2f [InstCombine] Transform (binop1 (binop2 (lshift X,Amt),Mask),(lshift Y,Amt))
If `Mask` and `Amt` are not constants and `binop1` and `binop2` are
the same we can transform to:
`(binop (lshift (binop X, Y), Amt), Mask)`

If `binop` is `add`, `lshift` must be `shl`.

If `Mask` and `Amt` are constants `C` and `C1` respectively.
We can transform to:
`(lshift1 (binop1 (binop2 X, (inv_lshift1 C, C1), Y)), C1)`

Saving an instruction IFF:
`lshift1` is same opcode as `lshift2`
Either `bitwise1` and/or `bitwise2` is `and`.

Proofs(1/2): https://alive2.llvm.org/ce/z/BjN-m_
Proofs(2/2): https://alive2.llvm.org/ce/z/bZn5QB

This is to help fix the regression caused in D151807

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D152568
2023-06-13 20:08:35 -05:00
khei4
116670d192 [InstCombine] add overflow checking on Add ~X + C --> (C-1) - X
Differential Revision: https://reviews.llvm.org/D152088
2023-06-06 12:24:45 +09:00
khei4
4db8d4f839 [InstCombine] add overflow checking on AddSub C-(X+C2) --> (C-C2)-X
Differential Revision: https://reviews.llvm.org/D152068
2023-06-05 20:05:06 +09:00
Serguei Katkov
f38365aef4 [InstCombine] Add support for maximum(a,b) + minimum(a,b) => a + b
Unfortunately alive2 cannot prove the correctness due to fails by timeout even for
float type half.

However it should be correct. If a and b are not NaN, maximum and minimum will just
return different values (a and b) and take into account a + b == b + a this is the same.
If a or b is NaN, than maximum and minimum are equal to NaN and NaN + NaN is NaN.
a + b is also a NaN.

In terms of preserving fast flags, we cannot preserve ninf due to
minimum(NaN, Infinity) == maximum(NaN, Infinity) == NaN,
minimum(NaN, Infinity) +ninf maximum(NaN, Infinity) == NaN +ninf NaN = NaN
However transformation will change
minimum(NaN, Infinity) + maximum(NaN, Infinity) to NaN +ninf Infinity == poison.

But if fadd is marked as nnan, we can preserve because NaN +ninf/nnan NaN = poison as well.

The same optimization for
  maximum(a,b) * minimum(a,b) => a * b
is added.
All said above for fadd is correct for fmul.

Reviewed By: mkazantsev
Differential Revision: https://reviews.llvm.org/D147299
2023-04-07 12:38:04 +07:00
Serguei Katkov
624973806c [InstCombine] Add support for max(a,b) + min(a,b) => a + b. Re-land.
The same optimization for
  max(a,b) * min(a,b) => a * b
is added.

Correctness check:
uadd: https://alive2.llvm.org/ce/z/2rXDek
sadd: https://alive2.llvm.org/ce/z/zNu_er
uadd + nuw/nsw: https://alive2.llvm.org/ce/z/EaiNjB
sadd + nuw/nsw: https://alive2.llvm.org/ce/z/w_2Nrs

umul: https://alive2.llvm.org/ce/z/dgXRLr
smul: https://alive2.llvm.org/ce/z/hBjGzz
umul + nuw/nsw: https://alive2.llvm.org/ce/z/EaiNjB
smul + nuw/nsw: https://alive2.llvm.org/ce/z/87MNeS

Reviewed By: goldstein.w.n
Differential Revision: https://reviews.llvm.org/D147296
2023-04-07 11:56:05 +07:00
Serguei Katkov
4665f3c838 Revert "[InstCombine] Add support for max(a,b) + min(a,b) => a + b."
Revert commit due to failure on buildbot:
error: 'match_combine_or' may not intend to support class template argument deduction

This reverts commit b86a06ef284f2637bef89bf5bb20157a8b195568.
2023-04-07 11:14:28 +07:00
Serguei Katkov
b86a06ef28 [InstCombine] Add support for max(a,b) + min(a,b) => a + b.
The same optimization for
  max(a,b) * min(a,b) => a * b
is added.

Correctness check:
uadd: https://alive2.llvm.org/ce/z/2rXDek
sadd: https://alive2.llvm.org/ce/z/zNu_er
uadd + nuw/nsw: https://alive2.llvm.org/ce/z/EaiNjB
sadd + nuw/nsw: https://alive2.llvm.org/ce/z/w_2Nrs

umul: https://alive2.llvm.org/ce/z/dgXRLr
smul: https://alive2.llvm.org/ce/z/hBjGzz
umul + nuw/nsw: https://alive2.llvm.org/ce/z/EaiNjB
smul + nuw/nsw: https://alive2.llvm.org/ce/z/87MNeS

Reviewed By: goldstein.w.n
Differential Revision: https://reviews.llvm.org/D147296
2023-04-07 10:24:07 +07:00
Jun Zhang
3ecf731376
[InstCombine] Reduce absolute diff from min+max+sub
This patch implements fold: max(a,b) nsw/nuw - min(a,b) --> abs(a nsw - b)

Alive2: https://alive2.llvm.org/ce/z/4yLp7D
Fixes: https://github.com/llvm/llvm-project/issues/61228

Signed-off-by: Jun Zhang <jun@junz.org>

Differential Revision: https://reviews.llvm.org/D145540
2023-03-10 08:00:40 +08:00
Sanjay Patel
542e70f96c [InstCombine] reassociate subtract-from-constant to add-constant
(C - X) + Y --> (Y - X) + C

Moving the constant operand to an 'add' gives more
flexibility to subsequent reassociation patterns,
and it may be better for codegen on targets that
don't have subtract-from-immediate instructions.
2023-02-28 14:21:13 -05:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Craig Topper
df76ff98e8 [InstCombine][LV] Fold (add (zext (add X, -1)), 1) -> (zext X) if X is non-zero.
This artifact can appear from the vectorizer. (add X, -1) is the
backedge taken count. It gets zero extended and then 1 is added to
it to get the trip count.

There is usually a dominating branch that rules out X being zero.

Alive: https://alive2.llvm.org/ce/z/NsRDwX
2023-01-30 17:45:01 -08:00
Sanjay Patel
1720ec6da0 [InstCombine] restrict no-wrap propagation for i1/i2 to avoid miscompiles
This transform was added with 68c197f07eeae71b9b7,
and the post-commit review noted the potential
for miscompiles at narrow bitwidths.

I'm not sure how to expose the i1 nuw bug because we
already simplify that, but other cases show that
there are missing transforms to add in follow-up
patches.
2023-01-18 10:32:12 -05:00
Sanjay Patel
830ac677b7 [InstCombine] reduce code duplication in visitSub(); NFC 2023-01-18 10:17:07 -05:00
Sanjay Patel
68c197f07e [InstCombine] factor difference-of-squares to reduce multiplication
(X * X) - (Y * Y) --> (X + Y) * (X - Y)
https://alive2.llvm.org/ce/z/BAuRCf

The no-wrap propagation could be relaxed in some cases,
but there does not seem to be an obvious rule for that.
2023-01-17 14:58:40 -05:00
Sanjay Patel
dedc58da49 [InstCombine] canonicalize a signum (spaceship) that ends in add
(A s>> (BW - 1)) + (zext (A s> 0)) --> (A s>> (BW - 1)) | (zext (A != 0))

https://alive2.llvm.org/ce/z/V-nM8N

This is not the form that we currently match as m_Signum(),
but I'm not sure if one is better than the other, so there's
a follow-up patch needed either way.

For this patch, it should be better for analysis to use a
not-null test and bitwise logic rather than >0 with add.
Codegen doesn't seem significantly different on any targets
that I looked at.

Also note that none of these variants is shown in issue #60012 -
those generally include at least one 'select', so that's likely
where these patterns will end up.
2023-01-16 12:47:21 -05:00
luxufan
561ee10a25 [InstCombine] Combine ZExt (B - A) + ZExt(A) to ZExt(B)
Combine ZExt (B - A) + ZExt(A) to ZExt(B)
https://alive2.llvm.org/ce/z/ESUwPi

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D139930
2022-12-21 22:53:29 +08:00
Matt Arsenault
8ab032fbe5 InstCombine: Fold fneg (copysign x, y) -> copysign x, (fneg y) 2022-12-20 17:14:34 -05:00
Sanjay Patel
86b4a2355e [InstCombine] fold flooring sdiv by power-of-2 to ashr
It's a bigger match than usual, but I have not found any
sub-patterns that reduce:
(X / DivC) + sext ((X & (SMin | (DivC - 1)) >u SMin) --> X >>s log2(DivC)

https://alive2.llvm.org/ce/z/MJzlhl

Fixes issue #55741
2022-12-18 08:17:07 -05:00
Sanjay Patel
93099c7d21 [InstCombine] allow more fast-math-flags to propagate in fneg-of-select fold
We were conservatively intersecting flags, but we can take the union here
because forbidden special values (nsz/nnan/ninf) are not altered by fneg.
So if they were guaranteed not present on the select or fneg, then they
are guaranteed not present on the new select. Alive2 appears to agree on
the test diffs (reduced to not include irrelevant flags like reassoc):
https://alive2.llvm.org/ce/z/ViqqrO

This prevents a potential regression if we tighten up the FMF behavior
for fabs with NAN as suggested in issue #59279.
2022-12-09 11:07:24 -05:00
chenglin.bi
6703290361 [InstCombine] fold sub + and pattern with specific const value
`C1 - ((C3 - X) & C2) --> (X & C2) + (C1 - (C2 & C3))`
when:
    (C3 - ((C2 & C3) - 1)) is pow2 &&
    ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1) &&
    C2 is negative pow2 || (C3 - X) is nuw

https://alive2.llvm.org/ce/z/HXQJV-

Fix: #58523

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D136582
2022-11-05 12:58:45 +08:00
zhongyunde
f58311796c [InstCombine] refactor the SimplifyUsingDistributiveLaws NFC
Precommit for D136015
Reviewed By: spatel
Differential Revision: https://reviews.llvm.org/D137019
2022-10-30 21:04:06 +08:00