297 Commits

Author SHA1 Message Date
Florian Hahn
b769758056
[Options] Use UseDerefAtPointSemantics cl::opt<bool>. (#123192)
It is used as boolean option, use cl::opt<bool> instead of
vl::opt<unsigned>.

PR: https://github.com/llvm/llvm-project/pull/123192
2025-01-16 14:07:03 +00:00
Ramkumar Ramachandra
f1632d25db
IR: introduce ICmpInst::isImpliedByMatchingCmp (#122597)
Create an abstraction over isImplied{True,False}ByMatchingCmp to
faithfully communicate the result of both functions, cleaning up code in
callsites. While at it, fix a bug in the implied-false version of the
function, which was inadvertedenly dropping samesign information.
2025-01-13 16:20:00 +00:00
Ramkumar Ramachandra
66badf224a
VT: teach a special-case optz about samesign (#122590)
There is a narrow special-case in isImpliedCondICmps that can benefit
from being taught about samesign. Since it costs us nothing to implement
it, teach it about samesign, for completeness. This patch marks the
completion of the effort to teach ValueTracking about samesign.
2025-01-12 15:19:29 +00:00
Ramkumar Ramachandra
f38c40bff3
VT: teach isImpliedCondMatchingOperands about samesign (#122474)
Move isImplied{True,False}ByMatchingCmp from CmpInst to ICmpInst, so
that it can operate on CmpPredicate instead of CmpInst::Predicate, and
teach it about samesign. There are two callers of this function, and we
choose to migrate the one in ValueTracking, namely
isImpliedCondMatchingOperands to CmpPredicate, hence teaching it about
samesign, with visible test impact.
2025-01-11 09:08:57 +00:00
Ramkumar Ramachandra
cfee344dda
VT: teach implied-cond-cr about samesign (#122447)
Teach isImpliedCondCommonOperandWithCR about samesign, noting that the
only case we need to handle is when exactly one of the icmps have
samesign.
2025-01-10 14:26:49 +00:00
Ramkumar Ramachandra
b53e79422a
VT: teach isImpliedCondOperands about samesign (#120263)
isImpliedCondICmps() and its callers in ValueTracking can greatly
benefit from being taught about samesign. As a first step, teach one
caller, namely isImpliedCondOperands(). Very minimal changes are
required for this, as CmpPredicate::getMatching() does most of the work.
2025-01-10 12:07:56 +00:00
Ramkumar Ramachandra
9d5299eb61
VT/test: pre-commit tests to enable samesign optz (#120257)
Pre-commit some tests in preparation to teach ValueTracking's
implied-cond about samesign.
2025-01-09 20:18:34 +00:00
adam-bzowski
088d636136
[ValueTracking] Fix a bug for signed min-max clamping (#121206)
Correctly handle the case where the clamp is over the full range.
This fixes an issue introduced in #121206.
2024-12-28 18:21:47 +01:00
adam-bzowski
6d7cf5206f
[ValueTracking] Improve KnownBits for signed min-max clamping (#120576)
A signed min-max clamp is the sequence of smin and smax intrinsics,
which constrain a signed value into the range: smin <= value <= smax.
The patch improves the calculation of KnownBits for a value subjected to
the signed clamping.
2024-12-25 22:39:56 +08:00
Nikita Popov
f7685af4a5 [InstCombine] Move gep of phi fold into separate function
This makes sure that an early return during this fold doesn't end
up skipping later gep folds.
2024-12-05 15:20:56 +01:00
Nikita Popov
462cb3cd6c
[InstCombine] Infer nusw + nneg -> nuw for getelementptr (#111144)
If the gep is nusw (usually via inbounds) and the offset is
non-negative, we can infer nuw.

Proof: https://alive2.llvm.org/ce/z/ihztLy
2024-12-05 14:36:40 +01:00
Ramkumar Ramachandra
fef6613e9f
ValueTracking: simplify udiv/urem recurrences (#108973)
A urem recurrence has the property that the result can never exceed the
start value. A udiv recurrence has the property that the result can
never exceed either the start value or the numerator, whichever is
greater. Implement a simplification based on these properties.
2024-11-07 11:41:35 +00:00
Ramkumar Ramachandra
abe0cd4621
ValueTracking: pre-commit udiv/urem recurrence tests (#109198) 2024-11-07 11:36:52 +00:00
Lee Wei
1469d82e1c
Remove br i1 undef from some regression tests [NFC] (#115130)
As defined in LangRef, branching on `undef` is undefined behavior.
This PR aims to remove undefined behavior from tests. As UB tests break
Alive2 and may be the root cause of breaking future optimizations.

Here's an Alive2 proof for one of the examples:
https://alive2.llvm.org/ce/z/TncxhP
2024-11-07 08:11:15 +00:00
Paul Walker
38fffa630e
[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548) 2024-11-06 11:53:33 +00:00
goldsteinn
877cb9a2ed
[KnownBits] Make {s,u}{add,sub}_sat optimal (#113096)
Changes are:
    1) Make signed-overflow detection optimal
    2) For signed-overflow, try to rule out direction even if we can't
       totally rule out overflow.
    3) Intersect add/sub assuming no overflow with possible overflow
       clamping values as opposed to add/sub without the assumption.
2024-11-05 09:03:37 -06:00
Ramkumar Ramachandra
cfa5ecde41
ValueTracking/test: cover recur limit in non-equal PHIs (#113205)
Add a test covering the recursion limit of isNonEqualPHIs.
2024-11-05 12:45:51 +00:00
Yingwei Zheng
f78610af3f
[InstCombine] Add function attribute instcombine-no-verify-fixpoint (#113822)
This patch introduces a function attribute
`instcombine-no-verify-fixpoint` to avoids disabling fix-point
verification for unrelated tests in the same file.
Address comment
https://github.com/llvm/llvm-project/pull/112642#discussion_r1804714387.
2024-10-28 17:45:08 +08:00
Yingwei Zheng
095d49da76
[InstCombine] Set samesign when converting signed predicates into unsigned (#112642)
Alive2: https://alive2.llvm.org/ce/z/6cqdt-
2024-10-17 20:43:48 +08:00
Ramkumar Ramachandra
3fee3e83a8
KnownBits: refine srem for high-bits (#109121)
KnownBits::srem does not correctly set the leader zero-bits, omitting
the fact that LHS may be known-negative or known-non-negative. Fix this.

Alive2 proof: https://alive2.llvm.org/ce/z/Ugh-Dq
2024-09-27 12:00:50 +01:00
Ramkumar Ramachandra
d781df2006
ValueTracking/test: cover known-high-bits of rem (#109006)
There is an underlying bug in KnownBits, and we should theoretically be
able to determine the high-bits of an srem as shown in the test, just
like urem. In preparation to fix this bug, add pre-commit tests testing
high-bits of srem and urem.
2024-09-26 16:08:51 +01:00
Ramkumar Ramachandra
f25b09199a
ValueTracking/test: increase recurrence coverage (#108836)
The shift-recurrence-knownbits.ll test file only covers shift
instructions while testing recurrence patterns with knownbits. Add tests
for add, sub, mul, and, and or as well, and rename the file
recurrence-knownbits.ll.
2024-09-17 09:03:02 +01:00
Nikita Popov
a105877646
[InstCombine] Remove some of the complexity-based canonicalization (#91185)
The idea behind this canonicalization is that it allows us to handle less
patterns, because we know that some will be canonicalized away. This is
indeed very useful to e.g. know that constants are always on the right.

However, this is only useful if the canonicalization is actually
reliable. This is the case for constants, but not for arguments: Moving
these to the right makes it look like the "more complex" expression is
guaranteed to be on the left, but this is not actually the case in
practice. It fails as soon as you replace the argument with another
instruction.

The end result is that it looks like things correctly work in tests,
while they actually don't. We use the "thwart complexity-based
canonicalization" trick to handle this in tests, but it's often a
challenge for new contributors to get this right, and based on the
regressions this PR originally exposed, we clearly don't get this right
in many cases.

For this reason, I think that it's better to remove this complexity
canonicalization. It will make it much easier to write tests for
commuted cases and make sure that they are handled.
2024-08-21 12:02:54 +02:00
Bjorn Pettersson
098bd842a7 [ValueTracking] Let ComputeKnownSignBits handle (shl (zext X), C) (#97693)
Add simple support for looking through a zext when doing
ComputeKnownSignBits for shl. This is valid for the case when
all extended bits are shifted out, because then the number of sign
bits can be found by analysing the zext operand.

The solution here is simple as it only handle a single zext (not
passing remaining left shift amount during recursion). It could be
possible to generalize this in the future by for example passing an
'OffsetFromMSB' parameter to ComputeNumSignBitsImpl, telling it to
calculate number of sign bits starting at some offset from the most
significant bit.
2024-07-19 12:44:47 +02:00
Bjorn Pettersson
812694c449 [ValueTracking] Pre-commit ComputeNumSignBits test for (shl (zext X), C)
Adding a test case for potential simplifications of
  (shl (zext X), C)
based on number of known sign bits in X.
2024-07-19 12:44:46 +02:00
Noah Goldstein
0589762e4e [ValueTracking] Consistently propagate DemandedElts is computeKnownFPClass
Closes #99080
2024-07-18 16:38:00 +08:00
Noah Goldstein
72ff0499bb [ValueTracking] Consistently propagate DemandedElts is isKnownNonZero 2024-07-18 16:38:00 +08:00
Noah Goldstein
6ef970b65f [ValueTracking] Consistently propagate DemandedElts is computeKnownBits 2024-07-18 16:38:00 +08:00
Noah Goldstein
1dfbd07255 [ValueTracking] Add tests for llvm.vector.reverse with DemandedElts; NFC 2024-07-18 16:37:59 +08:00
Noah Goldstein
769952d72f [ValueTracking] Implement Known{Bits,NonZero,FPClass} for llvm.vector.reverse
`llvm.vector.reverse` preserves each of the elements and thus elements
common to them.

Alive2 doesn't support the intrin yet, but the logic seems pretty
self-evident.

Closes #99013
2024-07-17 02:48:09 +08:00
Noah Goldstein
41b876dba4 [ValueTracking] Add tests for Known{Bits,NonZero,FPClass} for llvm.vector.reverse; NFC 2024-07-17 02:48:09 +08:00
mskamp
b22fa9093b
[ValueTracking][X86] Compute KnownBits for phadd/phsub (#92429)
Add KnownBits computations to ValueTracking and X86 DAG lowering.
    
These instructions add/subtract adjacent vector elements in their operands. Example: phadd [X1, X2] [Y1, Y2] = [X1 + X2, Y1 + Y2]. This means that, in this example, we can compute the KnownBits of the operation by computing the KnownBits of [X1, X2] + [X1, X2] and [Y1, Y2] + [Y1, Y2] and intersecting the results. This approach also generalizes to all x86 vector types.
    
There are also the operations phadd.sw and phsub.sw, which perform saturating addition/subtraction. Use sadd_sat and ssub_sat to compute the KnownBits of these operations.
    
Also adjust the existing test case pr53247.ll because it can be transformed to a constant using the new KnownBits computation.
    
Fixes #82516.
2024-07-16 15:50:21 +01:00
Nikita Popov
05670b42f5 [InstCombine] Remove root special case in demanded bits simplification
When calling SimplifyDemandedBits (as opposed to
SimplifyDemandedInstructionBits), and there are multiple uses,
always use SimplifyMultipleUseDemandedBits and drop the special
case for root values.

This fixes the ephemeral value detection, as seen by the restored
assumes in tests. It may result in more or less simplification,
depending on whether we get more out of having demanded bits or
the ability to perform non-multi-use transforms. The change in
the phi-known-bits.ll test is because the icmp operand now gets
simplified based on demanded bits, which then prevents a different
known bits simplification later.

This also makes the code safe against future changes like
https://github.com/llvm/llvm-project/pull/97289, which add more
context that would have to be discarded for the multi-use case.
2024-07-02 11:14:36 +02:00
Noah Goldstein
5532ab1732 [InstCombine] Make the (icmp eq/ne (and X, Y), X) canonicalization work for non-const operands
We currently do:
    `(icmp eq/ne (and X, Y), Y)` -> `(icmp eq/ne (and ~X, Y), 0)`
if `X` is constant. We can make this more general and do it if `X` is
freely invertable (i.e say `X = ~Z`).

As well, we can also do:
    `(icmp eq/ne (and X, Y), Y)` -> `(icmp eq/ne (or X, ~Y), -1)`
If `Y` is freely invertible.

Proofs: https://alive2.llvm.org/ce/z/yeWH3E

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

Closes #84688
2024-05-29 02:38:23 -05:00
Ralender
d46e37348e
[DebugCounter] Add support for non-continous ranges. (#89470) 2024-05-28 12:40:39 +02:00
Monad
fd0ffb7438
[ValueTracking] Recognize LShr(UINT_MAX, Y) + 1 as a power-of-two (#91171)
There is a missed optimization in
``` llvm
define i8 @known_power_of_two_rust_next_power_of_two(i8 %x, i8 %y) {
  %2 = add i8 %x, -1
  %3 = tail call i8 @llvm.ctlz.i8(i8 %2, i1 true)
  %4 = lshr i8 -1, %3
  %5 = add i8 %4, 1
  %6 = icmp ugt i8 %x, 1
  %p = select i1 %6, i8 %5, i8 1

  %r = urem i8 %y, %p
  ret i8 %r
}
```
which is extracted from the Rust code
``` rust
fn func(x: usize, y: usize) -> usize {
    let z = x.next_power_of_two();
    y % z
}
```
Here `%p` (a.k.a `z`) is semantically a power-of-two, so `y urem p` can
be optimized to `y & (p - 1)`. (Alive2 proof:
https://alive2.llvm.org/ce/z/H3zooY)

---

It could be generalized to recognizing `LShr(UINT_MAX, Y) + 1` as a
power-of-two, which is what this PR does.
Alive2 proof: https://alive2.llvm.org/ce/z/zUPTbc
2024-05-07 10:28:36 +09:00
Nikita Popov
74aa1abfae
[InstCombine] Canonicalize scalable GEPs to use llvm.vscale intrinsic (#90569)
Canonicalize getelementptr instructions for scalable vector types into
ptradd representation with an explicit llvm.vscale call. This
representation has better support in BasicAA, which can reason about
llvm.vscale, but not plain scalable GEPs.
2024-05-01 14:53:43 +09:00
Noah Goldstein
b933c8447b [ValueTracking] Add support for trunc nuw/nsw in isKnowNonZero
With `nsw`/`nuw`, the `trunc` is non-zero if its operand is non-zero.

Proofs: https://alive2.llvm.org/ce/z/iujmk6

Closes #89643
2024-04-24 02:53:11 -05:00
Noah Goldstein
b3ca9c30de [ValueTracking] Add tests for isKnowNonZero of trunc nuw/nsw; NFC 2024-04-24 02:53:11 -05:00
Andreas Jonson
e66cfebb04
[ValueTracking] Handle range attributes (#85143)
Handle the range attribute in ValueTracking.
2024-03-20 12:43:00 +01:00
Nikita Popov
6872a64652 [ValueTracking] Handle vector range metadata in isKnownNonZero()
Nowadays !range can be placed on instructions with vector of int
return value. Support this case in isKnownNonZero().
2024-03-19 15:50:13 +01:00
Nikita Popov
0e76818672 [ValueTracking] Test isKnownNonZero() range metadata with vector (NFC) 2024-03-19 15:50:13 +01:00
Noah Goldstein
744a23f24b [ValueTracking] Use select condition to help infer bits of arms
If we have something like `(select (icmp ult x, 8), x, y)`, we can use
the `(icmp ult x, 8)` to help compute the knownbits of `x`.

Closes #84699
2024-03-13 14:27:05 -05:00
Noah Goldstein
882992a951 [ValueTracking] Add tests for inferring select arm bits from condition; NFC 2024-03-13 14:27:05 -05:00
Noah Goldstein
d81db0e5f5 [KnownBits] Implement knownbits lshr/ashr with exact flag
The exact flag basically allows us to set an upper bound on shift
amount when we have a known 1 in `LHS`.

Typically we deduce exact using knownbits (on non-exact incoming
shifts), so this is particularly impactful, but may be useful in some
circumstances.

Closes #84254
2024-03-11 15:51:07 -05:00
Noah Goldstein
f19d9e1617 [KnownBits] Add test for computing more information for lshr/ashr with exact flag; NFC 2024-03-11 15:51:06 -05:00
Noah Goldstein
db3bbe03f1 [Analysis] Unify most of the tracking between AssumptionCache and DomConditionCache
This helps cover some missing cases in both and hopefully serves as
creating an easier framework for extending general condition based
analysis.

Closes #83161
2024-03-04 16:53:27 -06:00
Noah Goldstein
9facaaddad [ValueTracking] Improve tracking for constant range of {s|u}rem C, x
Current we only support `C` as the remainder, but we can also limit
with a constant numerator.

Proofs: https://alive2.llvm.org/ce/z/QB95gU

Closes #82303
2024-02-20 10:39:34 -06:00
Noah Goldstein
aa7076fc9b [ValueTracking] Add tests for constant range of {s|u}rem C, x; NFC 2024-02-20 10:39:33 -06:00
Yingwei Zheng
50e80e06d1
[ValueTracking] Merge cannotBeOrderedLessThanZeroImpl into computeKnownFPClass (#76360)
This patch merges the logic of `cannotBeOrderedLessThanZeroImpl` into
`computeKnownFPClass` to improve the signbit inference.

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2024-01-31 18:26:50 +08:00