1035 Commits

Author SHA1 Message Date
Nikita Popov
c41aa41957 [ConstFold] Add missing check for inbounds gep
If the gep is not inbounds, then the gep might compute a null
value even if the base pointer is non-null.
2022-01-06 09:59:40 +01:00
Nikita Popov
37c9171764 [ConstantFold] Add test for invalid non-inbounds gep icmp fold
The gep evaluated to null in this case, and as such is not ne null.
2022-01-06 09:59:40 +01:00
Sanjay Patel
4a8c0aa094 [InstSimplify] add tests for udiv/urem with known bits; NFC 2022-01-05 08:33:04 -05:00
Nikita Popov
3dc1907d06 [ConstantFold] Use ConstantFoldLoadFromUniformValue() in more places
In particular, this also preserves undef when loading from padding,
rather than converting it to zero through a different codepath.

This is the remaining part of D115924.
2022-01-05 12:47:50 +01:00
Nikita Popov
4e62d210c4 [ConstantFold] Add test for load of padding (NFC)
This currently load zero rather than undef.
2022-01-05 12:47:49 +01:00
Nikita Popov
99c6b12b92 [ConstantFolding] Unify handling of load from uniform value
There are a number of places that specially handle loads from a
uniform value where all the bits are the same (zero, one, undef,
poison), because we a) don't care about the load offset in that
case b) it bypasses casts that might not be legal generally but
do work with uniform values.

We had multiple implementations of this, with a different set of
supported values each time. This replaces two usages with a more
complete helper. Other usages will be replaced separately, because
they have larger impact.

This is part of D115924.
2022-01-05 12:30:46 +01:00
Nikita Popov
00686ab4af [ConstantFold] Add additional load from uniform value tests (NFC) 2022-01-05 12:30:46 +01:00
Nikita Popov
6c031780aa [ConstantFold] Remove another incorrect icmp of gep fold
This folded (null + X) == g to false, but of course this is
incorrect if X == g.

Possibly this got confused with the null == g case, which is
already handled elsewhere.
2022-01-04 16:08:09 +01:00
Nikita Popov
25448826dd [InstSimplify] Update test to make miscompile more obvious (NFC)
This is now testing (null + g3) != g3 and still coming up with
"true" as the answer. The original case was a less obvious
miscompile with index overflow involved.
2022-01-04 16:08:09 +01:00
Nikita Popov
75db002725 [ConstantFold] Remove another incorrect icmp of GEP fold
This fold is not correct, because indices might evaluate to zero
even if they are not a literal zero integer. Additionally, this
fold would be wrong (in the general case) for non-i8 types as well,
due to index overflow.

Drop this fold and instead let the target-dependent constant
folder compute the actual offset and fold the comparison based
on that.
2022-01-04 12:27:40 +01:00
Nikita Popov
aefab6f8d5 [InstSimplify] Use weak symbol in test to show miscompile (NFC)
This fold is incorrect, because it assumes that all indices are
non-zero. This happens to be true for the test as written, but
doesn't hold if we use an extern weak global instead, for which
ptrtoint might be zero.

Add separate tests for the simple constant int case.
2022-01-04 12:27:40 +01:00
Nikita Popov
5afbfe33e7 [ConstantFold] Make icmp of gep fold offset based
We can fold an equality or unsigned icmp between base+offset1 and
base+offset2 with inbounds offsets by comparing the offsets directly.

This replaces a pair of specialized folds that tried to reason
based on the GEP structure instead. One of those folds was plain
wrong (because it does not account for negative offsets), while
the other is unnecessarily complicated and limited (e.g. it will
fail with bitcasts involved).

The disadvantage of this change is that it requires data layout,
so the fold is no longer performed by datalayout-independent
constant folding. I don't think this is a loss in practice, but
it does regress the ConstantExprFold.ll test, which checks folding
without running any passes.

Differential Revision: https://reviews.llvm.org/D116332
2022-01-03 09:41:37 +01:00
Sanjay Patel
c054402170 [InstSimplify] fold or-nand-xor
~(A & B) | (A ^ B) --> ~(A & B)

