248 Commits

Author SHA1 Message Date
David Bolvansky
3339db2884 [InstCombine] sub(xor(x, y), or(x, y)) -> neg(and(x, y))
Summary:
```
Name: sub(xor(x, y), or(x, y)) -> neg(and(x, y))
%or = or i32 %y, %x
%xor = xor i32 %x, %y
%sub = sub i32 %xor, %or
  =>
%sub1 = and i32 %x, %y
%sub = sub i32 0, %sub1

Optimization: sub(xor(x, y), or(x, y)) -> neg(and(x, y))
Done: 1
Optimization is correct!
```

https://rise4fun.com/Alive/8OI

Reviewers: lebedev.ri

Reviewed By: lebedev.ri

Subscribers: llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370945 91177308-0d34-0410-b5e6-96231b3b80d8
2019-09-04 18:03:21 +00:00
David Bolvansky
9a3265114a [InstCombine] Fold sub (and A, B) (or A, B)) to neg (xor A, B)
Summary:
```
Name: sub(and(x, y), or(x, y)) -> neg(xor(x, y))
%or = or i32 %y, %x
%and = and i32 %x, %y
%sub = sub i32 %and, %or
  =>
%sub1 = xor i32 %x, %y
%sub = sub i32 0, %sub1

Optimization: sub(and(x, y), or(x, y)) -> neg(xor(x, y))
Done: 1
Optimization is correct!
```

https://rise4fun.com/Alive/VI6

Found by @lebedev.ri. Also author of the proof.

Reviewers: lebedev.ri, spatel

Reviewed By: lebedev.ri

Subscribers: llvm-commits, lebedev.ri

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370934 91177308-0d34-0410-b5e6-96231b3b80d8
2019-09-04 17:30:53 +00:00
David Bolvansky
4743865ece [InstCombine] Fold sub (or A, B) (and A, B) to (xor A, B)
Summary:
```
Name: sub or and to xor
%or = or i32 %y, %x
%and = and i32 %x, %y
%sub = sub i32 %or, %and
  =>
%sub = xor i32 %x, %y

Optimization: sub or and to xor
Done: 1
Optimization is correct!
```
https://rise4fun.com/Alive/eJu

Reviewers: spatel, lebedev.ri

Reviewed By: lebedev.ri

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370883 91177308-0d34-0410-b5e6-96231b3b80d8
2019-09-04 12:00:33 +00:00
Roman Lebedev
a6ff94bf91 [InstCombine][NFC] Rename IsFreeToInvert() -> isFreeToInvert() for consistency
As per https://reviews.llvm.org/D65530#inline-592325

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368686 91177308-0d34-0410-b5e6-96231b3b80d8
2019-08-13 12:49:16 +00:00
Roman Lebedev
5ae3769ae0 [IR] SelectInst: add swapValues() utility
Summary:
Sometimes we need to swap true-val and false-val of a `SelectInst`.
Having a function for that is nicer than hand-writing it each time.

Reviewers: spatel, RKSimon, craig.topper, jdoerfert

Reviewed By: jdoerfert

Subscribers: jdoerfert, hiraditya, llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367547 91177308-0d34-0410-b5e6-96231b3b80d8
2019-08-01 12:31:35 +00:00
Sanjay Patel
79df64cbfa [InstCombine] canonicalize fneg before fmul/fdiv
Reverse the canonicalization of fneg relative to fmul/fdiv. That makes it
easier to implement the transforms (and possibly other fneg transforms) in
1 place because we can always start the pattern match from fneg (either the
legacy binop or the new unop).

There's a secondary practical benefit seen in PR21914 and PR42681:
https://bugs.llvm.org/show_bug.cgi?id=21914
https://bugs.llvm.org/show_bug.cgi?id=42681
...hoisting fneg rather than sinking seems to play nicer with LICM in IR
(although this change may expose analysis holes in the other direction).

1. The instcombine test changes show the expected neutral IR diffs from
   reversing the order.

2. The reassociation tests show that we were missing an optimization
   opportunity to fold away fneg-of-fneg. My reading of IEEE-754 says
   that all of these transforms are allowed (regardless of binop/unop
   fneg version) because:

   "For all other operations [besides copy/abs/negate/copysign], this
   standard does not specify the sign bit of a NaN result."
   In all of these transforms, we always have some other binop
   (fadd/fsub/fmul/fdiv), so we are free to flip the sign bit of a
   potential intermediate NaN operand.
   (If that interpretation is wrong, then we must already have a bug in
   the existing transforms?)

