76 Commits

Author SHA1 Message Date
Sanjay Patel
7ec604a317 [InstCombine] try harder to cancel out mul/div
((Op1 * X) / Y) / Op1 --> X / Y
https://alive2.llvm.org/ce/z/JYxWjA

InstSimplify handles the more basic mul+div pattern with
shared operand, but we don't seem to have any reassociation
folds to handle cases where the common op is further away.

This is a generalization of 9cff4711ac72 and another
transform derived from issue #58137.
2022-10-11 09:51:51 -04:00
Sanjay Patel
5185c5db0e [InstCombine] add tests for div with common mul operand; NFC 2022-10-11 09:51:51 -04:00
Bjorn Pettersson
4ab40eca08 [test][InstCombine] Update some test cases to use opaque pointers
These tests cases were converted using the script at
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34

Differential Revision: https://reviews.llvm.org/D135094
2022-10-03 22:17:59 +02:00
Nuno Lopes
952e069393 [NFC] remove 'br undef' from InstCombine test cases
This is UB and allows the compiler to give any result, so these tests weren't meaningful
InstCombine tests are now clean of 'br undef'
2022-06-10 15:28:57 +01:00
Sanjay Patel
99ef341ce9 [InstCombine] freeze operand in sdiv expansion
As discussed in issue #37809, this transform is not safe
if the input is an undefined value.

This is similar to a recent change for urem:
d428f09b2c9d

There is no difference in codegen on the basic examples,
but this could lead to regressions. We may need to
improve freeze analysis or lowering if that happens.

Presumably, in real cases that are similar to the tests
where a subsequent transform removes the select, we
will also be able to remove the freeze by seeing that
the parameter has 'noundef'.
2022-05-11 14:01:28 -04:00
Sanjay Patel
5fdfcf4892 [InstCombine] update auto-generated CHECK lines in test file; NFC
These are all cosmetic (value naming) diffs that would distract from
real changes in this file.
2022-05-11 14:01:28 -04:00
Chenbing Zheng
467cbb6249 [InstCombine] fold more constant divisor to select-of-constants divisor
By adding a parameter to function FoldOpIntoSelect, we can fold more Ops to Select.
For this example, we tend to fold the division instruction,
so we no longer care whether SelectInst is one use.

This patch slove TODO left in InstCombine/div.ll.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D122967
2022-04-08 10:19:24 +08:00
Bjorn Pettersson
acdc419c89 [test] Use -passes=instcombine instead of -instcombine in lots of tests. NFC
Another step moving away from the deprecated syntax of specifying
pass pipeline in opt.

Differential Revision: https://reviews.llvm.org/D119081
2022-02-07 14:26:59 +01:00
Simon Pilgrim
4f97aa7e1d [InstCombine] Add PR34063 test coverage 2022-02-05 15:22:13 +00:00
Sanjay Patel
a7ed21aa1e [InstCombine] try to fold div with constant dividend and select-of-constants divisor
We avoid this fold in the more general cases where we use FoldOpIntoSelect.
That's because -- unlike most binary opcodes -- 'div' can't usually be
speculated with a variable divisor since it can have immediate UB. But in
the case where both arms of the select are constants, we can safely evaluate
both sides and eliminate 'div' completely.

This is a follow-up to the equivalent fold for 'rem' opcodes:
D115173 / f65be726ab50
2021-12-08 10:27:50 -05:00
Sanjay Patel
51d3cb0ab1 [InstCombine] add tests for div/rem with 0 select arm; NFC
More coverage for D115173 and its div sibling. These are
existing transforms handled by simplifyDivRemOfSelectWithZeroOp().
2021-12-07 15:30:06 -05:00
Sanjay Patel
cfde8a6c9d [InstCombine] add tests for div with select-of-constants divisor; NFC
Similar patterns as tests for:
D115173
(and we might want to make a single patch for all of these).
2021-12-07 15:30:06 -05:00
David Sherwood
8439415333 [IR] Let ConstantVector::getSplat use poison instead of undef
This patch updates ConstantVector::getSplat to use poison instead
of undef when using insertelement/shufflevector to splat.

