1472 Commits

Author SHA1 Message Date
Simon Pilgrim
11ba72e651
[KnownBits] Add KnownBits::add and KnownBits::sub helper wrappers. (#99468) 2024-08-12 10:21:28 +01:00
zhongyunde 00443407
2bd568fecc [ValueTracking] Infer relationship for the select with SLT 2024-08-06 10:30:04 +08:00
zhongyunde 00443407
3023713014 [ValueTracking] Infer relationship for the select with ICmp
x -nsw y < -C is false when x > y and C >= 0
Alive2 proof for sgt, sge : https://alive2.llvm.org/ce/z/tupvfi
Note: It only really makes sense in the context of signed comparison for
      "X - Y must be positive if X >= Y and no overflow".

Fixes https://github.com/llvm/llvm-project/issues/54735
2024-08-06 10:30:03 +08:00
Kazu Hirata
7df9da7d78
[llvm] Construct SmallVector with ArrayRef (NFC) (#101872) 2024-08-04 08:54:23 -07:00
Vitaly Buka
945dd9a740
[NFC][Load] Find better place for mustSuppressSpeculation (#100794)
And extract `suppressSpeculativeLoadForSanitizers`.

For #100639.
2024-07-29 10:29:02 -07:00
Yingwei Zheng
62e9f40949
[PatternMatch] Use m_SpecificCmp matchers. NFC. (#100878)
Compile-time improvement:
http://llvm-compile-time-tracker.com/compare.php?from=13996378d81c8fa9a364aeaafd7382abbc1db83a&to=861ffa4ec5f7bde5a194a7715593a1b5359eb581&stat=instructions:u
baseline: 803eaf29267c6aae9162d1a83a4a2ae508b440d3
```
Top 5 improvements:
  stockfish/movegen.ll 2541620819 2538599412 -0.12%
  minetest/profiler.cpp.ll 431724935 431246500 -0.11%
  abc/luckySwap.c.ll 581173720 580581935 -0.10%
  abc/kitTruth.c.ll 2521936288 2519445570 -0.10%
  abc/extraUtilTruth.c.ll 1216674614 1215495502 -0.10%
Top 5 regressions:
  openssl/libcrypto-shlib-sm4.ll 1155054721 1155943201 +0.08%
  openssl/libcrypto-lib-sm4.ll 1155054838 1155943063 +0.08%
  spike/vsm4r_vv.ll 1296430080 1297039258 +0.05%
  spike/vsm4r_vs.ll 1312496906 1313093460 +0.05%
  nuttx/lib_rand48.c.ll 126201233 126246692 +0.04%
Overall: -0.02112308%
```
2024-07-29 10:04:06 +08:00
Ramkumar Ramachandra
2754c083cb
LAA: mark LoopInfo pointer const (NFC) (#100373) 2024-07-24 16:52:11 +01:00
Yingwei Zheng
0c03b4ce10
[InstCombine] Infer sub nuw from dominating conditions (#100164)
Alive2: https://alive2.llvm.org/ce/z/g3xxnM
2024-07-24 23:39:30 +08:00
Yingwei Zheng
59eae919c9
[ValueTracking] Don't use CondContext in dataflow analysis of phi nodes (#100316)
See the following case:
```
define i16 @pr100298() {
entry:
  br label %for.inc

for.inc:
  %indvar = phi i32 [ -15, %entry ], [ %mask, %for.inc ]
  %add = add nsw i32 %indvar, 9
  %mask = and i32 %add, 65535
  %cmp1 = icmp ugt i32 %mask, 5
  br i1 %cmp1, label %for.inc, label %for.end

for.end:
  %conv = trunc i32 %add to i16
  %cmp2 = icmp ugt i32 %mask, 3
  %shl = shl nuw i16 %conv, 14
  %res = select i1 %cmp2, i16 %conv, i16 %shl
  ret i16 %res
}
```

When computing knownbits of `%shl` with `%cmp2=false`, we cannot use
this condition in the analysis of `%mask (%for.inc -> %for.inc)`.
 
Fixes https://github.com/llvm/llvm-project/issues/100298.
2024-07-24 20:06:36 +08:00
Nikita Popov
32cd18975d
[GVN] Look through select/phi when determining underlying object (#99509)
This addresses an optimization regression in Rust we have observed after
https://github.com/llvm/llvm-project/pull/82458. We now only perform
pointer replacement if they have the same underlying object. However,
getUnderlyingObject() by default only looks through linear chains, not
selects/phis. In particular, this means that we miss cases involving
involving pointer induction variables.

This patch fixes this by introducing a new helper
getUnderlyingObjectAggressive() which basically does what
getUnderlyingObjects() does, just specialized to the case where we must
arrive at a single underlying object in the end, and with a limit on the
number of inspected values.

Doing this more expensive underlying object check has no measurable
compile-time impact on CTMark.
2024-07-22 16:22:01 +02:00
AtariDreams
56ad7cc012
[IR] Remove non-canonical matchings (#96763) 2024-07-22 09:47:37 +02:00
Yingwei Zheng
248fcab2fc
[InstCombine] Do not use operand info in replaceInInstruction (#99492)
Consider the following case:
```
%cmp = icmp eq ptr %p, null
%load = load i32, ptr %p, align 4
%sel = select i1 %cmp, i32 %load, i32 0
```
`foldSelectValueEquivalence` converts `load i32, ptr %p, align 4` into
`load i32, ptr null, align 4`, which causes immediate UB. `%load` is
speculatable, but it doesn't hold after operand substitution.

This patch introduces a new helper
`isSafeToSpeculativelyExecuteWithVariableReplaced`. It ignores operand
info in these instructions since their operands will be replaced later.

Fixes #99436.

---------

Co-authored-by: Nikita Popov <github@npopov.com>
2024-07-22 11:59:54 +08: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
Noah Goldstein
c6144cb0de [ValueTracking] Remove unnecessary m_ElementWiseBitCast from isKnownNonZeroFromOperator; NFC 2024-07-18 17:02:13 +08:00
Noah Goldstein
0589762e4e [ValueTracking] Consistently propagate DemandedElts is computeKnownFPClass
Closes #99080
2024-07-18 16:38:00 +08:00
Noah Goldstein
e8eeda8e4d [ValueTracking] Consistently propagate DemandedElts is ComputeNumSignBits 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
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
Alexey Bataev
8ff233f4f1 [SLP]Correctly detect minnum/maxnum patterns for select/cmp operations on floats.
The patch enables detection of minnum/maxnum patterns for float point
instruction, represented as select/cmp. Also, enables better cost
estimation for integer min/max patterns since the compiler starts
to estimate the scalars separately.

Reviewers: nikic, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/98570
2024-07-16 09:42:08 -07: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
Alexey Bataev
c3540d0b6b Revert "[SLP]Correctly detect minnum/maxnum patterns for select/cmp operations on floats."
This reverts commit c7aac38c29f564bc48f7cfb71d3b3b8b482c873b to fix
crashes reavealed by the buildbot in https://lab.llvm.org/buildbot/#/builders/168/builds/1104.
2024-07-16 05:59:59 -07:00
Alexey Bataev
c7aac38c29
[SLP]Correctly detect minnum/maxnum patterns for select/cmp operations on floats.
The patch enables detection of minnum/maxnum patterns for float point
instruction, represented as select/cmp. Also, enables better cost
estimation for integer min/max patterns since the compiler starts
to estimate the scalars separately.

Reviewers: nikic, RKSimon

Reviewed By: RKSimon

Pull Request: https://github.com/llvm/llvm-project/pull/98570
2024-07-16 08:14:27 -04:00
Nikita Popov
d177a94fbd [IR] Add Constant::toConstantRange() (NFC)
The logic in llvm::getVectorConstantRange() can be a bit
inconvenient to use in some cases because of the need to handle
the scalar case separately. Generalize it to handle all constants,
and move it to live directly on Constant.
2024-07-05 16:51:49 +02:00
Simon Pilgrim
5c204b1d26 [ValueTracking][X86] computeKnownBitsFromOperator - add PMULH/PMULHU intrinsics mulhs/mulhu known bits handling.
These map directly to the KnownBits implementations.
2024-07-04 11:08:06 +01:00
Nikita Popov
ebab105670 [IR] Don't strip through pointer to vector of pointer bitcasts
When using stripPointerCasts() and getUnderlyingObject(), don't
strip through a bitcast from ptr to <1 x ptr>, which is not a
no-op pointer cast. Calling code is generally not prepared to
handle that situation, resulting in incorrect alias analysis
results for example.

Fixes https://github.com/llvm/llvm-project/issues/97600.
2024-07-04 09:47:59 +02:00
Nikita Popov
2dbb454791 [ValueTracking][LVI] Consolidate vector constant range calculation
Add a common helper used for computeConstantRange() and LVI. The
implementation is a mix of both, with the efficient handling for
ConstantDataVector taken from computeConstantRange(), and the
general handling (including non-splat poison) from LVI.
2024-07-03 15:19:26 +02:00
Noah Goldstein
7c96469ea8 [ValueTracking] Extend LHS/RHS with matching operand to work without constants.
Previously we only handled the `L0 == R0` case if both `L1` and `R1`
where constant.

We can get more out of the analysis using general constant ranges
instead.

For example, `X u> Y` implies `X != 0`.

In general, any strict comparison on `X` implies that `X` is not equal
to the boundary value for the sign and constant ranges with/without
sign bits can be useful in deducing implications.

Closes #85557
2024-07-03 20:18:51 +08:00
Nikita Popov
b58ae6bd27 [InstCombine] Sync KnownBits logic for select arms
Extract an adjustKnownBitsForSelectArm() helper for the
ValueTracking logic and make use of it in SimplifyDemandedBits().

This fixes a consistency violation under instcombine-verify-known-bits.
2024-07-01 15:52:20 +02:00
Nikita Popov
77eb056830
[InstCombine] Simplify select using KnownBits of condition (#95923)
Simplify the arms of a select based on the KnownBits implied by its condition.
For now this only handles the case where the select arm folds to a constant,
but this can be generalized to handle other patterns by using
SimplifyDemandedBits instead (in that case we would also have to limit to
non-undef conditions).

This is implemented by adding a new member to SimplifyQuery that can be used
to inject an additional condition. The affected values are pre-computed and
we don't call computeKnownBits() if the select arms don't contain affected
values. This reduces the cost in some pathological cases.
2024-07-01 09:26:01 +02:00
Matt Arsenault
1d27348e53 ValueTracking: Simplify intrinsic ID asserts 2024-06-30 07:58:51 +02:00
Nikita Popov
9df71d7673
[IR] Add getDataLayout() helpers to Function and GlobalValue (#96919)
Similar to https://github.com/llvm/llvm-project/pull/96902, this adds
`getDataLayout()` helpers to Function and GlobalValue, replacing the
current `getParent()->getDataLayout()` pattern.
2024-06-28 08:36:49 +02:00
Farzon Lotfi
918313d17d
[SLPVectorizer] Support SLPVectorizer cases of tan across all backends (#95517)
This PR is intended to address the limited SLPVectorizer support of tan
raised in the comments of this PR:
https://github.com/llvm/llvm-project/pull/94559.

Right now emitting the tan intrinsisic allows you to vectorize tan, but
emitting the libfunc does not. to address this the libcall needs to be
mapped to the intrinsic. and the libcall and function name need to be
marked approriately so they can be optimized or defined as a call
lowering.
2024-06-27 15:15:13 -04:00
Nikita Popov
2d209d964a
[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)
This is a helper to avoid writing `getModule()->getDataLayout()`. I
regularly try to use this method only to remember it doesn't exist...

`getModule()->getDataLayout()` is also a common (the most common?)
reason why code has to include the Module.h header.
2024-06-27 16:38:15 +02:00
Craig Topper
326ba38a99
[ValueTracking][RISCV] Use ConstantRange::getUnsignedMax instead of getUpper to simplify some code. (#96816)
This avoids the need to subtract 1 and explain why.
2024-06-26 17:30:19 -07:00
Poseydon42
ffec31566c
[InstSimplify] Provide information about the range of possible values that ucmp/scmp can return (#96410)
This makes it possible to fold dumb comparisons like `ucmp(x, y) == 7`.
2024-06-24 12:01:46 +08:00
Nikita Popov
6012de2b4e [ValueTracking] Support gep nuw in isKnownNonZero()
gep nuw can be null if and only if both the base pointer and offset
are null. Unlike the inbounds case this does not depend on whether
the null pointer is valid.

Proofs: https://alive2.llvm.org/ce/z/PLoqK5
2024-06-20 12:41:21 +02:00
Zain Jaffal
22ff7c5dc9
[ValueTracking][NFC] move isKnownInversion to ValueTracking (#95321)
I am using `isKnownInversion` in the following pr 
https://github.com/llvm/llvm-project/pull/94915

it is useful to have the method in a shared class so I can reuse it. I am not sure if `ValueTracking` is the correct place but it looks like most of the methods with the pattern `isKnownX` belong there.
2024-06-13 07:14:08 +01:00
c8ef
b25b1db819
[KnownBits] Remove hasConflict() assertions (#94568)
Allow KnownBits to represent "always poison" values via conflict.

close: #94436
2024-06-07 17:01:22 +02:00
Nikita Popov
16e2ec82ac [ValueTracking] Make undef element check more precise
If we're only checking for undef, then also only look for undef
elements in the vector (rather than undef and poison).
2024-06-06 09:39:33 +02:00
Ahmed Bougacha
0edc97f119
[IR][AArch64][PAC] Add "ptrauth(...)" Constant to represent signed pointers. (#85738)
This defines a new kind of IR Constant that represents a ptrauth signed
pointer, as used in AArch64 PAuth.

It allows representing most kinds of signed pointer constants used thus
far in the llvm ptrauth implementations, notably those used in the
Darwin and ELF ABIs being implemented for c/c++.  These signed pointer
constants are then lowered to ELF/MachO relocations.

These can be simply thought of as a constant `llvm.ptrauth.sign`, with
the interesting addition of discriminator computation: the `ptrauth`
constant can also represent a combined blend, when both address and
integer discriminator operands are used.  Both operands are otherwise
optional, with default values 0/null.
2024-05-28 16:39:09 -07:00
Noah Goldstein
2232843160 [ValueTracking] Recognize X op (X != 0) as non-zero
The ops supported are: `add`, `sub`, `xor`, `or`, `umax`, `uadd.sat`

Proofs: https://alive2.llvm.org/ce/z/8ZMSRg

The `add` case actually comes up in SPECInt, the rest are here mostly
for completeness.

Closes #88579
2024-05-20 15:25:40 -05:00
Yingwei Zheng
04ae6e600a
[ValueTracking] Fix incorrect inferrence about the signbit of sqrt (#92510)
According to IEEE Std 754-2019, `sqrt` returns nan when the input is
negative (except for -0). In this case, we cannot make assumptions about
sign bit of the result.

Fixes https://github.com/llvm/llvm-project/issues/92217
2024-05-20 21:52:38 +08:00
Matt Arsenault
0cd2bf3521
ValueTracking: Correct undef handling for constant FP vectors (#92557)
Treat undef as unknown, and poison as ignorable.
2024-05-19 20:56:21 +02:00
Noah Goldstein
05347f8c2f [ValueTracking] Compute knownbits from (icmp upred (add/sub nuw X, Y), C)
`(icmp ule/ult (add nuw X, Y), C)` implies both `(icmp ule/ult X, C)` and
`(icmp ule/ult Y, C)`. We can use this to deduce leading zeros in `X`/`Y`.

`(icmp uge/ugt (sub nuw X, Y), C)` implies `(icmp uge/uge X, C)` . We
can use this to deduce leading ones in `X`.

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

Closes #87180
2024-05-16 13:03:32 -05:00
Yingwei Zheng
46bc54f4e6
[ValueTracking] Fix assertion failure when computeKnownFPClass returns fcNone (#92355)
Fixes
https://github.com/llvm/llvm-project/pull/92084#issuecomment-2114083188.
2024-05-16 19:14:30 +08:00
Yingwei Zheng
3aae916ff7
Reland "[ValueTracking] Compute knownbits from known fp classes" (#92084)
This patch relands https://github.com/llvm/llvm-project/pull/86409.

I mistakenly thought that `Known.makeNegative()` clears the sign bit of
`Known.Zero`. This patch fixes the assertion failure by explicitly
clearing the sign bit.
2024-05-14 18:10:28 +08:00
Martin Storsjö
2e165a2c4b Revert "[ValueTracking] Compute knownbits from known fp classes (#86409)"
This reverts commit d03a1a6e5838c7c2c0836d71507dfdf7840ade49.

This change caused failed assertions, see
https://github.com/llvm/llvm-project/pull/86409#issuecomment-2109469845
for details.
2024-05-14 10:37:23 +03:00
Yingwei Zheng
d03a1a6e58
[ValueTracking] Compute knownbits from known fp classes (#86409)
This patch calculates knownbits from fp instructions/dominating fcmp
conditions. It will enable more optimizations with signbit idioms.
2024-05-14 01:58:45 +08: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