3. The clang tests shouldn't exist as-is, but that's effectively a
   revert of rL367149 (the test broke with an extension of the
   pre-existing fneg canonicalization in rL367146).

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367447 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-31 16:53:22 +00:00
Sanjay Patel
d76b11b54b [InstCombine] fold fadd+fneg with fdiv/fmul betweena
The backend already does this via isNegatibleForFree(),
but we may want to alter the fneg IR canonicalizations
that currently exist, so we need to try harder to fold
fneg in IR to avoid regressions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367227 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-29 13:50:25 +00:00
Sanjay Patel
9efe2bcad2 [InstCombine] reduce code for fadd with fneg operand; NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367224 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-29 13:20:46 +00:00
Sanjay Patel
f40aeae387 [InstCombine] fold fsub+fneg with fdiv/fmul between
The backend already does this via isNegatibleForFree(),
but we may want to alter the fneg IR canonicalizations
that currently exist, so we need to try harder to fold
fneg in IR to avoid regressions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367194 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-28 17:10:06 +00:00
Sanjay Patel
3798c1bc58 [InstCombine] remove flop from lerp patterns
(Y * (1.0 - Z)) + (X * Z) -->
Y - (Y * Z) + (X * Z) -->
Y + Z * (X - Y)

This is part of solving:
https://bugs.llvm.org/show_bug.cgi?id=42716

Factoring eliminates an instruction, so that should be a good canonicalization.
The potential conversion to FMA would be handled by the backend based on target
capabilities.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367101 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-26 11:19:18 +00:00
Roman Lebedev
d07ba468a4 [InstCombine] Y - ~X --> X + Y + 1 fold (PR42457)
Summary:
I *think* we'd want this new variant, because we obviously
have better handling for `add` as compared to `sub`/`not`.

https://rise4fun.com/Alive/WMn

Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=42457 | PR42457 ]]

Reviewers: spatel, nikic, huihuiz, efriedma

Reviewed By: spatel

Subscribers: RKSimon, llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365011 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-03 09:41:50 +00:00
Roman Lebedev
5b80637fd3 [InstCombine] (Y + ~X) + 1 --> Y - X fold (PR42459)
Summary:
To be noted, this pattern is not unhandled by instcombine per-se,
it is somehow does end up being folded when one runs opt -O3,
but not if it's just -instcombine. Regardless, that fold is
indirect, depends on some other folds, and is thus blind
when there are extra uses.

This does address the regression being exposed in D63992.

https://godbolt.org/z/7DGltU
https://rise4fun.com/Alive/EPO0

Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=42459 | PR42459 ]]

Reviewers: spatel, nikic, huihuiz

Reviewed By: spatel

Subscribers: llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364792 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-01 15:55:24 +00:00
Cameron McInally
35ebe10afc [InstCombine] Handle -(X-Y) --> (Y-X) for unary fneg when NSZ
Differential Revision: https://reviews.llvm.org/D62612

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363082 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-11 16:21:21 +00:00
Roman Lebedev
9c291f7450 [InstCombine] 'C-(C2-X) --> X+(C-C2)' constant-fold
It looks this fold was already partially happening, indirectly
via some other folds, but with one-use limitation.
No other fold here has that restriction.

https://rise4fun.com/Alive/ftR

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362217 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-31 09:47:16 +00:00
Roman Lebedev
08e5b97049 [InstCombine] 'add (sub C1, X), C2 --> sub (add C1, C2), X' constant-fold
https://rise4fun.com/Alive/qJQ

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362216 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-31 09:47:04 +00:00
Cameron McInally
99733f0406 [NFC][InstCombine] Add FIXME for one-use check on constant negation transforms.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361197 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-20 21:00:42 +00:00
Cameron McInally
b9f8673396 [InstCombine] Add visitFNeg(...) visitor for unary Fneg
Also, break out a helper function, namely foldFNegIntoConstant(...), which performs transforms common between visitFNeg(...) and visitFSub(...).

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361188 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-20 19:10:30 +00:00
Cameron McInally
7b1463b708 Add InstCombine::visitFNeg(...)
Differential Revision: https://reviews.llvm.org/D61784

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360461 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-10 20:01:04 +00:00
Robert Lougher
b81da4406f [InstCombine] Add new combine to add folding
(X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2)

I verified the correctness using Alive:
https://rise4fun.com/Alive/YNV

