406 Commits

Author SHA1 Message Date
Roman Lebedev
ebc98fa7a0 [InstCombine] foldUnsignedUnderflowCheck(): handle last few cases (PR43251)
Summary:
I don't have a direct motivational case for this,
but it would be good to have this for completeness/symmetry.

This pattern is basically the motivational pattern from
https://bugs.llvm.org/show_bug.cgi?id=43251
but with different predicate that requires that the offset is non-zero.

The completeness bit comes from the fact that a similar pattern (offset != zero)
will be needed for https://bugs.llvm.org/show_bug.cgi?id=43259,
so it'd seem to be good to not overlook very similar patterns..

Proofs: https://rise4fun.com/Alive/21b

Also, there is something odd with `isKnownNonZero()`, if the non-zero
knowledge was specified as an assumption, it didn't pick it up (PR43267)

With this, i see no other missing folds for
https://bugs.llvm.org/show_bug.cgi?id=43251

Reviewers: spatel, nikic, xbolva00

Reviewed By: spatel

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372257 91177308-0d34-0410-b5e6-96231b3b80d8
2019-09-18 20:10:07 +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
c5c43eb086 [InstCombine] foldXorOfICmps(): don't give up on non-single-use ICmp's if all users are freely invertible
Summary:
This is rather unconventional..

As the comment there says, we don't have much folds for xor-of-icmps,
we try to turn them into an and-of-icmps, for which we have plenty of folds.
But if the ICmp we need to invert is not single-use - we give up.

As discussed in https://reviews.llvm.org/D65148#1603922,
we may have a non-canonical CLAMP pattern, with bit match and
select-of-threshold that we'll potentially clamp.
As it can be seen in `canonicalize-clamp-with-select-of-constant-threshold-pattern.ll`,
out of all 8 variations of the pattern, only two are **not** canonicalized into
the variant with and+icmp instead of bit math.
The reason is because the ICmp we need to invert is not single-use - we give up.

We indeed can't perform this fold at will, the general rule is that
we should not increase instruction count in InstCombine,

But we wouldn't end up increasing instruction count if we can adapt every other
user to the inverted value. This way the `not` we create **will** get folded,
and in the end the instruction count did not increase.

For that, of course, we need to look at the users of a Value,
which is again rather unconventional for InstCombine :S

Thus i'm proposing to be a little bit more insistive in `foldXorOfICmps()`.
The alternatives would be to not create that `not`, but add duplicate code to
manually invert all users; or to add some even less general combine to handle
some more specific pattern[s].

Reviewers: spatel, nikic, RKSimon, craig.topper

Reviewed By: spatel

Subscribers: hiraditya, jdoerfert, dmgreen, llvm-commits

Tags: #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368685 91177308-0d34-0410-b5e6-96231b3b80d8
2019-08-13 12:49:06 +00:00
Craig Topper
609d3187b1 [InstCombine] Teach foldOrOfICmps to allow icmp eq MIN_INT/MAX to be part of a range comparision. Similar for foldAndOfICmps
We can treat icmp eq X, MIN_UINT as icmp ule X, MIN_UINT and allow
it to merge with icmp ugt X, C. Similar for the other constants.

We can do simliar for icmp ne X, (U)INT_MIN/MAX in foldAndOfICmps. And we already handled UINT_MIN there.

Fixes PR42691.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366945 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-24 20:57:29 +00:00
Craig Topper
907ce53c5d [InstCombine] Update comment I missed in r366649. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366658 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-21 16:15:03 +00:00
Craig Topper
a787e56a9d [InstCombine] Remove insertRangeTest code that handles the equality case.
For equality, the function called getTrue/getFalse with the VT
of the comparison input. But getTrue/getFalse need the boolean VT.
So if this code ever executed, it would assert.

I believe these cases are removed by InstSimplify so we don't get here.