https://alive2.llvm.org/ce/z/hXQucg
2021-12-31 15:11:13 -05:00
Sanjay Patel
3bf2373d19 [InstSimplify] add tests for or-nand-xor; NFC 2021-12-31 15:11:13 -05:00
Nuno Lopes
e5e844b37e [NFC] Pre-commit test for InstSimplify phi(poison) 2021-12-30 12:37:20 +00:00
Sanjay Patel
0edf99950e [Analysis] allow caller to choose signed/unsigned when computing constant range
We should not lose analysis precision if an 'add' has both no-wrap
flags (nsw and nuw) compared to just one or the other.

This patch is modeled on a similar construct that was added with
D59386.

I don't think it is possible to expose a problem with an unsigned
compare because of the way this was coded (nuw is handled first).

InstCombine has an assert that fires with the example from:
https://github.com/llvm/llvm-project/issues/52884
...because it was expecting InstSimplify to handle this kind of
pattern with an smax.

Fixes #52884

Differential Revision: https://reviews.llvm.org/D116322
2021-12-28 09:45:37 -05:00
Sanjay Patel
aaeae842ef [InstSimplify] add tests for icmp with no-wrap add operand; NFC 2021-12-28 09:45:37 -05:00
Nikita Popov
3bfe0962ba [ConstFold] Add another icmp of gep of global test (NFC)
This time with some complex arithmetic involving bitcasts.
2021-12-28 14:28:28 +01:00
Nikita Popov
23de66d163 [ConstFold] Don't fold signed comparison of gep of global
An inbounds GEP may still cross the sign boundary, so signed icmps
cannot be folded (https://alive2.llvm.org/ce/z/XSgi4D). This was
previously fixed for other folds in this function, but this one
was missed.
2021-12-28 14:13:33 +01:00
Nikita Popov
1bd11d34fe [ConstFold] Add additional icmp of gep of global tests (NFC)
The fold is incorrect for the sgt case, as gep inbounds is allowed
to cross the sign boundary.
2021-12-28 14:07:15 +01:00
Mehrnoosh Heidarpour
0ff20f2f44 [InstSimplify] Fold logic AND to zero
Adding following fold opportunity:
((A | B) ^ A) & ((A | B) ^ B) --> 0

Reviewed By: spatel, rampitec

Differential Revision: https://reviews.llvm.org/D115755
2021-12-23 10:06:26 -05:00
Serge Pavlov
185c80b89a [ConstantFolding] Tests for constrained compare intrinsics
This are tests extracted from https://reviews.llvm.org/D110322, committed
prior to that patch to show the change in behavior.
2021-12-22 18:08:30 +07:00
Serge Pavlov
77b923d0db [ConstantFolding] Do not remove side effect from constrained functions
According to the discussion in https://reviews.llvm.org/D110322 the code
that removes side effect from replaced function call is deleted.

Differential Revision: https://reviews.llvm.org/D115870
2021-12-22 13:45:49 +07:00
Nikita Popov
2926d6d335 [ConstantFold][GlobalOpt] Don't create x86_mmx null value
This fixes the assertion failure reported at
https://reviews.llvm.org/D114889#3198921 with a straightforward
check, until the cleaner fix in D115924 can be reapplied.
2021-12-21 09:11:41 +01:00
Nikita Popov
aeb36ae0f4 Revert "[ConstantFolding] Unify handling of load from uniform value"
This reverts commit 9fd4f80e33a4ae4567483819646650f5735286e2.

This breaks SingleSource/Regression/C/gcc-c-torture/execute/pr19687.c
in test-suite. Either the test is incorrect, or clang is generating
incorrect union initialization code. I've submitted
https://reviews.llvm.org/D115994 to fix the test, assuming my
interpretation is correct. Reverting this in the meantime as it
may take some time to resolve.
2021-12-18 20:46:52 +01:00
Nikita Popov
9fd4f80e33 [ConstantFolding] Unify handling of load from uniform value
There are a number of places that specially handle loads from a
uniform value where all the bits are the same (zero, one, undef,
poison), because we a) don't care about the load offset in that
case and b) it bypasses casts that might not be legal generally
but do work with uniform values.

We had multiple implementations of this, with a different set of
supported values each time, as well as incomplete type checks in
some cases. In particular, this fixes the assertion reported in
https://reviews.llvm.org/D114889#3198921, as well as a similar
assertion that could be triggered via constant folding.

