1597 Commits

Author SHA1 Message Date
Craig Topper
88305251fe
[ConstantFolding] Add constant folding for scalable vector interleave intrinsics. (#168668)
We can constant fold interleave of identical splat vectors to a larger
splat vector.
2025-11-19 15:50:36 -08:00
Craig Topper
90ea49a9d1
[ConstantFolding] Generalize constant folding for vector_deinterleave2 to deinterleave3-8. (#168640) 2025-11-19 14:27:34 -08:00
Craig Topper
d2c7c60642 [InstSimplify] Add whitespace to struct declarations in vector-calls.ll. NFC
This matches how IR is printed.
2025-11-19 11:04:31 -08:00
Craig Topper
4ab24235cb
[ConstantFolding] Generalize constant folding for vector_interleave2 to interleave3-8. (#168473) 2025-11-18 11:13:15 -08:00
Paul Walker
f2b5d04f29
[LLVM][InstSimplify] Add folds for SVE integer reduction intrinsics. (#167519)
[andv, eorv, orv, s/uaddv, s/umaxv, s/uminv]
sve_reduce_##(none, ?) -> op's neutral value
sve_reduce_##(any, neutral) -> op's neutral value
    
[andv, orv, s/umaxv, s/uminv]
sve_reduce_##(all, splat(X)) -> X
    
[eorv]
sve_reduce_##(all, splat(X)) -> 0
2025-11-18 14:33:43 +00:00
Igor Gorban
dd7a000a31
[InstSimplify] Fix crash when optimizing minmax with bitcast constant vectors (#168055)
When simplifying min/max intrinsics with fixed-size vector constants,
InstructionSimplify attempts to optimize element-wise. However,
getAggregateElement() can return null for certain constant expressions
like bitcasts, leading to a null pointer dereference.

This patch adds a check to bail out of the optimization when
getAggregateElement() returns null, preventing the crash while
maintaining correct behavior for normal constant vectors.

Fixes crash with patterns like:
  call <2 x half> @llvm.minnum.v2f16(<2 x half> %x,
<2 x half> bitcast (<1 x i32> <i32 N> to <2 x half>))
2025-11-15 03:05:30 +08:00
Paul Walker
96c6fd36c1
[LLVM][ConstantFolding] Extend constantFoldVectorReduce to include scalable vectors. (#165437) 2025-10-31 11:14:08 +00:00
Paul Walker
16f61ac234 Extend vector reduction constants folding tests to include scalable vectors. 2025-10-28 15:57:39 +00:00
Nikita Popov
ec26f219ac
[InstSimplify] Support ptrtoaddr in simplifyGEPInst() (#164262)
This adds support for ptrtoaddr in the `ptradd p, ptrtoaddr(p2) -
ptrtoaddr(p) -> p2` fold.

This fold requires that p and p2 have the same underlying object
(otherwise the provenance may not be the same).

The argument I would like to make here is that because the underlying
objects are the same (and the pointers in the same address space), the
non-address bits of the pointer must be the same. Looking at some
specific cases of underlying object relationship:

 * phi/select: Trivially true.
* getelementptr: Only modifies address bits, non-address bits must
remain the same.
* addrspacecast round-trip cast: Must preserve all bits because we
optimize such round-trip casts away.
* non-interposable global alias: I'm a bit unsure about this one, but I
guess the alias and the aliasee must have the same non-address bits?
* various intrinsics like launder.invariant.group, ptrmask. I think
these all either preserve all pointer bits (like the invariant.group
ones) or at least the non-address bits (like ptrmask). There are some
interesting cases like amdgcn.make.buffer.rsrc, but those are cross
address-space.

-----

There is a second `gep (gep p, C), (sub 0, ptrtoint(p)) -> C` transform
in this function, which I am not extending to handle ptrtoaddr, adding
negative tests instead. This transform is overall dubious for provenance
reasons, but especially dubious with ptrtoaddr, as then we don't have
the guarantee that provenance of `p` has been exposed.
2025-10-21 09:27:07 +02:00
Nikita Popov
2e7afb1170 [InstCombine] Move ptrtoaddr tests to InstSimplify (NFC)
All the existing tests test code either in ConstantFolding or
InstSimplify, so move them to use -passes=instsimplify instead of
-passes=instcombine. This makes sure we keep InstSimplify coverage
even if there are subsuming InstCombine folds.

This requires writing some of the constant folding tests in a
different way, as InstSimplify does not try to re-fold already
existing constant expressions.
2025-10-20 14:39:40 +02:00
Cullen Rhodes
5b5eacc579
[ValueTracking] Teach isGuaranteedNotToBeUndefOrPoison about splats (#163570)
Splats include two poison values, but only the poison-ness of the
splatted value actually matters.
2025-10-20 11:20:09 +01:00
Paul Walker
d17d32a6cb
[LLVM][ConstProp] Enable intrinsic simplifications for vector ConstantInt based operands. (#159358)
Simplifcation of vector.reduce intrinsics are prevented by an early
bailout for ConstantInt base operands. This PR removes the bailout and
updates the tests to show matching output when
-use-constant-int-for-*-splat is used.
2025-10-17 13:43:00 +01:00
Nikita Popov
cf3765752b [InstSimplify] Support ptrtoaddr in ptrmask fold
Treat it the same way as ptrtoint. ptrmask only operates on the
address bits of the pointer.
2025-10-14 13:55:04 +02:00
Nikita Popov
261580cacd
[InstSimplify] Support non-inbounds GEP in ptrdiff fold (#162676)
We can fold ptrdiff(ptradd(p, x), p) to x regardless of whether the
ptradd is inbounds.

Proof: https://alive2.llvm.org/ce/z/Xuvc7N
2025-10-10 08:03:25 +00:00
Nikita Popov
c06005cce5 [InstSimplify] Clean up naming in ptr diff test (NFC)
Turns out there already was a test for the non-inbounds variant,
so remove the duplicate. Rename the tests to be more meaningful.
Drop irrelevant target triple.
2025-10-09 17:06:40 +02:00
Nikita Popov
e0c47d58f8 [InstSimplify] Add test for ptr diff without inbounds (NFC)
Also regenerate the test in current format.
2025-10-09 17:00:40 +02:00
Nikita Popov
7e5bb1e58a
[IR] Require DataLayout for pointer cast elimination (#162279)
isEliminableCastPair() currently tries to support elimination of
ptrtoint/inttoptr cast pairs by assuming that the maximum possible
pointer size is 64 bits. Of course, this is no longer the case nowadays.

This PR changes isEliminableCastPair() to accept an optional DataLayout
argument, which is required to eliminate pointer casts.

This means that we no longer eliminate these cast pairs during ConstExpr
construction, and instead only do it during DL-aware constant folding.
This had a lot of annoying fallout on tests, most of which I've
addressed in advance of this change.
2025-10-07 17:19:48 +02:00
Lewis Crawford
17efa572c3
[InstSimplify] Optimize maximumnum and minimumnum (#139581)
Add support for the new maximumnum and minimumnum intrinsics in various
optimizations in InstSimplify.

Also, change the behavior of optimizing maxnum(sNaN, x) to simplify to
qNaN instead of x to better match the LLVM IR spec, and add more tests
for sNaN behavior for all 3 max/min intrinsic types.
2025-10-07 14:23:32 +01:00
Nikita Popov
f2de174ef9 [InstSimplify] Add test for incorrect handling of wide pointers (NFC)
The intermediate integer type is too small to hold the full value.
2025-10-07 14:55:23 +02:00
Yingwei Zheng
ca5ece8939
[InstSimplify] Simplify fcmp implied by dominating fcmp (#161090)
This patch simplifies an fcmp into true/false if it is implied by a
dominating fcmp.
As an initial support, it only handles two cases:
+ `fcmp pred1, X, Y -> fcmp pred2, X, Y`: use set operations.
+ `fcmp pred1, X, C1 -> fcmp pred2, X, C2`: use `ConstantFPRange` and
set operations.

Note: It doesn't fix https://github.com/llvm/llvm-project/issues/70985,
as the second fcmp in the motivating case is not dominated by the edge.
We may need to adjust JumpThreading to handle this case.

Comptime impact (~+0.1%):
https://llvm-compile-time-tracker.com/compare.php?from=a728f213c863e4dd19f8969a417148d2951323c0&to=8ca70404fb0d66a824f39d83050ac38e2f1b25b9&stat=instructions:u
IR diff: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2848
2025-10-05 16:15:51 +08:00
Lewis Crawford
25c0da8b0d
[NVPTX] Fix NaN + overflow semantics of f2ll/d2i (#159530)
Fix the NaN-handling semantics of various NVVM intrinsics converting
from fp types to integer types.

Previously in ConstantFolding, NaN inputs would be constant-folded to 0.
However, v9.0 of the PTX spec states that:

In float-to-integer conversions, depending upon conversion types, NaN
input results in following value:
 * Zero if source is not `.f64` and destination is not `.s64`, .`u64`.
* Otherwise `1 << (BitWidth(dst) - 1)` corresponding to the value of
`(MAXINT >> 1) + 1` for unsigned type or `MININT` for signed type.

Also, support for constant-folding +/-Inf and values which
overflow/underflow the integer output type has been added (they clamp to
min/max int).

Because of this NaN-handling semantic difference, we also need to
disable transforming several intrinsics to FPToSI/FPToUI, as the LLVM
intstruction will return poison, but the intrinsics have defined
behaviour for these edge-cases like NaN/Inf/overflow.
2025-09-25 16:19:11 +01:00
Lewis Crawford
a7f5abbe73
[NFC][InstSimplify] Refactor fminmax-folds.ll test (#160504)
Refactor all the tests in `fminmax-folds.ll` so that they are grouped by
optimization, rather than by intrinsic.

Instead of calling 1 intrinsic per function, each function now tests all
6 variants of the intrinsic. Results are stored to named pointers to
maintain readability in this more compact form. This makes it much
easier to compare the outputs from each intrinsic, rather than having
them scattered in different functions in different parts of the file. It
is also much more compact, so despite adding >50% more tests, the file
is ~500 lines shorter.

The tests added include:
* Adding `maximumnum` and `minimumnum` everywhere (currently not
optimized, but added as a baseline for future optimizations in #139581).
* Adding separate tests for SNaN and QNaN (as a baseline for correctness
improvements in #139581 )
 * Adding tests for scalable vectors
* Increasing the variety of types used in various tests by using more
f16, f64, and vector types in tests.

The only coverage removed is for tests with undef (only poison is now
tested for).

Overall, this refactor should increase coverage, improve readability
with more comments and clear section headers, and make the tests much
more compact and easier to review in #139581 by providing a clear
baseline for each intrinsic's current behaviour.
2025-09-25 11:11:21 +01:00
Matthew Devereau
819e6b2043
[InstSimplify] Consider vscale_range for get active lane mask (#160073)
Scalable get_active_lane_mask intrinsic calls can be simplified to i1
splat (ptrue) when its constant range is larger than or equal to the
maximum possible number of elements, which can be inferred from
vscale_range(x, y)
2025-09-24 11:35:15 +01:00
Alexander Richardson
fd81bd8b3e
[ConstantFolding] Avoid use of isNonIntegralPointerType()
Avoiding any new inttoptr is unnecessarily restrictive for "plain"
non-integral pointers, but it is important for unstable pointers and
pointers with external state. Fixes another test codegen regression
from https://github.com/llvm/llvm-project/pull/105735.

Reviewed By: nikic

Pull Request: https://github.com/llvm/llvm-project/pull/159959
2025-09-23 15:29:33 -07:00
Alexander Richardson
dde000a7d6
[DataLayout][LangRef] Split non-integral and unstable pointer properties
This commit adds finer-grained versions of isNonIntegralAddressSpace() and
isNonIntegralPointerType() where the current semantics prohibit
introduction of both ptrtoint and inttoptr instructions. The current
semantics are too strict for some targets (e.g. AMDGPU/CHERI) where
ptrtoint has a stable value, but the pointer has additional metadata.
Currently, marking a pointer address space as non-integral also marks it
as having an unstable bitwise representation (e.g. when pointers can be
changed by a copying GC). This property inhibits a lot of
optimizations that are perfectly legal for other non-integral pointers
such as fat pointers or CHERI capabilities that have a well-defined
bitwise representation but can't be created with only an address.

This change splits the properties of non-integral pointers and allows
for address spaces to be marked as unstable or non-integral (or both)
independently using the 'p' part of the DataLayout string.
A 'u' following the p marks the address space as unstable and specifying
a index width != representation width marks it as non-integral.
Finally, we also add an 'e' flag to mark pointers with external state
(such as the CHERI capability validity) state. These pointers require
special handling of loads and stores in addition to being non-integral.

This does not change the checks in any of the passes yet - we
currently keep the existing non-integral behaviour. In the future I plan
to audit calls to DL.isNonIntegral[PointerType]() and replace them with
the DL.mustNotIntroduce{IntToPtr,PtrToInt}() checks that allow for more
optimizations.

RFC: https://discourse.llvm.org/t/rfc-finer-grained-non-integral-pointer-properties/83176

Reviewed By: nikic, krzysz00

Pull Request: https://github.com/llvm/llvm-project/pull/105735
2025-09-23 11:16:47 -07:00
Paul Walker
1773341f2c [NFC] Regenerate checks - llvm/test/Transforms/InstSimplify/ConstProp/bswap.ll 2025-09-17 10:20:59 +00:00
David Sherwood
1f49c9494e
[InstSimplify] Simplify get.active.lane.mask when 2nd arg is zero (#158018)
When the second argument passed to the get.active.lane.mask intrinsic is
zero we can simplify the instruction to return an all-false mask
regardless of the first operand.
2025-09-12 10:39:29 +01:00
Florian Hahn
607a813029
[ConstFold] Don't crash on ConstantExprs when folding get_active_lane_m.
Check if operands are ConstantInt to avoid crashing on constant
expression after https://github.com/llvm/llvm-project/pull/156659.
2025-09-11 23:17:56 +01:00
Matthew Devereau
75099c2246
[ConstantFolding] Fold scalable get_active_lane_masks (#156659)
Scalable get_active_lane_mask intrinsics with a range of 0 can be
lowered to zeroinitializer. This helps remove no-op scalable masked
stores and loads.
2025-09-11 10:53:18 +01:00
Aaditya
bdebbd9015
[AMDGPU] Propagate Constants for Wave Reduction Intrinsics (#150395) 2025-09-10 20:13:30 +05:30
Florian Hahn
b50ad945dd
[InstSimplify] Simplify extractvalue (umul_with_overflow(x, 1)). (#157307)
Look through extractvalue to simplify umul_with_overflow where one of
the operands is 1.

This removes some redundant instructions when expanding SCEVs, which in
turn makes the runtime check cost estimate more accurate, reducing the
minimum iterations for which vectorization is profitable.

PR: https://github.com/llvm/llvm-project/pull/157307
2025-09-07 18:32:40 +01:00
Lewis Crawford
729701b885
[NVPTX] Constant fold NVVM add/mul/div/fma (#152544)
Constant fold the NVVM intrinsics for add, mul, div, fma with specific
rounding modes.
2025-08-22 17:33:00 +01:00
Jasmine Tang
10d9e7b1b7
Reapply "[WebAssembly] Constant fold wasm.dot" (#153070)
In #149619, for the test of `@dot_follow_modulo_spec_2`, constant
folding the addition of two i32 1073741824 causes an overflow from 2^32
to -2^32=-2147483648, which triggers the UB sanitizer. This PR reapplies
the previous PR, explicitly casting the addition operand to int64_t
first before performing the addition before producing a int32 number via
`Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned)`
2025-08-14 18:52:35 -07:00
Yingwei Zheng
d8b1b46cd3
[IR] Handle fabs LHS in fcmpImpliesClass (#152913)
Closes https://github.com/llvm/llvm-project/issues/152824.
2025-08-10 22:55:04 +08:00
Andrew Lazarev
f61526971f
Revert "[WebAssembly] Constant fold wasm.dot" (#152382)
Reverts llvm/llvm-project#149619

It breaks ubsan bot:
https://lab.llvm.org/buildbot/#/builders/25/builds/10523

Earlier today the failure was hidden by another breakage that is fixed
now.
2025-08-06 15:16:19 -07:00
Jasmine Tang
9c6bb18040
[WebAssembly] Constant fold wasm.dot (#149619)
Constant fold wasm.dot of constant vectors/splats.

Test case added in
`llvm/test/Transforms/InstSimplify/ConstProp/WebAssembly/dot.ll`

Related to https://github.com/llvm/llvm-project/issues/55933
2025-08-05 15:22:37 -07:00
Abhishek Kaushik
30728eb26b
[Reland][ValueTracking] Improve Bitcast handling to match SDAG (#145223)
Fixes #125228

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
2025-08-04 14:51:03 +05:30
Lewis Crawford
5146917407
[ConstantFolding] Fix incorrect nvvm_round folding (#151563)
The `nvvm_round` intrinsic should round to the nearest even number in
the case of ties. It lowers to PTX `cvt.rni`, which will "round to
nearest integer, choosing even integer if source is equidistant between
two integers", so it matches the semantics of `rint` (and not `round` as
the name suggests).
2025-08-01 10:31:43 +01:00
Nikita Popov
36961202fb [InstSimplify] Regenerate test checks (NFC)
Change the function name so that UTC works properly. Also move the
test into the InstCombine directory, as that's the pass that's
actually being tested.
2025-07-30 15:14:46 +02:00
Pedro Lobo
67658af1cc
[ConstantFolding] Merge constant gep inrange attributes (#150546)
When folding a gep+gep into a single gep, intersect their `inrange`
attributes.
2025-07-25 20:02:06 +01:00
Lewis Crawford
fd8ae2cb76
Add constant-folding for unary NVVM intrinsics (#141233)
Add support for constant-folding numerous NVVM unary arithmetic
intrinsics (including f, d, and ftz_f variants):
  - nvvm.ceil.*
  - nvvm.fabs.*
  - nvvm.floor.*
  - nvvm.rcp.*
  - nvvm.round.*
  - nvvm.saturate.*
  - nvvm.sqrt.f
  - nvvm.sqrt.rn.*
2025-07-21 11:32:09 +01:00
Jasmine Tang
e7ac49977a
[InstSimplify] Add poison propagation for trivially vectorizable intrinsics (#149243)
Fixes https://github.com/llvm/llvm-project/issues/146769

Test cases added to
`llvm/test/Transforms/InstSimplify/fold-intrinsics.ll`
2025-07-19 19:37:21 -07:00
jjasmine
2206c7d4af
[InstSimplify] Fold trig functions call of poison to poison (#148969)
Fold trig functions call of poison to poison.

This includes sin, cos, asin, acos, atan, atan2, sinh, cosh, sincos,
sincospi.

Test cases are fixed and also added to
llvm/test/Transforms/InstSimplify/fold-intrinsics.ll just like in
https://github.com/llvm/llvm-project/pull/146750
2025-07-16 08:35:13 -07:00
jjasmine
18286e0c2a
[WebAssembly] Constant fold SIMD intrinsics: any/alltrue (#148074)
Constant fold  SIMD wasm intrinsics: any/alltrue

Added test in `llvm/test/Transforms/InstSimplify`
2025-07-15 02:13:22 +08:00
jjasmine
07286b1fcd
[InstCombine] Propagate poison pow[i], [us]add, [us]sub and [us]mul (#146750)
Fixes #146560 as well as propagate poison for [us]add, [us]sub and
[us]mul
2025-07-04 22:55:07 +01:00
Nikita Popov
1d5d125648
[ConstantFolding] Consolidate poison propagation for intrinsics (#146878)
This consolidates the "fold poison arg to poison result" constant
folding logic for intrinsics, based on a common
intrinsicPropagatesPoison() helper, which is also used for poison
propagation reasoning in ValueTracking. This ensures that the set of
supported intrinsics is consistent.

This add ucmp, scmp, smul.fix, smul.fix.sat, canonicalize and sqrt to
the intrinsicPropagatesPoison list, as these were handled by
ConstantFolding but not ValueTracking. The ctpop test is an example of
the converse, where it was handled by ValueTracking but not
ConstantFolding.
2025-07-04 09:16:28 +02:00
Lei Huang
4a31f7f8ea
[ConstantFold] Special case atan +/-0.0 (#143962)
C's Annex F specifies that atan +/-0.0 returns the input value;
however, this behavior is optional and host C libraries may behave
differently. This change applies the Annex F behavior to constant
folding by LLVM.

Ref:
https://pubs.opengroup.org/onlinepubs/9799919799/functions/atan.html
2025-06-25 16:03:18 -04:00
Iris Shi
f51d8730b3
[InstSimplify] Simplify 'x u>= 1' to true when x is known non-zero (#145204) 2025-06-22 13:32:19 +08:00
Nikita Popov
80b79ce432
[ConstantFolding] Handle reading from type padding (#144330)
ReadDataFromGlobal() did not handle reads from the padding of types (in
the sense of type store size != type alloc size, rather than struct
padding).

Return zero in that case.

Fixes https://github.com/llvm/llvm-project/issues/144279.
2025-06-17 09:30:28 +02:00
Philip Reames
6f9cd79fa2
[InstSimplify] Add basic simplifications for vp.reverse (#144112)
Directly modeled after what we do for vector.reverse, but with
restrictions on EVL and mask added.
2025-06-16 10:07:56 -07:00