This follows on from D93793.

Differential Revision: https://reviews.llvm.org/D107751
2021-08-10 08:27:43 +01:00
Fraser Cormack
fd3b556958 [Constants] Extend support for scalable-vector splats
This patch extends the various "isXXX" functions of the `Constant` class
to include scalable-vector splats.

In several "isXXX" functions, code that was separately inspecting
`ConstantVector` and `ConstantDataVector` was unified to use
`getSplatValue`, which already includes support for said splats.

In the varous "isNotXXX" functions, code was added to check whether the
scalar splat value -- if any -- satisfies the predicate.

An extra fix for `isNotMinSignedValue` was included, as it previously
crashed when passed a scalable-vector type because it unconditionally
cast to `FixedVectorType`

These changes address numerous missed optimizations, a compiler crash
mentioned above and -- perhaps most egregiously -- an infinite loop in
InstCombine due to the compiler breaking canonical form when it failed
to pick up on a splat in a select instruction.

Test cases have been added to cover as many of these functions as
possible, though existing coverage is slim; it doesn't appear that there
are any in-tree uses of `Constant::isNegativeZeroValue`, for example.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D103421
2021-06-07 14:37:56 +01:00
Nikita Popov
766cf7f32e [InstSimplify] Fold division by zero to poison
Div/rem by zero is immediate undefined behavior and anything goes.
Currently we fold it to undef, this patch changes it to fold to
poison instead, which is slightly stronger.

Differential Revision: https://reviews.llvm.org/D93995
2021-01-03 20:52:45 +01:00
Nikita Popov
8058196677 [InstCombine] Process newly inserted instructions in the correct order
InstCombine operates on the basic premise that the operands of the
currently processed instruction have already been simplified. It
achieves this by pushing instructions to the worklist in reverse
program order, so that instructions are popped off in program order.
The worklist management in the main combining loop also makes sure
to uphold this invariant.

However, the same is not true for all the code that is performing
manual worklist management. The largest problem (addressed in this
patch) are instructions inserted by InstCombine's IRBuilder. These
will be pushed onto the worklist in order of insertion (generally
matching program order), which means that a) the users of the
original instruction will be visited first, as they are pushed later
in the main loop and b) the newly inserted instructions will be
visited in reverse program order.

This causes a number of problems: First, folds operate on instructions
that have not had their operands simplified, which may result in
optimizations being missed (ran into this in
https://reviews.llvm.org/D72048#1800424, which was the original
motivation for this patch). Additionally, this increases the amount
of folds InstCombine has to perform, both within one iteration, and
by increasing the number of total iterations.

This patch addresses the issue by adding a Worklist.AddDeferred()
method, which is used for instructions inserted by IRBuilder. These
will only be added to the real worklist after the combine finished,
and in reverse order, so they will end up processed in program order.
I should note that the same should also be done to nearly all other
uses of Worklist.Add(), but I'm starting with just this occurrence,
which has by far the largest test fallout.

Most of the test changes are due to
https://bugs.llvm.org/show_bug.cgi?id=44521 or other cases where
we don't canonicalize something. These are neutral. One regression
has been addressed in D73575 and D73647. The remaining regression
in an shl+sdiv fold can't really be fixed without dropping another
transform, but does not seem particularly problematic in the first
place.

Differential Revision: https://reviews.llvm.org/D73411
2020-01-30 09:40:10 +01:00
Roman Lebedev
09311459e3
[InstCombine] Extend 0 - (X sdiv C) -> (X sdiv -C) fold to non-splat vectors
Split off from https://reviews.llvm.org/D68408
2019-12-05 15:48:29 +03:00
Eric Christopher
cee313d288 Revert "Temporarily Revert "Add basic loop fusion pass.""
The reversion apparently deleted the test/Transforms directory.

Will be re-reverting again.

llvm-svn: 358552
2019-04-17 04:52:47 +00:00
Eric Christopher
a863435128 Temporarily Revert "Add basic loop fusion pass."
As it's causing some bot failures (and per request from kbarton).