This transform enables the following transform that already exists in
instcombine:

(X | Y) ^ Y --> X & ~Y

As a result, the full expected transform is:

(X | C1) + C2 --> X & ~C1 iff (C1 == -C2)

There already exists the transform in the sub case:

(X | Y) - Y --> X & ~Y

However this does not trigger in the case where Y is constant due to an earlier
transform:

X - (-C) --> X + C

With this new add fold, both the add and sub constant cases are handled.

Patch by Chris Dawson.

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360185 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-07 19:36:41 +00:00
Sanjay Patel
30ccf8222e [InstCombine] prevent possible miscompile with negate+sdiv of vector op
// 0 - (X sdiv C)  -> (X sdiv -C)  provided the negation doesn't overflow.

This fold has been around for many years and nobody noticed the potential
vector miscompile from overflow until recently...
So it seems unlikely that there's much demand for a vector sdiv optimization
on arbitrary vector constants, so just limit the matching to splat constants
to avoid the possible bug.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358005 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-09 14:09:06 +00:00
Chen Zheng
ef1e756a76 [InstCombine] sdiv exact flag fixup.
Differential Revision: https://reviews.llvm.org/D60396


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357904 91177308-0d34-0410-b5e6-96231b3b80d8
2019-04-08 12:08:03 +00:00
Sanjay Patel
9551a63812 [InstCombine] form uaddsat from add+umin (PR14613)
This is the last step towards solving the examples shown in:
https://bugs.llvm.org/show_bug.cgi?id=14613

With this change, x86 should end up with psubus instructions
when those are available.

All known codegen issues with expanding the saturating intrinsics
were resolved with:
D59006 / rL356855

We also have some early evidence in D58872 that using the intrinsics
will lead to better perf. If some target regresses from this, custom
lowering of the intrinsics (as in the above for x86) may be needed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357012 91177308-0d34-0410-b5e6-96231b3b80d8
2019-03-26 17:50:08 +00:00
Sanjay Patel
26fe4b69c7 [InstCombine] fold adds of constants separated by sext/zext
This is part of a transform that may be done in the backend:
D13757
...but it should always be beneficial to fold this sooner in IR
for all targets.

https://rise4fun.com/Alive/vaiW

  Name: sext add nsw
  %add = add nsw i8 %i, C0
  %ext = sext i8 %add to i32
  %r = add i32 %ext, C1
  =>
  %s = sext i8 %i to i32
  %r = add i32 %s, sext(C0)+C1

  Name: zext add nuw
  %add = add nuw i8 %i, C0
  %ext = zext i8 %add to i16
  %r = add i16 %ext, C1
  =>
  %s = zext i8 %i to i16
  %r = add i16 %s, zext(C0)+C1

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355118 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-28 19:05:26 +00:00
Sanjay Patel
aaaa56c4e7 [InstCombine] canonicalize add/sub with bool
add A, sext(B) --> sub A, zext(B)

We have to choose 1 of these forms, so I'm opting for the
zext because that's easier for value tracking.

The backend should be prepared for this change after:
D57401
rL353433

This is also a preliminary step towards reducing the amount
of bit hackery that we do in IR to optimize icmp/select.
That should be waiting to happen at a later optimization stage.

The seeming regression in the fuzzer test was discussed in:
D58359

We were only managing that fold in instcombine by luck, and
other passes should be able to deal with that better anyway.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354748 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-24 16:57:45 +00:00
Chandler Carruth
6b547686c5 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351636 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-19 08:50:56 +00:00
Florian Hahn
4d62074ac2 [InstCombine] Don't undo 0 - (X * Y) canonicalization when combining subs.
Otherwise instcombine gets stuck in a cycle. The canonicalization was
added in D55961.

This patch fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12400

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351187 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-15 11:18:21 +00:00
Sanjay Patel
2aa873478d [InstCombine] name change: foldShuffledBinop -> foldVectorBinop; NFC
This function will deal with more than shuffles with D50992, and I 
have another potential per-element fold that could live here.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343692 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-03 15:20:58 +00:00
David Green
cf1b18658c [InstCombine] Fold ~A - Min/Max(~A, O) -> Max/Min(A, ~O) - A
This is an attempt to get out of a local-minimum that instcombine currently
gets stuck in. We essentially combine two optimisations at once, ~a - ~b = b-a
and min(~a, ~b) = ~max(a, b), only doing the transform if the result is at
least neutral. This involves using IsFreeToInvert, which has been expanded a
little to include selects that can be easily inverted.

