Commit Graph

358 Commits

Author SHA1 Message Date
Florian Hahn 30932a3c16 [InstSimplify] More fcmp cases when comparing against negative constants.
Summary:
For known positive non-zero value X:
    fcmp uge X, -C => true
    fcmp ugt X, -C => true
    fcmp une X, -C => true
    fcmp oeq X, -C => false
    fcmp ole X, -C => false
    fcmp olt X, -C => false


Patch by Paul Walker.

Reviewers: majnemer, t.p.northover, spatel, RKSimon

Reviewed By: spatel

Subscribers: fhahn, llvm-commits

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

llvm-svn: 319538
2017-12-01 12:34:16 +00:00
Sanjay Patel 178b70a3de [InstSimplify] add fcmp with negative constant tests; NFC
This is a superset of the tests proposed with D40012 to show another potential improvement.

llvm-svn: 319041
2017-11-27 16:08:34 +00:00
Sanjay Patel eb731b09f3 [InstSimplify] fold and/or of fcmp ord/uno when operand is known nnan
The 'ord' and 'uno' predicates have a logic operation for NAN built into their definitions:

FCMP_ORD   =  7,  ///< 0 1 1 1    True if ordered (no nans)
FCMP_UNO   =  8,  ///< 1 0 0 0    True if unordered: isnan(X) | isnan(Y)

So we can simplify patterns like this:

(fcmp ord (known NNAN), X) && (fcmp ord X, Y) --> fcmp ord X, Y
(fcmp uno (known NNAN), X) || (fcmp uno X, Y) --> fcmp uno X, Y

It might be better to split this into (X uno 0) | (Y uno 0) as a canonicalization, but that
would be another patch.

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

llvm-svn: 318627
2017-11-19 15:34:27 +00:00
Sanjay Patel b6f107d759 [InstSimplify] add tests for fcmp ord/uno; NFC
llvm-svn: 318408
2017-11-16 15:25:59 +00:00
Sanjay Patel e272be7c9a [ValueTracking] return zero when there's conflict in known bits of a shift (PR34838)
Poison allows us to return a better result than undef.

llvm-svn: 315595
2017-10-12 17:31:46 +00:00
Sanjay Patel 865e6c852b [InstSimplify] add tests to show we can do better at folding poison; NFC
llvm-svn: 315152
2017-10-07 15:39:06 +00:00
Haicheng Wu 25f6c196d7 [InstSimplify] teach SimplifySelectInst() to fold more vector selects
Call ConstantFoldSelectInstruction() to fold cases like below

select <2 x i1><i1 true, i1 false>, <2 x i8> <i8 0, i8 1>, <2 x i8> <i8 2, i8 3>

All operands are constants and the condition has mixed true and false conditions.

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

llvm-svn: 314741
2017-10-02 23:43:52 +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
Sanjay Patel dc3002de9d [InstSimplify] regenerate checks; NFC
llvm-svn: 313161
2017-09-13 17:39:39 +00:00
Sanjay Patel bb1b1c97fa [InstSimplify] fix some test names; NFC
Too much division...the quotient is the answer.

llvm-svn: 312943
2017-09-11 20:38:31 +00:00
Sanjay Patel a36eb77118 [InstSimplify] add tests for possible sdiv/srem simplifications; NFC
As noted in PR34517, the handling of signed div/rem is not on par with
unsigned div/rem. Signed is harder to reason about, but it should be
possible to handle at least some of these using the same technique that
we use for unsigned: use icmp logic to see if there's a relationship
between the quotient and divisor.

llvm-svn: 312938
2017-09-11 19:42:41 +00:00
Sanjay Patel 5876189ff1 [InstSimplify] refactor udiv/urem code and add tests; NFCI
This removes some duplicated code and makes it easier to support signed div/rem
in a similar way if we want to do that. Note that the existing comments were not
accurate - we don't need a constant divisor to simplify; icmp simplification does
more than that. But as the added tests show, it could go even further.

llvm-svn: 312885
2017-09-10 17:55:08 +00:00
Matt Arsenault 3ced3d90c3 InstSimplify: canonicalize is idempotent
llvm-svn: 312685
2017-09-07 01:21:43 +00:00
Sanjay Patel 69ac66cf8b [InstSimplify] regenerate checks; NFC
llvm-svn: 312413
2017-09-02 14:38:15 +00:00
Sanjay Patel 16019c5a68 [InstSimplify] move fcmp simplification tests from InstCombine
These are all tests that result in a constant, so moving the tests over to where they are actually handled.