This reverts commit r358543/ab70da07286e618016e78247e4a24fcb84077fda.

llvm-svn: 358546
2019-04-17 02:12:23 +00:00
Chen Zheng
5e13ff1da2 [InstCombine] Canonicalize (-X s/ Y) to -(X s/ Y).
Differential Revision: https://reviews.llvm.org/D60395

llvm-svn: 358050
2019-04-10 06:52:09 +00:00
Sanjay Patel
49d9d17a77 [InstCombine] prevent possible miscompile with sdiv+negate of vector op
Similar to:
rL358005

Forego folding arbitrary vector constants to fix a possible miscompile bug.
We can enhance the transform if we do want to handle the more complicated
vector case.

llvm-svn: 358013
2019-04-09 15:13:03 +00:00
Sanjay Patel
d5173f5acf [InstCombine] add tests for sdiv with negated dividend and constant divisor; NFC
llvm-svn: 358010
2019-04-09 14:48:44 +00:00
Sanjay Patel
7563b65ad4 [InstCombine] add tests for sdiv-by-int-min; NFC
llvm-svn: 358008
2019-04-09 14:27:07 +00:00
Sanjay Patel
f62dcea7ed [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

llvm-svn: 358005
2019-04-09 14:09:06 +00:00
Sanjay Patel
a230bb5fc0 [InstCombine] add tests/comments for negate+sdiv; NFC
llvm-svn: 358003
2019-04-09 13:41:29 +00:00
Sanjay Patel
74ccef1f4f [InstCombine] add tests for negate+sdiv; NFC
PR41425:
https://bugs.llvm.org/show_bug.cgi?id=41425

llvm-svn: 357953
2019-04-08 22:55:10 +00:00
Chen Zheng
923c7c9daa [InstCombine] sdiv exact flag fixup.
Differential Revision: https://reviews.llvm.org/D60396

llvm-svn: 357904
2019-04-08 12:08:03 +00:00
Chen Zheng
edf91ed855 [InstCombine] add more testcases for sdiv exact flag fixup.
llvm-svn: 357894
2019-04-08 09:19:42 +00:00
Chen Zheng
d3b1d74624 [InstCombine] add testcases for sdiv exact flag fixing - NFC.
llvm-svn: 357884
2019-04-08 05:49:15 +00:00
Sanjay Patel
6d6eab66e0 [InstCombine] fold udiv with common factor from muls with nuw
Unfortunately, sdiv isn't as simple because of UB due to overflow.

This fold is mentioned in PR38239:
https://bugs.llvm.org/show_bug.cgi?id=38239

llvm-svn: 338059
2018-07-26 19:22:41 +00:00
Sanjay Patel
b381e7e59a [InstCombine] add tests for udiv with common factor; NFC
This fold is mentioned in PR38239:
https://bugs.llvm.org/show_bug.cgi?id=38239

The general case probably belongs in -reassociate, but given that we do 
basic reassociation optimizations similar to this in instcombine already, 
we might as well be consistent within instcombine and handle this pattern?

llvm-svn: 338038
2018-07-26 16:14:53 +00:00
Sanjay Patel
7c45debaea [InstCombine] fold udiv with sext bool divisor
Note: I didn't add a hasOneUse() check because the existing,
related fold doesn't have that check. I suspect that the
improved analysis and codegen make these some of the rare
canonicalization cases where we allow an increase in
instructions.

llvm-svn: 335597
2018-06-26 12:41:15 +00:00
Sanjay Patel
0c90400bf2 [InstCombine] add/move tests for udiv; NFC
llvm-svn: 335544
2018-06-25 22:27:36 +00:00
Sanjay Patel
6a96d90acd [InstCombine] fold sdiv with sext bool divisor
llvm-svn: 335527
2018-06-25 21:39:41 +00:00
Sanjay Patel
46f9b8c333 [InstCombine] add tests for sdiv with sext bool divisor; NFC
llvm-svn: 335526
2018-06-25 21:36:09 +00:00
Sanjay Patel
d0b27a1156 [InstSimplify] move/add/regenerate checks for tests; NFC
llvm-svn: 330515
2018-04-21 16:23:47 +00:00
Sanjay Patel
510d647a4d [InstCombine] X / (X * Y) -> 1 / Y if the multiplication does not overflow
The related cases for (X * Y) / X were handled in rL124487.

https://rise4fun.com/Alive/6k9

The division in these tests is subsequently eliminated by existing instcombines
for 1/X.

llvm-svn: 324843
2018-02-11 17:20:32 +00:00
Sanjay Patel
aee107f30d [InstCombine] add tests for div-mul folds; NFC
The related cases for (X * Y) / X were handled in rL124487.

llvm-svn: 324840
2018-02-11 16:52:44 +00:00
Craig Topper
17b0c78447 [InstCombine] Fix a vector splat handling bug in transformZExtICmp.
We were using an i1 type and then zero extending to a vector. Instead just create the 0/1 directly as a ConstantInt with the correct type. No need to ask ConstantExpr to zero extend for us.

This bug is a bit tricky to hit because it requires us to visit a zext of an icmp that would normally be simplified to true/false, but that icmp hasnt' been visited yet. In the test case this zext and icmp were created by visiting a udiv and due to worklist ordering we got to the zext first.

Fixes PR34841.

llvm-svn: 314971
2017-10-05 07:59:11 +00:00
Sanjay Patel
0d4fd5b668 [InstSimplify] fold sdiv/srem based on compare of dividend and divisor
This should bring signed div/rem analysis up to the same level as unsigned. 
We use icmp simplification to determine when the divisor is known greater than the dividend.

Each positive test is followed by a negative test to show that we're not overstepping the boundaries of the known bits.
There are extra tests for the signed-min-value special cases.

Alive proofs:
http://rise4fun.com/Alive/WI5

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

llvm-svn: 313264
2017-09-14 14:59:07 +00:00
Craig Topper
218a359fbd [InstCombine] Simplify 1/X for vectors.
llvm-svn: 300439
2017-04-17 03:41:47 +00:00
Craig Topper
eee53c030a [InstCombine] Add test cases for missing support for simplifying 1/X for vectors. NFC
llvm-svn: 300438
2017-04-17 03:41:44 +00:00
Craig Topper
f248468359 [InstCombine] Add support for turning vector sdiv into udiv.
llvm-svn: 300435
2017-04-17 01:51:19 +00:00
Craig Topper
43b012b1b3 [InstCombine] Add test cases for missing support for turning vector sdiv into udiv. NFC
llvm-svn: 300434
2017-04-17 01:51:16 +00:00
Sanjay Patel
541aef4661 [InstCombine] allow icmp (div X, Y), C folds for splat constant vectors
Converting all of the overflow ops to APInt looked risky, so I've left that as a TODO.

llvm-svn: 280299
2016-08-31 21:57:21 +00:00
Sanjay Patel
b860859611 [InstCombine] add tests for missing vector icmp folds
llvm-svn: 278717
2016-08-15 19:16:33 +00:00
Sanjay Patel
59ed2ffca3 [InstCombine] shrink type of sdiv if dividend is sexted and constant divisor is small enough (PR28153)
This should fix PR28153:
https://llvm.org/bugs/show_bug.cgi?id=28153

Differential Revision: http://reviews.llvm.org/D21769

llvm-svn: 273951
2016-06-27 22:27:11 +00:00
Sanjay Patel
5cdf699daa add tests for PR28153
llvm-svn: 273936
2016-06-27 20:28:59 +00:00
Sanjay Patel
e2e89ef936 [ValueTracking, InstCombine] extend isKnownToBeAPowerOfTwo() to handle vector splat constants
We could try harder to handle non-splat vector constants too, 
but that seems much rarer to me.

Note that the div test isn't resolved because there's a check
for isIntegerTy() guarding that transform.

Differential Revision: http://reviews.llvm.org/D20497

llvm-svn: 270369
2016-05-22 15:41:53 +00:00
Sanjay Patel
ec4d91a4d7 add test vector sdiv
llvm-svn: 270285
2016-05-20 22:08:40 +00:00