This is trying to fix PR35875, using the ideas from Sanjay. It is a large
improvement to one of our rgb to cmy kernels.

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343569 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-02 09:48:34 +00:00
Craig Topper
becd18d5a8 [InstCombine] Support (sub (sext x), (sext y)) --> (sext (sub x, y)) and (sub (zext x), (zext y)) --> (zext (sub x, y))
Summary:
If the sub doesn't overflow in the original type we can move it above the sext/zext.

This is similar to what we do for add. The overflow checking for sub is currently weaker than add, so the test cases are constructed for what is supported.

Reviewers: spatel

Reviewed By: spatel

Subscribers: llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342335 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-15 18:54:10 +00:00
Sanjay Patel
fd837765bd [InstCombine] refactor mul narrowing folds; NFCI
Similar to rL342278:
The test diffs are all cosmetic due to the change in
value naming, but I'm including that to show that the
new code does perform these folds rather than something
else in instcombine.

D52075 should be able to use this code too rather than
duplicating all of the logic.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342292 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-14 22:23:35 +00:00
Sanjay Patel
d84a0a2c13 [InstCombine] add/use overflowing math helper functions; NFC
The mul case can already be refactored to use this similar to
rL342278.
The sub case is proposed in D52075.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342289 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-14 21:30:07 +00:00
Sanjay Patel
03a74f0299 [InstCombine] refactor add narrowing folds; NFCI
The test diffs are all cosmetic due to the change in
value naming, but I'm including that to show that the
new code does perform these folds rather than something
else in instcombine.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342278 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-14 20:40:46 +00:00
Craig Topper
9d207e5918 [InstCombine] Use dyn_cast instead of match(m_Constant). NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341962 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-11 16:51:26 +00:00
Craig Topper
8e2acb78ca [InstCombine] Extend (add (sext x), cst) --> (sext (add x, cst')) and (add (zext x), cst) --> (zext (add x, cst')) to work for vectors
Differential Revision: https://reviews.llvm.org/D51236

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340796 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-28 02:02:29 +00:00
Andrea Di Biagio
aec303a986 [InstCombine] Remove unused method FAddCombine::createFDiv(). NFC
This commit fixes a (gcc 7.3.0) [-Wunused-function] warning caused by the
presence of unused method FaddCombine::createFDiv().
The last use of that method was removed at r339519.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340014 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-17 11:33:48 +00:00
Sanjay Patel
fa0e915a8e [InstCombine] fix/enhance fadd/fsub factorization
(X * Z) + (Y * Z) --> (X + Y) * Z
  (X * Z) - (Y * Z) --> (X - Y) * Z
  (X / Z) + (Y / Z) --> (X + Y) / Z
  (X / Z) - (Y / Z) --> (X - Y) / Z

The existing code that implemented these folds failed to 
optimize vectors, and it transformed code with multiple 
uses when it should not have.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339519 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-12 15:48:26 +00:00
Sanjay Patel
ccbe637eb2 [InstCombine] allow fsub+fmul FMF folds for vectors
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339368 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-09 18:42:12 +00:00
Sanjay Patel
2998722fb0 [InstCombine] reduce code duplication; NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339349 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-09 15:07:13 +00:00
Sanjay Patel
6b0047a7da [InstCombine] fold fadd+fsub with common operand
This is a sibling to the simplify from:
https://reviews.llvm.org/rL339174


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339267 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-08 16:19:22 +00:00
Sanjay Patel
bd96310a2c [InstCombine] fold fsub+fsub with common operand
This is a sibling to the simplify from:
rL339171


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339266 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-08 16:04:48 +00:00
Sanjay Patel
752da31e95 [InstCombine] fold fneg into constant operand of fmul/fdiv
This accounts for the missing IR fold noted in D50195. We don't need any fast-math to enable the negation transform. 
FP negation can always be folded into an fmul/fdiv constant to eliminate the fneg.

I've limited this to one-use to ensure that we are eliminating an instruction rather than replacing fneg by a 
potentially expensive fdiv or fmul.

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339248 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-08 14:29:08 +00:00
Fangrui Song
af7b1832a0 Remove trailing space
sed -Ei 's/[[:space:]]+$//' include/**/*.{def,h,td} lib/**/*.{cpp,h}

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338293 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-30 19:41:25 +00:00
Sanjay Patel
19a2e2a495 [InstCombine] try to fold 'add+sub' to 'not+add'
These are reassociated versions of the same pattern and
similar transforms as in rL338200 and rL338118.