So this patch just fixes up an assert to exclude the equality
possibility and removes the broken code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366649 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-21 06:43:38 +00:00
Craig Topper
c409d22837 [InstCombine] Don't use AddOne/SubOne to see if two APInts are 1 apart. Use APInt operations instead. NFCI
AddOne/SubOne create new Constant objects. That seems heavy for
comparing ConstantInts which wrap APInts. Just do the math on
on the APInts and compare them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366648 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-21 05:26:05 +00:00
Rui Ueyama
c3f211d97b Fix parameter name comments using clang-tidy. NFC.
This patch applies clang-tidy's bugprone-argument-comment tool
to LLVM, clang and lld source trees. Here is how I created this
patch:

$ git clone https://github.com/llvm/llvm-project.git
$ cd llvm-project
$ mkdir build
$ cd build
$ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug \
    -DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra' \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DLLVM_ENABLE_LLD=On \
    -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ../llvm
$ ninja
$ parallel clang-tidy -checks='-*,bugprone-argument-comment' \
    -config='{CheckOptions: [{key: StrictMode, value: 1}]}' -fix \
    ::: ../llvm/lib/**/*.{cpp,h} ../clang/lib/**/*.{cpp,h} ../lld/**/*.{cpp,h}

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366177 91177308-0d34-0410-b5e6-96231b3b80d8
2019-07-16 04:46:31 +00:00
Sanjay Patel
1c6a395c06 [InstCombine] squash is-not-power-of-2 using ctpop
This is the Demorgan'd 'not' of the pattern handled in:
D63660 / rL364153

This is another intermediate IR step towards solving PR42314:
https://bugs.llvm.org/show_bug.cgi?id=42314

We can test if a value is not a power-of-2 using ctpop(X) > 1,
so combining that with an is-zero check of the input is the
same as testing if not exactly 1 bit is set:

