Nikita Popov
2e0af16c93
[ValueTracking] Support add+icmp assumes for KnownBits
...
Support the canonical range check pattern for KnownBits assumptions.
This is the same as the generic ConstantRange handling, just shifted
by an offset.
2023-07-05 16:15:47 +02:00
Nikita Popov
dfb369399d
[ValueTracking] Directly use KnownBits shift functions
...
Make ValueTracking directly call the KnownBits shift helpers, which
provides more precise results.
Unfortunately, ValueTracking has a special case where sometimes we
determine non-zero shift amounts using isKnownNonZero(). I have my
doubts about the usefulness of that special-case (it is only tested
in a single unit test), but I've reproduced the special-case via an
extra parameter to the KnownBits methods.
Differential Revision: https://reviews.llvm.org/D151816
2023-06-01 09:46:16 +02:00
Nikita Popov
a1dec5dacb
[ValueTracking] Avoid optimizing away condition in test (NFC)
...
This is not what we're interested in testing, and it allows to
essentially optimize away the entire function with more powerful
optimization.
2023-05-26 16:38:37 +02:00
Nikita Popov
8f12057e8e
[ValueTracking] Avoid UB in test (NFC)
...
Don't use br undef, as it is UB.
2023-05-26 15:55:20 +02:00
Noah Goldstein
2622b2f409
[ValueTracking] Use select condition to help determine if select is non-zero
...
In `select c, x, y` the condition `c` dominates the resulting `x` or
`y` chosen by the `select`. This adds logic to `isKnownNonZero` to try
and use the `icmp` for the `c` condition to see if it implies the
select `x` or `y` are known non-zero.
For example in:
```
%c = icmp ugt i8 %x, %C
%r = select i1 %c, i8 %x, i8 %y
```
The true arm of select `%x` is non-zero (when "returned" by the
`select`) because `%c` being true implies `%x` is non-zero.
Alive2 Links (with `x {pred} C`):
- EQ iff `C != 0`:
- https://alive2.llvm.org/ce/z/umLabn
- NE iff `C == 0`:
- https://alive2.llvm.org/ce/z/DQvy8Y
- UGT [always]:
- https://alive2.llvm.org/ce/z/HBkjgQ
- UGE iff `C != 0`:
- https://alive2.llvm.org/ce/z/LDNifB
- SGT iff `C s>= 0`:
- https://alive2.llvm.org/ce/z/QzWDj3
- SGE iff `C s> 0`:
- https://alive2.llvm.org/ce/z/rR4g3D
- SLT iff `C s<= 0`:
- https://alive2.llvm.org/ce/z/uysayx
- SLE iff `C s< 0`:
- https://alive2.llvm.org/ce/z/2jYc7e
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D147900
2023-05-23 13:52:40 -05:00
Noah Goldstein
530bbc8f69
[ValueTracking] Add tests for using condition in select for non-zero analysis; NFC
...
Differential Revision: https://reviews.llvm.org/D147899
2023-05-23 13:52:40 -05:00
Noah Goldstein
8a60814ed5
[ValueTracking] Use KnownBits functions for computeKnownBits of saturating add/sub functions
...
The knownbits implementation covers all the cases previously handled
by `uadd.sat`/`usub.sat` as well some additional ones. We previously
were not handling the `ssub.sat`/`sadd.sat` cases at all.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D150103
2023-05-23 13:52:40 -05:00
Noah Goldstein
1e963b4081
[ValueTracking] Add tests for knownbits of saturating add/sub functions; NFC
...
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D150101
2023-05-23 13:52:39 -05:00
Noah Goldstein
4fd3401e76
[KnownBits] Improve implementation of KnownBits::abs
...
`abs` preserves the lowest set bit, so if we know the lowest set bit,
set it in the output.
As well, implement the case where the operand is known negative.
Reviewed By: foad, RKSimon
Differential Revision: https://reviews.llvm.org/D150100
2023-05-23 13:52:39 -05:00
Noah Goldstein
261e5d0951
[ValueTracking] Add tests for knownbits of abs; NFC
...
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D150099
2023-05-16 18:58:13 -05:00
Noah Goldstein
124547eae8
[ValueTracking] Use KnownBits::sdiv for sdiv opcode in computeKnownBits
...
We now of an implementation of `KnownBits::sdiv` so we can implement
this case.
Differential Revision: https://reviews.llvm.org/D150096
2023-05-16 18:58:12 -05:00
Noah Goldstein
99795afb28
[ValueTracking] Pass exact flag to KnownBits::udiv in computeKnownBits
...
This information was previously missing but we can use it for
determining the low-bits.
Differential Revision: https://reviews.llvm.org/D150095
2023-05-16 18:58:12 -05:00
Noah Goldstein
7d05ab99ed
[KnownBits] Improve KnownBits::udiv
...
We can more precisely determine the upper bits doing `MaxNum /
MinDenum` as opposed to only using the MSB.
As well, if the `exact` flag is set, we can sometimes determine some
of the low-bits.
Differential Revision: https://reviews.llvm.org/D150094
2023-05-16 18:58:12 -05:00
Noah Goldstein
53a079c8f7
[ValueTracking] Add tests for knownbits of sdiv and udiv; NFC
...
Differential Revision: https://reviews.llvm.org/D150092
2023-05-16 18:58:12 -05:00
Noah Goldstein
774ecc20e1
[ValueTracking] deduce X * Y != 0 if LowestKnownBit(X) * LowestKnownBit(Y) != 0
...
For `X * Y`, if there exists a subset of `X` and subset of `Y` s.t `sX * sY != 0`,
then `X * Y != 0`.
- See first proof: https://alive2.llvm.org/ce/z/28C9CG
- NB: This is why the previous Odd case works.
In knownbits we could exhaustively hunt for such a subset, but
`LSB(X)` and `LSB(Y)` actually works. If `LSB(X) * LSB(Y) != 0`, then
`X * Y != 0`
- See proof: https://alive2.llvm.org/ce/z/p5wWid
In `isKnownNonZero` we can use this as if the `LowestKnownOne(X) *
LowestKnownOne(Y) != 0`, then `X * Y != 0`, and we don't need to try
and other subsets.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D150425
2023-05-16 18:58:12 -05:00
Noah Goldstein
7f82f108c2
[ValueTracking] Add tests for deducing X * Y != 0 if LSB(X) * LSB(Y) != 0; NFC
...
Differential Revision: https://reviews.llvm.org/D150424
2023-05-16 18:58:12 -05:00
Noah Goldstein
7770b0abfd
[KnownBits] Improve KnownBits::rem(X, Y) in cases where we can deduce low-bits of output
...
The first `cttz(Y)` bits in `X` are translated 1-1 in the output.
Alive2 Links:
https://alive2.llvm.org/ce/z/Qc47p7
https://alive2.llvm.org/ce/z/19ut5H
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D149421
2023-05-07 19:11:53 -05:00
Noah Goldstein
7b1f123b15
[KnownBits] Add tests for getting lowbits of rem X, Y; NFC
...
Reviewed By: foad
Differential Revision: https://reviews.llvm.org/D149420
2023-05-07 19:11:53 -05:00
Noah Goldstein
5eedfff695
[ValueTracking] Add additional cases for isKnownNonZero(mul X, Y)
...
If either `X` or `Y` is odd and the other is non-zero, the result is
non-zero.
Alive2 Link:
https://alive2.llvm.org/ce/z/9V7-es
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149418
2023-04-30 10:06:46 -05:00
Noah Goldstein
d840391401
[ValueTracking] Add logic for isKnownNonZero(smin/smax X, Y)
...
For `smin` if either `X` or `Y` is negative, the result is non-zero.
For `smax` if either `X` or `Y` is strictly positive, the result is
non-zero.
For both if `X != 0` and `Y != 0` the result is non-zero.
Alive2 Link:
https://alive2.llvm.org/ce/z/7yvbgN
https://alive2.llvm.org/ce/z/zizbvq
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149417
2023-04-30 10:06:46 -05:00
Noah Goldstein
e78c30a10f
[ValueTracking] Add logic for isKnownNonZero(umin X, Y)
...
`(umin X, Y) != 0` -> `X != 0 && Y != 0`
Alive2 Link:
https://alive2.llvm.org/ce/z/AQh67i
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149416
2023-04-30 10:06:46 -05:00
Noah Goldstein
883daa7ac4
[ValueTracking] Add logic for isKnownNonZero(umax X, Y)
...
`(umax X, Y) != 0` -> `X != 0 || Y != 0`
Alive2 Link:
https://alive2.llvm.org/ce/z/_Z9AUT
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149415
2023-04-30 10:06:46 -05:00
Noah Goldstein
167ecdaa2c
[ValueTracking] Add logic for isKnownNonZero(sadd.sat X, Y)
...
The logic here is the same for `add` so reuse the existing helper
`isNonZeroAdd`
Alive2 Link:
https://alive2.llvm.org/ce/z/mhKvC5
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149414
2023-04-30 10:06:46 -05:00
Noah Goldstein
461ded4631
[ValueTracking] Add logic for isKnownNonZero(ssub.sat X, Y)
...
The logic here is the same for normal `(sub X, Y)`, so just reused
`isNonZeroSub`.
Alive2 Link:
https://alive2.llvm.org/ce/z/9kSkMv
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149412
2023-04-30 10:06:45 -05:00
Noah Goldstein
f1dfa4938a
[ValueTracking] Add logic for isKnownNonZero(sshl.sat/ushl.sat X, Y)
...
`(sshl/ushl X, Y) != 0` -> `X != 0`
Alive2 Links
https://alive2.llvm.org/ce/z/4WLM2p
https://alive2.llvm.org/ce/z/BHFng4
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149411
2023-04-30 10:06:45 -05:00
Noah Goldstein
ea5a0d4b90
[ValueTracking] Add logic for isKnownNonZero(ctlz/cttz X)
...
for `cttz` if `X[0]` is non-zero, then the expression is non-zero.
for `ctlz` if `X[SignBit]` is non-zero, then the expression in
non-zero.
Alive2 Links:
cttz (false): https://alive2.llvm.org/ce/z/ySQzbg
cttz (true): https://alive2.llvm.org/ce/z/auiTCJ
ctlz (false): https://alive2.llvm.org/ce/z/yk3sTJ
ctlz (true): https://alive2.llvm.org/ce/z/-JuDty
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149410
2023-04-30 10:06:45 -05:00
Noah Goldstein
c7f7f601f2
[ValueTracking] Handle bitcasts between vec-int-ptr in isKnownNonZero
...
We where missing these cases so something like:
`(bitcast to i32 (or v216 x, <2, 1>))`
would not be found to be non-zero.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149409
2023-04-30 10:06:45 -05:00
Noah Goldstein
f7bf984ed3
[ValueTracking] Add more tests for isKnownNonZero cases; NFC
...
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149408
2023-04-30 10:06:45 -05:00
Noah Goldstein
4cd1b67491
[ValueTracking] Add logic for fshl/fshr(A, B, C) != 0 if A == B && A ! = 0
...
Having `A == B` is quite common for rotate patterns.
Alive2 Links:
- https://alive2.llvm.org/ce/z/mPXi9c
- https://alive2.llvm.org/ce/z/UfDHoI
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149372
2023-04-28 01:57:37 -05:00
Noah Goldstein
74157bf6e2
[ValueTracking] Add tests for proving fshr/fshl is non-zero; NFC
...
Differential Revision: https://reviews.llvm.org/D149371
2023-04-28 01:57:31 -05:00
Noah Goldstein
d8e9dd33b2
[ValueTracking] Add logic for udiv x,y != 0 if y u<= x
...
Alive2 Link:
https://alive2.llvm.org/ce/z/2DKh46
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149203
2023-04-27 13:48:41 -05:00
Noah Goldstein
75b48b4077
[ValueTracking] Add logic for add nuw x,y != 0 -> x != 0 || y != 0
...
Alive2 Link:
https://alive2.llvm.org/ce/z/TKpqxc
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149204
2023-04-26 23:48:20 -05:00
Noah Goldstein
9b3c865d32
[ValueTracking] Add logic for (sub x, y) != 0 if we know KnownX != KnownY
...
Alive2 Link:
https://alive2.llvm.org/ce/z/TAFcjF
Differential Revision: https://reviews.llvm.org/D149202
2023-04-26 23:48:17 -05:00
Noah Goldstein
73f5f1a8fa
[ValueTracking] Add some additional tests for isKnownNonZero; NFC
...
Differential Revision: https://reviews.llvm.org/D149201
2023-04-26 23:48:10 -05:00
Noah Goldstein
e846ec57cb
Recommit "[ValueTracking] Apply the isKnownNonZero techniques in ashr/lshl to shl and vice-versa" (2nd Try)
...
Wasn't related to the bug it was original thought to be causing.
2023-04-18 17:17:57 -05:00
Noah Goldstein
3c4d9cc273
Revert "[ValueTracking] Apply the isKnownNonZero techniques in ashr/lshl to shl and vice-versa"
...
May be related to PR62175
This reverts commit 57590d1dd47bbe9aa4b79a0f93cc3ec62cc5d060.
2023-04-18 01:23:08 -05:00
Noah Goldstein
57590d1dd4
[ValueTracking] Apply the isKnownNonZero techniques in ashr/lshl to shl and vice-versa
...
For all shifts we can apply the same two optimizations.
1) `ShiftOp(KnownVal.One, Max(KnownCnt)) != 0`
-> result is non-zero
2) If already known `Val != 0` and we only shift out zeros (based
on `Max(KnownCnt)`)
-> result is non-zero
The former exists for `shl` and the latter (for constant `Cnt`) exists
for `ashr`/`lshr`.
This patch improves the latter to use `Max(KnownCnt)` instead of
relying on a constant shift `Cnt` and applies both techniques for all
shift ops.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D148404
2023-04-17 22:39:06 -05:00
Noah Goldstein
107a5e2bc7
[ValueTracking] Add more tests for isKnownNonZero(Shift); NFC
...
Differential Revision: https://reviews.llvm.org/D148403
2023-04-17 22:39:06 -05:00
Noah Goldstein
f688d215e5
[ValueTracking] Add shl nsw %val, %cnt != 0 if %val != 0.
...
Alive2 Link: https://alive2.llvm.org/ce/z/mxZLJn
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D147898
2023-04-14 18:23:47 -05:00
Noah Goldstein
684963b86d
[ValueTracking] Use maximum shift count in shl when determining if shl can be zero.
...
Previously only return `shl` non-zero if the shift value was `1`. We
can expand this if we have some bounds on the shift count.
For example:
```
%cnt = and %c, 16 ; Max cnt == 16
%val = or %v, 4 ; val[2] is known one
%shl = shl %val, %cnt ; (val.known.one << cnt.maxval) != 0
```
Differential Revision: https://reviews.llvm.org/D147897
2023-04-14 18:23:45 -05:00
Noah Goldstein
e7999fb42d
[ValueTracking] Add more tests for shl isKnownNonZero; NFC
...
Differential Revision: https://reviews.llvm.org/D147896
2023-04-14 18:23:35 -05:00
Noah Goldstein
4fcfff4f2d
Use analyzeKnownBitsFromAndXorOr in SimplifyDemandedUseBits for and/xor/or
...
There are extra patterns that have for these three logic operations
that aren't covered in `SimplifyDemandedUseBits`. To avoid duplicating
the code, just use `analyzeKnownBitsFromAndXorOr` in
`SimplifyDemandedUseBits` to get full coverage.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D142429
2023-02-23 19:52:17 -06:00
Noah Goldstein
196d3e3965
Add logic for tracking lowbit of (and/xor/or X, (add/sub X, Odd))
...
Any case of logicop + add/sub(Odd) we can prove the low bit is either
zero/non-zero.
Alive2 Links:
xor:
sub x, C: https://alive2.llvm.org/ce/z/aaABdS
sub C, x: https://alive2.llvm.org/ce/z/2W-ZJ7
add C, x: https://alive2.llvm.org/ce/z/pzDkte
or:
sub x, C: https://alive2.llvm.org/ce/z/xd-bcP
sub C, x: https://alive2.llvm.org/ce/z/p8hXJF
add C, x: https://alive2.llvm.org/ce/z/osmkB6
and:
sub x, C: https://alive2.llvm.org/ce/z/D_NNxR
sub C, x: https://alive2.llvm.org/ce/z/N_5C62
add C, x: https://alive2.llvm.org/ce/z/4cy7a4
Differential Revision: https://reviews.llvm.org/D142427
2023-02-23 19:52:17 -06:00
Noah Goldstein
5fe70be799
Add tests for KnownBits of (and/xor/or X, (add/sub X, OddV)); NFC
...
Differential Revision: https://reviews.llvm.org/D142426
2023-02-23 19:52:16 -06:00
Noah Goldstein
3bd38f6639
[ValueTracking] Add cases for additional ops in isKnownNonZero
...
Add cases for the following ops:
- 0-X -- https://alive2.llvm.org/ce/z/6C75Li
- bitreverse(X) -- https://alive2.llvm.org/ce/z/SGG1q9
- bswap(X) -- https://alive2.llvm.org/ce/z/p7pzwh
- ctpop(X) -- https://alive2.llvm.org/ce/z/c5y3BC
- abs(X) -- https://alive2.llvm.org/ce/z/yxXGz_
https://alive2.llvm.org/ce/z/rSRg4K
- uadd_sat(X, Y) -- https://alive2.llvm.org/ce/z/Zw-y4W
https://alive2.llvm.org/ce/z/2NRqRz
https://alive2.llvm.org/ce/z/M1OpF8
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D142828
2023-02-18 13:45:15 -06:00
Noah Goldstein
e0ce87509b
[ValueTracking] Add tests for additional isKnownNonZero cases; NFC
...
Add cases for the following ops:
- 0-X
- bitreverse(X)
- bswap(X)
- ctpop(X)
- abs(X)
- uadd_sat(X, Y)
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D142827
2023-02-18 13:44:55 -06:00
Noah Goldstein
9a8f517f57
[ValueTracking] Add KnownBits patterns xor(x, x - 1) and and(x, -x) for knowing upper bits to be zero
...
These two BMI pattern will clear the upper bits of result past the
first set bit. So if we know a single bit in `x` is set, we know that
`results[bitwidth - 1, log2(x) + 1] = 0`.
Alive2:
blsmsk: https://alive2.llvm.org/ce/z/a397BS
blsi: https://alive2.llvm.org/ce/z/tsbQhC
Differential Revision: https://reviews.llvm.org/D142271
2023-02-18 13:31:17 -06:00
Noah Goldstein
c8fb2775ce
[ValueTracking] Add tests for known bits after common BMI pattern (blsmsk/blsi); NFC
...
Differential Revision: https://reviews.llvm.org/D142270
2023-02-18 13:31:12 -06:00
Nikita Popov
7fbbbfd638
[ValueTracking] Convert tests to opaque pointers (NFC)
2022-12-16 12:19:03 +01:00
Matt Arsenault
a74c5707be
Fix some test files with executable permissions
2022-12-02 17:12:03 -05:00