The motivation is identical to those commits:
Patterns with add/sub combos can be improved using
'not' ops. This is better for analysis and may lead
to follow-on transforms because 'xor' and 'add' are
commutative/associative. It can also help codegen.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338221 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-29 18:13:16 +00:00
Sanjay Patel
bd68890e8f [InstCombine] try to fold 'sub' to 'not'
https://rise4fun.com/Alive/jDd

Patterns with add/sub combos can be improved using
'not' ops. This is better for analysis and may lead
to follow-on transforms because 'xor' and 'add' are 
commutative/associative. It can also help codegen.  


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338200 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-28 16:48:44 +00:00
Sanjay Patel
8a35df349b [InstCombine] return when SimplifyAssociativeOrCommutative makes a change
This bug was created by rL335258 because we used to always call instsimplify
after trying the associative folds. After that change it became possible
for subsequent folds to encounter unsimplified code (and potentially assert
because of it). 

Instead of carrying changed state through instcombine, we can just return 
immediately. This allows instsimplify to run, so we can continue assuming
that easy folds have already occurred.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336965 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-13 01:18:07 +00:00
Gil Rapaport
d7d68723b8 [InstCombine] (A + 1) + (B ^ -1) --> A - B
Turn canonicalized subtraction back into (-1 - B) and combine it with (A + 1) into (A - B).
This is similar to the folding already done for (B ^ -1) + Const into (-1 + Const) - B.

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335579 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-26 05:31:18 +00:00
Sanjay Patel
1a4304a132 [InstCombine] simplify binops before trying other folds
This is outwardly NFC from what I can tell, but it should be more efficient 
to simplify first (despite the name, SimplifyAssociativeOrCommutative does
not actually simplify as InstSimplify does - it creates/morphs instructions).

This should make it easier to refactor duplicated code that runs for all binops.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335258 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-21 17:06:36 +00:00
Sanjay Patel
6a08b7888b [InstCombine] fold another shifty abs pattern to cmp+sel (PR36036)
The bug report:
https://bugs.llvm.org/show_bug.cgi?id=36036

...requests a DAG change for this, but an IR canonicalization
probably handles most cases. If we still want to match this
pattern in the backend, there's a proposal for that too:
D47831

Alive proofs including nsw/nuw cases that were first noted in:
D46988

https://rise4fun.com/Alive/Kmp

This patch is largely copied from the existing code that was
initially added with:
D40984
...but I didn't see much gain from trying to share code.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334137 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-06 21:58:12 +00:00
Roman Lebedev
85b7bc9e52 [InstCombine] PR37603: low bit mask canonicalization
Summary:
This is [[ https://bugs.llvm.org/show_bug.cgi?id=37603 | PR37603 ]].

https://godbolt.org/g/VCMNpS
https://rise4fun.com/Alive/idM

When doing bit manipulations, it is quite common to calculate some bit mask,
and apply it to some value via `and`.

The typical C code looks like:
```
int mask_signed_add(int nbits) {
    return (1 << nbits) - 1;
}
```
which is translated into (with `-O3`)
```
define dso_local i32 @mask_signed_add(int)(i32) local_unnamed_addr #0 {
  %2 = shl i32 1, %0
  %3 = add nsw i32 %2, -1
  ret i32 %3
}
```

But there is a second, less readable variant:
```
int mask_signed_xor(int nbits) {
    return ~(-(1 << nbits));
}
```
which is translated into (with `-O3`)
```
define dso_local i32 @mask_signed_xor(int)(i32) local_unnamed_addr #0 {
  %2 = shl i32 -1, %0
  %3 = xor i32 %2, -1
  ret i32 %3
}
```

Since we created such a mask, it is quite likely that we will use it in `and` next.
And then we may get rid of `not` op by folding into `andn`.

But now that i have actually looked:
https://godbolt.org/g/VTUDmU
_some_ backend changes will be needed too.
We clearly loose `bzhi` recognition.

Reviewers: spatel, craig.topper, RKSimon

Reviewed By: spatel

Subscribers: llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334127 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-06 19:38:27 +00:00
Sanjay Patel
9a5dadc5b1 [InstCombine] improve sub with bool folds
There's a patchwork of existing transforms trying to handle
these cases, but as seen in the changed test, we weren't
catching them all.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333845 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-03 16:35:26 +00:00