Differential Revision: https://reviews.llvm.org/D115924
2021-12-17 17:05:06 +01:00
Mehrnoosh Heidarpour
b5c49b62a2 [InstSimplify] Add tests for logic AND; NFC 2021-12-14 15:50:07 -05:00
Nikita Popov
65bec04295 [ConstantFold] Handle same type in ConstantFoldLoadThroughBitcast
Usually the case where the types are the same ends up being handled
fine because it's legal to do a trivial bitcast to the same type.
However, this is not true for aggregate types. Short-circuit the
whole code if the types match exactly to account for this.
2021-12-10 16:39:50 +01:00
Nikita Popov
9c244a33e7 [InstSimplify] Add test for load of aggregate (NFC)
The test is switched to use -instsimplify as it is in the
InstSimplify directory. In this particular case InstCombine does
fold the load (in a very roundabout way), but InstSimplify does not.
2021-12-10 16:18:18 +01:00
Hasyimi Bahrudin
c1cd698a52 [InstSimplify] Simplify bool icmp with not in LHS
Refer to https://llvm.org/PR52546.

Simplifies the following cases:
    not(X) == 0 -> X != 0 -> X
    not(X) <=u 0 -> X >u 0 -> X
    not(X) >=s 0 -> X <s 0 -> X
    not(X) != 1 -> X == 1 -> X
    not(X) <=u 1 -> X >=u 1 -> X
    not(X) >s 1 -> X <=s -1 -> X

Differential Revision: https://reviews.llvm.org/D114666
2021-12-09 16:26:46 -05:00
Hasyimi Bahrudin
64d4bd02dc [InstCombine][InstSimplify] Add baseline tests for icmp bool with not on LHS; NFC
See D114666 for proposed code change to instsimplify.

The difference between the CHECK result of these 2 tests
highlights missed folds in instsimplify
(e.g. (icmp eq (xor X, true), false) -> X) that are
already being handled by instcombine.

The tests are based on:
llvm/test/Transforms/InstSimplify/icmp-bool-constant.ll

Differential Revision: https://reviews.llvm.org/D115209
2021-12-08 08:48:03 -05:00
Sanjay Patel
8a69b04478 [InstSimplify] add logic fold for 'or' with 'xor'+'and'
This replaces the 'or' from 4b30076f16fc with an 'and'.
We have to guard against propagating undef elements from
vector 'not' values:
https://alive2.llvm.org/ce/z/irMwRc
2021-12-07 11:08:26 -05:00
Sanjay Patel
c65e651e60 [InstSimplify] fix logic fold of 'or' for vectors
Reduce code duplication for commutative pattern matching
and fix a miscompile.

We can't safely propagate an undef element in this transform:
https://alive2.llvm.org/ce/z/s5xy55
2021-12-05 09:57:07 -05:00
Sanjay Patel
0bb8a97b41 [InstSimplify] add/adjust tests for 'or' logic fold; NFC
The last test shows a miscompile:
https://alive2.llvm.org/ce/z/s5xy55
2021-12-05 09:28:11 -05:00
Mehrnoosh Heidarpour
e94134052f [InstSimplify] Add logic 'or' fold to -1
Adding the following folding opportunity:
(~A | B) | (A ^ B) --> -1

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

Differential revision: https://reviews.llvm.org/D114996
2021-12-04 15:04:18 -05:00
David Green
ab0c5cea0b [ARM] Use v2i1 for MVE and CDE intrinsics
This adjusts all the MVE and CDE intrinsics now that v2i1 is a legal
type, to use a <2 x i1> as opposed to emulating the predicate with a
<4 x i1>. The v4i1 workarounds have been removed leaving the natural
v2i1 types, notably in vctp64 which now generates a v2i1 type.

AutoUpgrade code has been added to upgrade old IR, which needs to
convert the old v4i1 to a v2i1 be converting it back and forth to an
integer with arm.mve.v2i and arm.mve.i2v intrinsics. These should be
optimized away in the final assembly.

Differential Revision: https://reviews.llvm.org/D114455
2021-12-03 15:27:58 +00:00
Mehrnoosh Heidarpour
54dc03b97b [InstSimplify] Add test case for logic 'or' fold; NFC 2021-12-03 09:29:43 -05:00
Sanjay Patel
4b30076f16 [InstSimplify] add logic fold for 'or'
https://alive2.llvm.org/ce/z/4PaPDy