(X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364246 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-24 22:35:26 +00:00
Sanjay Patel
3c6fdf0329 [InstCombine] squash is-power-of-2 that uses ctpop
This is another intermediate IR step towards solving PR42314:
https://bugs.llvm.org/show_bug.cgi?id=42314

We can test if a value is power-of-2-or-0 using ctpop(X) < 2,
so combining that with a non-zero check of the input is the
same as testing if exactly 1 bit is set:

(X != 0) && (ctpop(X) u< 2) --> ctpop(X) == 1

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364153 91177308-0d34-0410-b5e6-96231b3b80d8
2019-06-23 14:22:37 +00:00
Sanjay Patel
8ddb735757 [InstCombine] try harder to form rotate (funnel shift) (PR20750)
We have a similar match for patterns ending in a truncate. This
should be ok for all targets because the default expansion would
still likely be better from replacing 2 'and' ops with 1.

Attempt to show the logic equivalence in Alive (which doesn't
currently have funnel-shift in its vocabulary AFAICT):

  %shamt = zext i8 %i to i32
  %m = and i32 %shamt, 31
  %neg = sub i32 0, %shamt
  %and4 = and i32 %neg, 31
  %shl = shl i32 %v, %m
  %shr = lshr i32 %v, %and4
  %or = or i32 %shr, %shl
  =>
  %a = and i8 %i, 31
  %shamt2 = zext i8 %a to i32
  %neg2 = sub i32 0, %shamt2
  %and4 = and i32 %neg2, 31
  %shl = shl i32 %v, %shamt2
  %shr = lshr i32 %v, %and4
  %or = or i32 %shr, %shl

https://rise4fun.com/Alive/V9r

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360605 91177308-0d34-0410-b5e6-96231b3b80d8
2019-05-13 17:28:19 +00:00
Craig Topper
8ff8e3360b [InstCombine] Don't transform ((C1 OP zext(X)) & C2) -> zext((C1 OP X) & C2) if either zext or OP has another use.
If they have other users we'll just end up increasing the instruction count.

We might be able to weaken this to only one of them having a single use if we can prove that the and will be removed.

Fixes PR41164.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356690 91177308-0d34-0410-b5e6-96231b3b80d8
2019-03-21 17:50:49 +00:00
Sanjay Patel
94418e1f64 [InstCombine] fold logic-of-nan-fcmps (PR41069)
Combine 2 fcmps that are checking for nan-ness:
   and (fcmp ord X, 0), (and (fcmp ord Y, 0), Z) --> and (fcmp ord X, Y), Z
   or  (fcmp uno X, 0), (or  (fcmp uno Y, 0), Z) --> or  (fcmp uno X, Y), Z

This is an exact match for a minimal reassociation pattern.
If we want to handle this more generally that should go in
the reassociate pass and allow removing this code.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356471 91177308-0d34-0410-b5e6-96231b3b80d8
2019-03-19 16:39:17 +00:00
Sanjay Patel
a054687ab1 [InstCombine] Fix matchRotate bug when one operand is a ConstantExpr shift
This bug seems to be harmless in release builds, but will cause an error in UBSAN
builds or an assertion failure in debug builds.

When it gets to this opcode comparison, it assumes both of the operands are BinaryOperators,
but the prior m_LogicalShift will also match a ConstantExpr. The cast<BinaryOperator> will
assert in a debug build, or reading an invalid value for BinaryOp from memory with
((BinaryOperator*)constantExpr)->getOpcode() will cause an error in a UBSAN build.

The test I added will fail without this change in debug/UBSAN builds, but not in release.

Patch by: @AndrewScheidecker (Andrew Scheidecker)

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353736 91177308-0d34-0410-b5e6-96231b3b80d8
2019-02-11 19:26:27 +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
Sanjay Patel
41d08309c8 [InstCombine] canonicalize another raw IR rotate pattern to funnel shift
This is matching the equivalent of the DAG expansion, 
so it should never end up with worse perf than the 
original code even if the target doesn't have a rotate
instruction.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350672 91177308-0d34-0410-b5e6-96231b3b80d8
2019-01-08 22:39:55 +00:00
Sanjay Patel
04cb4ca323 [CmpInstAnalysis] fix function signature for ICmp code to predicate; NFC
The old function underspecified the return type, took an unused parameter,
and had a misleading name.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348292 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-04 18:53:27 +00:00
Sanjay Patel
79a6444f88 [CmpInstAnalysis] fix formatting; NFC
There are potential improvements to the structure of this API
raised by D54994, but remove some cosmetic blemishes before
making any functional changes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348149 91177308-0d34-0410-b5e6-96231b3b80d8
2018-12-03 15:48:30 +00:00
Sanjay Patel
5e3c9a56cb [InstCombine] fix formatting for matchBSwap(); NFC
We should have a similar function for matching rotate and/or 
funnel shift, so tidy up the related existing call.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346871 91177308-0d34-0410-b5e6-96231b3b80d8
2018-11-14 16:03:36 +00:00
Sanjay Patel
c26bd2324d [InstCombine] try harder to form select from logic ops (2nd try)
The original patch was committed here:
rL344609
...and reverted:
rL344612
...because it did not properly check/test data types before calling
ComputeNumSignBits(). 

The tests that caused bot failures for the previous commit are 
over-reaching front-end tests that run the entire -O optimizer 
pipeline: 
    Clang :: CodeGen/builtins-systemz-zvector.c
    Clang :: CodeGen/builtins-systemz-zvector2.c

I've added a negative test here to ensure coverage for that case.
The new early exit check also tests the type of the 'B' parameter,
so we don't waste time on matching if either value is unsuitable.

Original commit message:

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

The patterns shown here are a special case of something
that we already convert to select. Using ComputeNumSignBits()
catches that case (but not the more complicated motivating
patterns yet).

The backend has hooks/logic to convert back to logic ops
if that's better for the target.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345149 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-24 15:17:56 +00:00
Sanjay Patel
5973d70552 revert rL344609: [InstCombine] try harder to form select from logic ops
I noticed a missing check and added it at rL344610, but there actually
are codegen tests that will fail without that, so I'll edit those and
submit a fixed patch with more tests.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344612 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-16 15:26:08 +00:00
Sanjay Patel
0f096ec04e [InstCombine] make sure type is integer before calling ComputeNumSignBits
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344610 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-16 14:44:50 +00:00
Sanjay Patel
42fced4e53 [InstCombine] try harder to form select from logic ops
This is part of solving PR37549:
https://bugs.llvm.org/show_bug.cgi?id=37549

The patterns shown here are a special case of something
that we already convert to select. Using ComputeNumSignBits()
catches that case (but not the more complicated motivating
patterns yet).

The backend has hooks/logic to convert back to logic ops
if that's better for the target.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344609 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-16 14:35: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
Craig Topper
93dcdfe7b7 [InstCombine] Fold (xor (min/max X, Y), -1) -> (max/min ~X, ~Y) when X and Y are freely invertible.
This allows the xor to be removed completely.

This might help with recomitting r341674, but seems good regardless.

Coincidentally fixes PR38915.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342163 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-13 18:52:58 +00:00
Craig Topper
189c2c8cb6 [InstCombine] Fold (min/max ~X, Y) -> ~(max/min X, ~Y) when Y is freely invertible
If the ~X wasn't able to simplify above the max/min, we might be able to simplify it by moving it below the max/min.

I had to modify the ~(min/max ~X, Y) transform to prevent getting stuck in a loop when we saw the new ~(max/min X, ~Y) before the ~Y had been folded away to remove the new not.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341674 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-07 16:19:50 +00:00
Sanjay Patel
80b7585dc6 [InstCombine] add xor+not folds
This fold is needed to avoid a regression when we try
to recommit rL300977. 
We can't see the most basic win currently because 
demanded bits changes the patterns:
https://rise4fun.com/Alive/plpp


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341559 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-06 16:23:40 +00:00
Sanjay Patel
cb00c85d1c [InstCombine] fix xor-or-xor fold to check uses and handle commutes
I'm probably missing some way to use m_Deferred to remove the code
duplication, but that can be a follow-up.

The improvement in demand_shrink_nsw.ll is an example of missing
the fold because the pattern matching was deficient. I didn't try
to follow the bits in that test, but Alive says it's correct:
https://rise4fun.com/Alive/ugc


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341426 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-04 23:22:13 +00:00
Sanjay Patel
04349cea71 [InstCombine] make ((X & C) ^ C) form consistent for vectors
It would be better to create a 'not' here, but that's not possible yet.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341410 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-04 21:17:14 +00:00
Sanjay Patel
85c2e694ef [InstCombine] simplify code for xor folds; NFCI
This is just a cleanup step. The TODO comments show
what is wrong with the 'and' version of the fold.
Fixing this should be part of recommitting:
rL300977


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341405 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-04 21:00:13 +00:00
Sanjay Patel
cc6f9cbb28 [InstCombine] simplify xor/not folds; NFCI
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341336 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-03 18:40:56 +00:00
Sanjay Patel
8427b2fbd1 [InstCombine] allow add+not --> sub for arbitrary vector constants.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341335 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-03 18:21:59 +00:00
Sanjay Patel
87137bbfee [InstCombine] allow not+sub fold for arbitrary vector constants
The fold was implemented for the general case but use-limitation,
but the later constant version which didn't check uses was only
matching splat constants.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341292 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-02 19:31:45 +00:00
Sanjay Patel
2a632aa1b6 [InstCombine] simplify code for 'or' fold
This is no-outwardly-visible-change intended, so no test.
But the code is smaller and more efficient. The check for
a 'not' op is intended to avoid the expensive value tracking
call when it should not be necessary, and it might prevent
infinite looping when we resurrect:
rL300977


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341280 91177308-0d34-0410-b5e6-96231b3b80d8
2018-09-01 15:08:59 +00:00
Craig Topper
2f00acbb71 [InstCombine] Pull simple checks above a more complicated one. NFCI
I'm assuming its easier to make sure the RHS of an XOR is all ones than it is to check for the many select patterns we have. So lets check that first. Same with the one use check.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340321 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-21 19:17:00 +00:00
Amara Emerson
9dfeae47a7 [InstCombine] Fix IC trying to create a xor of pointer types.
rdar://42473741

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339796 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-15 17:46:22 +00:00
Roman Lebedev
f91b41f402 [InstCombine] Re-land: Optimize redundant 'signed truncation check pattern'.
Summary:
This comes with `Implicit Conversion Sanitizer - integer sign change` (D50250):
```
signed char test(unsigned int x) { return x; }
```
`clang++ -fsanitize=implicit-conversion -S -emit-llvm -o - /tmp/test.cpp -O3`
* Old: {F6904292}
* With this patch: {F6904294}

General pattern:
  X & Y

Where `Y` is checking that all the high bits (covered by a mask `4294967168`)
are uniform, i.e.  `%arg & 4294967168`  can be either  `4294967168`  or  `0`
Pattern can be one of:
  %t = add        i32 %arg,    128
  %r = icmp   ult i32 %t,      256
Or
  %t0 = shl       i32 %arg,    24
  %t1 = ashr      i32 %t0,     24
  %r  = icmp  eq  i32 %t1,     %arg
Or
  %t0 = trunc     i32 %arg  to i8
  %t1 = sext      i8  %t0   to i32
  %r  = icmp  eq  i32 %t1,     %arg
This pattern is a signed truncation check.

And `X` is checking that some bit in that same mask is zero.
I.e. can be one of:
  %r = icmp sgt i32   %arg,    -1
Or
  %t = and      i32   %arg,    2147483648
  %r = icmp eq  i32   %t,      0

Since we are checking that all the bits in that mask are the same,
and a particular bit is zero, what we are really checking is that all the
masked bits are zero.
So this should be transformed to:
  %r = icmp ult i32 %arg, 128

The transform itself ended up being rather horrible, even though i omitted some cases.
Surely there is some infrastructure that can help clean this up that i missed?

https://rise4fun.com/Alive/3Ou

The initial commit (rL339610)
was reverted, since the first assert was being triggered.
The @positive_with_extra_and test now has coverage for that case.

Reviewers: spatel, craig.topper

Reviewed By: spatel

Subscribers: RKSimon, erichkeane, vsk, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339621 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-13 21:54:37 +00:00
Roman Lebedev
8244893b61 Revert "[InstCombine] Optimize redundant 'signed truncation check pattern'."
At least one buildbot was able to actually trigger that assert
on the top of the function. Will investigate.

This reverts commit r339610.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339612 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-13 20:46:22 +00:00
Roman Lebedev
3edbc102dd [InstCombine] Optimize redundant 'signed truncation check pattern'.
Summary:
This comes with `Implicit Conversion Sanitizer - integer sign change` (D50250):
```
signed char test(unsigned int x) { return x; }
```
`clang++ -fsanitize=implicit-conversion -S -emit-llvm -o - /tmp/test.cpp -O3`
* Old: {F6904292}
* With this patch: {F6904294}

General pattern:
  X & Y

Where `Y` is checking that all the high bits (covered by a mask `4294967168`)
are uniform, i.e.  `%arg & 4294967168`  can be either  `4294967168`  or  `0`
Pattern can be one of:
  %t = add        i32 %arg,    128
  %r = icmp   ult i32 %t,      256
Or
  %t0 = shl       i32 %arg,    24
  %t1 = ashr      i32 %t0,     24
  %r  = icmp  eq  i32 %t1,     %arg
Or
  %t0 = trunc     i32 %arg  to i8
  %t1 = sext      i8  %t0   to i32
  %r  = icmp  eq  i32 %t1,     %arg
This pattern is a signed truncation check.

And `X` is checking that some bit in that same mask is zero.
I.e. can be one of:
  %r = icmp sgt i32   %arg,    -1
Or
  %t = and      i32   %arg,    2147483648
  %r = icmp eq  i32   %t,      0

Since we are checking that all the bits in that mask are the same,
and a particular bit is zero, what we are really checking is that all the
masked bits are zero.
So this should be transformed to:
  %r = icmp ult i32 %arg, 128

https://rise4fun.com/Alive/3Ou

Reviewers: spatel, craig.topper

Reviewed By: spatel

Subscribers: RKSimon, erichkeane, vsk, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339610 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-13 20:33:08 +00:00
Craig Topper
6145f7d3cf [InstCombine] Fix typo in comment. NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339532 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-13 00:54:23 +00:00
Craig Topper
069f0c31f7 [InstCombine] Replace call to haveNoCommonBitsSet in visitXor with just the special case that doesn't use computeKnownBits.
Summary: computeKnownBits is expensive. The cases that would be detected by the computeKnownBits portion of haveNoCommonBitsSet were already handled by the earlier call to SimplifyDemandedInstructionBits.

Reviewers: spatel, lebedev.ri

Reviewed By: lebedev.ri

Subscribers: llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339531 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-13 00:38:27 +00:00
Roman Lebedev
b6b375c7ec [InstCombine] De Morgan: sink 'not' into 'xor' (PR38446)
Summary:
https://rise4fun.com/Alive/IT3

Comes up in the [most ugliest]  `signed int` -> `signed char`  case of
`-fsanitize=implicit-conversion` (https://reviews.llvm.org/D50250)
Previously, we were stuck with `not`: {F6867736}
But now we are able to completely get rid of it: {F6867737}
(FIXME: why are we loosing the metadata? that seems wrong/strange.)

Here, we only want to do that it we will be able to completely
get rid of that 'not'.

Reviewers: spatel, craig.topper

Reviewed By: spatel

Subscribers: vsk, erichkeane, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339243 91177308-0d34-0410-b5e6-96231b3b80d8
2018-08-08 13:31:19 +00:00
Sanjay Patel
44442fbe1a [InstCombine] simplify code for A & (A ^ B) --> A & ~B
This fold was written in an odd way and tried to avoid
an endless loop by bailing out on all constants instead
of the supposedly problematic case of -1. But (X & -1) 
should always be simplified before we reach here, so I'm
not sure how that is a problem.

There were no tests for the commuted patterns, so I added
those at rL338364.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338367 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-31 13:00:03 +00:00
Sanjay Patel
4582fbe062 [InstCombine] not(sub X, Y) --> add (not X), Y
The tests with constants show a missing optimization.
Analysis for adds is better than subs, so this can also
help with other transforms. And codegen is better with 
adds for targets like x86 (destructive ops, no sub-from).

https://rise4fun.com/Alive/llK


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338118 91177308-0d34-0410-b5e6-96231b3b80d8
2018-07-27 10:54:48 +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
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
David Blaikie
8325fb20d4 Move Analysis/Utils/Local.h back to Transforms
Review feedback from r328165. Split out just the one function from the
file that's used by Analysis. (As chandlerc pointed out, the original
change only moved the header and not the implementation anyway - which
was fine for the one function that was used (since it's a
template/inlined in the header) but not in general)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333954 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-04 21:23:21 +00:00
Sanjay Patel
b155a7cf56 [InstCombine] call simplify before trying vector folds
As noted in the review thread for rL333782, we could have
made a bug harder to hit if we were simplifying instructions
before trying other folds. 

The shuffle transform in question isn't ever a simplification;
it's just a canonicalization. So I've renamed that to make that 
clearer.

This is NFCI at this point, but I've regenerated the test file 
to show the cosmetic value naming difference of using 
instcombine's RAUW vs. the builder.

Possible follow-ups:
1. Move reassociation folds after simplifies too.
2. Refactor common code; we shouldn't have so much repetition.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333820 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-02 16:27:44 +00:00
Roman Lebedev
81e2b6bb01 Revert rL333106 / D46814: [InstCombine] Fold unfolded masked merge pattern with variable mask!
In post-commit review, Eric Christopher notes that many
new MSan warnings are being observed with this patch.

The probable reason is: if 'y' is undef here and we could
evaluate it twice and get different results.
We can't increase the number of uses of a value.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333631 91177308-0d34-0410-b5e6-96231b3b80d8
2018-05-31 06:00:36 +00:00