llvm-svn: 312411
2017-09-02 14:27:00 +00:00
Sanjay Patel 6f7ac7e402 [InstCombine] remove unnecessary vector select fold; NFCI
This code is double-dead:
1. We simplify all selects with constant true/false condition in InstSimplify.
   I've minimized/moved the tests to show that works as expected.
2. All remaining vector selects with a constant condition are canonicalized to
   shufflevector, so we really can't see this pattern.

llvm-svn: 312123
2017-08-30 14:04:57 +00:00
Craig Topper b1e4b1a070 [InstSimplify] Teach decomposeBitTestICmp to handle non-canonical compares
This adds support non-canonical compare predicates. InstSimplify can't rely on canonicalization to have occurred.

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

llvm-svn: 310893
2017-08-14 22:11:43 +00:00
Craig Topper 0aa3a19512 Recommit r310869, "[InstSimplify][InstCombine] Modify the interface of decomposeBitTestICmp and use it in the InstSimplify"
This recommits r310869, with the moved files and no extra changes.

Original commit message:

This addresses a fixme in InstSimplify about using decomposeBitTest. This also fixes InstSimplify to handle ugt and ult compares too.

I've modified the interface a little to return only the APInt version of the mask that InstSimplify needs. InstCombine now has a small wrapper routine to create a Constant out of it. I've also dropped the returning of 0 since InstSimplify doesn't need that. So InstCombine creates a zero constant itself.

I also had to make decomposeBitTest support vectors since InstSimplify needs that.

As InstSimplify can't use something from the Transforms library, I've moved the CmpInstAnalysis code to the Analysis library.

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

llvm-svn: 310889
2017-08-14 21:39:51 +00:00
Craig Topper 69fa8e0d99 Revert r310869 "[InstSimplify][InstCombine] Modify the interface of decomposeBitTestICmp and use it in the InstSimplify"
Failed to add the two files that moved. And then added an extra change I didn't mean to while trying to fix that. Reverting everything.

llvm-svn: 310873
2017-08-14 19:09:32 +00:00
Craig Topper 2f0b450666 [InstSimplify][InstCombine] Modify the interface of decomposeBitTestICmp and use it in the InstSimplify
This addresses a fixme in InstSimplify about using decomposeBitTest. This also fixes InstSimplify to handle ugt and ult compares too.

I've modified the interface a little to return only the APInt version of the mask that InstSimplify needs. InstCombine now has a small wrapper routine to create a Constant out of it. I've also dropped the returning of 0 since InstSimplify doesn't need that. So InstCombine creates a zero constant itself.

I also had to make decomposeBitTest support vectors since InstSimplify needs that.

As InstSimplify can't use something from the Transforms library, I've moved the CmpInstAnalysis code to the Analysis library.

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