There's a related fold where the inner 'or' is replaced by 'and',
but that needs to be more careful about matching a 'not'.
2021-11-30 14:08:54 -05:00
Sanjay Patel
6076c1dc1c [InstSimplify] make 'or' test names more descriptive; NFC
Also, vary the types in a couple of tests for better coverage.
2021-11-30 14:08:54 -05:00
Sanjay Patel
33f8c1168f [InstSimplify] adjust tests for 'or' of logic ops; NFC
Half of the tests had an extra instruction so were not testing the minimal patterns.
2021-11-30 12:55:37 -05:00
Sanjay Patel
1fdb0f6ffd [InstSimplify] add tests for 'or' with logic ops; NFC
The code for these transforms can be refactored,
but the existing tests are incomplete.
2021-11-30 12:55:36 -05:00
Sanjay Patel
746e632daf [InstSimplify] add tests for 'or' logic folds; NFC
The tests are adapted from the xor patterns used with:
892648b18a8c
b326c058146f
2021-11-30 12:55:36 -05:00
Erik Desjardins
53b00b8215 [InstSimplify] Fold X {lshr,udiv} C <u X --> true for nonzero X, non-identity C
This eliminates the bounds check in Rust code like

pub fn mid(data: &[i32]) -> i32 {
  if data.is_empty() { return 0; }
  return data[data.len()/2];
}

(from https://blog.sigplan.org/2021/11/18/undefined-behavior-deserves-a-better-reputation/)

Alive proofs:
lshr https://alive2.llvm.org/ce/z/nyTu8D
udiv https://alive2.llvm.org/ce/z/CNUZH7

Differential Revision: https://reviews.llvm.org/D114279
2021-11-26 16:48:33 -05:00
Erik Desjardins
a68af62b42 [InstSimplify] baseline tests for icmp of lshr/udiv fold (NFC)
Precommits tests for https://reviews.llvm.org/D114279

Differential Revision: https://reviews.llvm.org/D114280
2021-11-26 15:57:04 -05:00
Zarko Todorovski
7f7dac7126 [NFC][llvm] Inclusive language: reword uses of sanity test and check
Part of continuing work to use more inclusive language. Reworded uses
of sanity check and sanity test in llvm/test/
2021-11-25 07:21:42 -05:00
Sanjay Patel
b326c05814 [InstSimplify] fold xor logic of 2 variables, part 2
(~a & b) ^ (a | b) --> a

This is the swapped and/or (Demorgan?) sibling fold for
the fold added with D114462 ( 892648b18a8c ).

This case is easier to specify because we are returning
a root value, not a 'not':
https://alive2.llvm.org/ce/z/SRzj4f
2021-11-24 08:15:47 -05:00
Sanjay Patel
823fc8aa06 [InstSimplify] add tests for xor logic; NFC 2021-11-24 08:15:47 -05:00
Sanjay Patel
892648b18a [InstSimplify] fold xor logic of 2 variables
(a & b) ^ (~a | b) --> ~a

I was looking for a shortcut to reduce some of the complex logic
folds that are currently up for review (D113216
and others in that stack), and I found this missing from
instcombine/instsimplify.

There is a trade-off in putting it into instsimplify: because
we can't create new values here, we need a strict 'not' op (no
undef elements). Otherwise, the fold is not valid:
https://alive2.llvm.org/ce/z/k_AGGj

If this was in instcombine instead, we could create the proper
'not'. But having the fold here benefits other passes like GVN
that use instsimplify as an analysis.

There is a related fold where 'and' and 'or' are swapped, and
that is planned as a follow-up commit.

Differential Revision: https://reviews.llvm.org/D114462
2021-11-23 16:50:23 -05:00
Sanjay Patel
14d743457c [InstSimplify] add tests for xor logic fold; NFC 2021-11-23 15:35:52 -05:00
Mehrnoosh Heidarpour
62c51a72f9 [InstSimplify] Fold A|B | (A^B) --> A|B
This patch adds the following fold opportunity:
A|B | (A^B) --> A|B

that is reported here : https://bugs.llvm.org/show_bug.cgi?id=52479

https://alive2.llvm.org/ce/z/33-My-

Test cases with base results are added in D113860

Reviewed By: rampitec

Differential Revision: https://reviews.llvm.org/D113861
2021-11-15 18:55:04 -05:00