llvm-svn: 310869
2017-08-14 18:49:42 +00:00
Craig Topper 58def1e1f2 [InstSimplify] Add some tests cases for selects with bittests hidden in ugt/ult/uge/ule compares. NFC
llvm-svn: 310868
2017-08-14 18:49:39 +00:00
Craig Topper ba69187988 [InstSimplify] Add test cases that show that simplifySelectWithICmpCond doesn't work with non-canonical comparisons.
llvm-svn: 310542
2017-08-10 01:02:02 +00:00
Davide Italiano 1a26f24f35 [ConstantFolder] Don't try to fold gep when the idx is a vector.
The code in ConstantFoldGetElementPtr() assumes integers, and
therefore it crashes trying to get the integer bidwith of a vector
type (in this case <4 x i32>. I just changed the code to prevent
the folding in case of vectors and I didn't bother to generalize
as this doesn't seem to me something that really happens in
practice, but I'm willing to change the patch if you think
it's worth it.
This is hard to trigger from -instsimplify or -instcombine
only as the second instruction is dead, so the test uses loop-unroll.

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

llvm-svn: 309330
2017-07-27 22:20:44 +00:00
Joey Gouly 61eaa63b65 [InstSimplify] Constant fold the new GEP in SimplifyGEPInst.
llvm-svn: 304784
2017-06-06 10:17:14 +00:00
Craig Topper fe9ad82e44 [ConstantFolding] Properly support constant folding of vector powi intrinsic. The second argument is not a vector so needs special treatment.
llvm-svn: 304679
2017-06-04 07:30:28 +00:00
Craig Topper 97f113e795 [InstSimplify] Add test case demonstrating that we fail to constant fold vector llvm.powi intrinsics due to the second argument not being a vector.
llvm-svn: 304678
2017-06-04 07:30:23 +00:00
Craig Topper 7c553edced [ConstantFolding] Fix constant folding for vector cttz and ctlz intrinsics to understand that the second argument is still a scalar.
llvm-svn: 304668
2017-06-03 18:50:29 +00:00
Craig Topper 36fa2f0dee [InstCombine][InstSimplify] Add various tests for ctlz/cttz with vectors, some showing missed optimizations. NFC
llvm-svn: 304667
2017-06-03 18:50:26 +00:00
Craig Topper b23e7c78a5 [InstSimplify][ConstantFolding] Teach constant folding how to handle icmp null, (inttoptr x) as well as it handles icmp (inttoptr x), null
Summary:
The constant folding code currently assumes that the constant expression will always be on the left and the simple null will be on the right. But that's not true at least on the path from InstSimplify.

This patch adds support to ConstantFolding to detect the reversed case.

Reviewers: spatel, dberlin, majnemer, davide, joey

Reviewed By: joey

Subscribers: joey, llvm-commits

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

llvm-svn: 304559
2017-06-02 16:17:32 +00:00
Craig Topper 5ea2d55e1c [InstSimplify][ConstantFolding] Add test demonstrating failure to simplify (icmp eq null, inttoptr x) when the null is on the left hand side. NFC
llvm-svn: 304474
2017-06-01 21:20:07 +00:00
Craig Topper 1da22c3244 [InstSimplify] Use m_APInt instead of m_ConstantInt in ((V + N) & C1) | (V & C2) handling in order to support splat vectors.
The tests here are have operands commuted to provide more coverage. I also commuted one of the instructions in the scalar tests so the 4 tests cover the 4 commuted variations

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

llvm-svn: 304021
2017-05-26 19:03:53 +00:00
Craig Topper 77e07cc010 [InstSimplify] Simplify uadd/sadd/umul/smul with overflow intrinsics when the Zero or Undef is on the LHS.
Summary: This code was migrated from InstCombine a few years ago. InstCombine had nearby code that would move Constants to the RHS for these, but InstSimplify doesn't have such code on this path.

Reviewers: spatel, majnemer, davide

Reviewed By: spatel

Subscribers: llvm-commits

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

llvm-svn: 303774
2017-05-24 17:05:28 +00:00
Craig Topper ae292aaad1 [InstSimplify] Add more tests for undef inputs and multiplying by 0 for the add/sub/mul with overflow intrinsics. NFC
llvm-svn: 303671
2017-05-23 18:42:58 +00:00
Craig Topper 15288da293 [InstSimplify] auto-generate test checks. NFC
llvm-svn: 303664
2017-05-23 17:57:36 +00:00
Craig Topper df01feb40e [InstSimplify] Make m_Not work for xor -1, X
Currently m_Not only works the canonical xor X, -1 form that InstCombine produces. InstSimplify can't rely on this canonicalization.

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

llvm-svn: 303379
2017-05-18 20:27:32 +00:00
Craig Topper 93898495b9 [InstSimplify] Add test cases for missing fold (A & B) | ~(A ^ B) -> ~(A ^ B).
llvm-svn: 303367
2017-05-18 18:14:40 +00:00
Sanjay Patel e2787b9a35 [InstSimplify] handle all icmp i1 X, C in one place; NFCI
We already handled all of the new tests identically, but several
of those went through a lot of unnecessary processing before
getting folded.

Another motivation for grouping these cases together is that
InstCombine needs a similar fold. Currently, it handles the
'not' cases inefficiently which can lead to bugs as described
in the post-commit comments of:
https://reviews.llvm.org/D32143 

llvm-svn: 303295
2017-05-17 20:27:55 +00:00
Sanjay Patel 877364ff99 [InstSimplify] add folds for constant mask of value shifted by constant
We would eventually catch these via demanded bits and computing known bits in InstCombine,
but I think it's better to handle the simple cases as soon as possible as a matter of efficiency.

This fold allows further simplifications based on distributed ops transforms. eg:
  %a = lshr i8 %x, 7
  %b = or i8 %a, 2
  %c = and i8 %b, 1

InstSimplify can directly fold this now:
  %a = lshr i8 %x, 7

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

llvm-svn: 303213
2017-05-16 21:51:04 +00:00
Sanjay Patel 9edfbc4409 [InstSimplify] add tests for unnecessary mask of shifted values; NFC
llvm-svn: 303127
2017-05-15 22:54:37 +00:00
Sanjay Patel a23b141cd2 [InstSimplify] restrict icmp fold with 2 sdiv exact operands (PR32949)
These folds were introduced with https://reviews.llvm.org/rL127064 as part of solving:
https://bugs.llvm.org/show_bug.cgi?id=9343

As shown here:
http://rise4fun.com/Alive/C8
...however, the sdiv exact case needs a stronger predicate.

I opted for duplicated code instead of adding another fallthrough because I think that's 
easier to read (and edit in case we need/want to restrict/loosen the predicates any more).

This should fix:
https://bugs.llvm.org/show_bug.cgi?id=32949
https://bugs.llvm.org/show_bug.cgi?id=32948

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

llvm-svn: 303104
2017-05-15 19:16:49 +00:00
Craig Topper 479daaf74c [InstSimplify] Add patterns for folding (A & B) | (~A ^ B) -> (~A ^ B) and its commuted variants.
We already had (A & ~B) | (A ^ B), but we missed the cases where the not was part of the xor.

llvm-svn: 303004
2017-05-14 07:54:43 +00:00
Craig Topper 982cc3b1d5 foo
llvm-svn: 303003
2017-05-14 07:54:40 +00:00
Sanjay Patel 0b24b7ef72 [InstSimplify, InstCombine] move 'or' simplification tests; NFC
Surprisingly, I don't think these are redundant for InstSimplify. 
They were just misplaced as InstCombine tests.

llvm-svn: 302684
2017-05-10 15:57:47 +00:00
Sanjay Patel 390f1dc6ba [InstSimplify] add tests for PR32949 miscompile; NFC
llvm-svn: 302374
2017-05-07 18:19:13 +00:00
Zvi Rackover 973ff7c74c InstructionSimplify: Relanding r301766
Summary:
Re-applying r301766 with a fix to a typo and a regression test.

The log message for r301766 was:
==================================================================================
    InstructionSimplify: Canonicalize shuffle operands. NFC-ish.

    Summary:
     Apply canonicalization rules:
        1. Input vectors with no elements selected from can be replaced with undef.
        2. If only one input vector is constant it shall be the second one.

    This allows constant-folding to cover more ad-hoc simplifications that
    were in place and avoid duplication for RHS and LHS checks.

    There are more rules we may want to add in the future when we see a
    justification. e.g. mask elements that select undef elements can be
    replaced with undef.
==================================================================================

Reviewers: spatel, RKSimon

Reviewed By: spatel

Subscribers: llvm-commits

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

llvm-svn: 302373
2017-05-07 18:16:37 +00:00
Sanjay Patel 599e65b1ff [InstSimplify] use ConstantRange to simplify or-of-icmps
We can simplify (or (icmp X, C1), (icmp X, C2)) to 'true' or one of the icmps in many cases.
I had to check some of these with Alive to prove to myself it's right, but everything seems 
to check out. Eg, the deleted code in instcombine was completely ignoring predicates with
mismatched signedness.

This is a follow-up to:
https://reviews.llvm.org/rL301260
https://reviews.llvm.org/D32143

llvm-svn: 302370
2017-05-07 15:11:40 +00:00
Sanjay Patel 3bf1d6b763 [InstSimplify] fix copy-paste mistake in test comments; NFC
llvm-svn: 302251
2017-05-05 16:24:58 +00:00
Sanjay Patel 34cd5e4307 [InstSimplify] add tests for (icmp X, C1 | icmp X, C2); NFC
These are the 'or' counterparts for the tests added with r300493.

llvm-svn: 302248
2017-05-05 16:12:05 +00:00
Sanjay Patel e42b4d566e [InstSimplify] add folds for or-of-casted-icmps
The sibling folds for 'and' with casts were added with https://reviews.llvm.org/rL273200.
This is a preliminary step for adding the 'or' variants for the folds added with https://reviews.llvm.org/rL301260.

The reason for the strange form with constant LHS in the 1st test is because there's another missing fold in that
case for the inverted predicate. That should be fixed when we add the ConstantRange functionality for 'or-of-icmps' 
that already exists for 'and-of-icmps'.

I'm hoping to share more code for the and/or cases, so we won't have these differences. This will allow us to remove
code from InstCombine. It's also possible that we can remove some code here in InstSimplify. I think we have some 
duplicated folds because patterns are not matched in a general way.

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

llvm-svn: 302189
2017-05-04 19:51:34 +00:00
Sanjay Patel 500e5122d3 [InstSimplify] add tests for or-of-casted-icmps; NFC
llvm-svn: 302174
2017-05-04 17:36:53 +00:00