1528 Commits

Author SHA1 Message Date
Luke Lau
9a5b0f302b
Reapply "[InstCombine] Match scalable splats in m_ImmConstant (#132522)" (#134262)
This reapplies #132522.

Previously casts of scalable m_ImmConstant splats weren't being folded
by ConstantFoldCastOperand, triggering the "Constant-fold of ImmConstant
should not fail" assertion.

There are no changes to the code in this PR, instead we just needed
#133207 to land first.

A test has been added for the assertion in
llvm/test/Transforms/InstSimplify/vec-icmp-of-cast.ll
@icmp_ult_sext_scalable_splat_is_true.

<hr/>

#118806 fixed an infinite loop in FoldShiftByConstant that could occur
when the shift amount was a ConstantExpr.

However this meant that FoldShiftByConstant no longer kicked in for
scalable vectors because scalable splats are represented by
ConstantExprs.

This fixes it by allowing scalable splats of non-ConstantExprs in
m_ImmConstant, which also fixes a few other test cases where scalable
splats were being missed.

But I'm also hoping that UseConstantIntForScalableSplat will eventually
remove the need for this.

I noticed this when trying to reverse a combine on RISC-V in #132245,
and saw that the resulting vector and scalar forms were different.
2025-04-03 18:03:16 +01:00
Luke Lau
79435de8a5
[ConstantFold] Support scalable constant splats in ConstantFoldCastInstruction (#133207)
Previously only fixed vector splats were handled. This adds supports for
scalable vectors too by allowing ConstantExpr splats.

We need to add the extra V->getType()->isVectorTy() check because a
ConstantExpr might be a scalar to vector bitcast.

By allowing ConstantExprs this also allow fixed vector ConstantExprs to
be folded, which causes the diffs in
llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll
and llvm/test/Transforms/InstSimplify/ConstProp/cast-vector.ll. I can
remove them from this PR if reviewers would prefer.

Fixes #132922
2025-04-03 16:24:56 +01:00
Iris
3295970d84
[ConstantFolding] Add support for sinh and cosh intrinsics in constant folding (#132671)
Closes #132503.
2025-04-03 08:34:09 +02:00
Nikita Popov
8758e5fe47
[ConstantFolding] Fix handling of index width != pointer width (#130608)
Per LangRef:

> The offsets are then added to the low bits of the base address up to
the index type width, with silently-wrapping two’s complement
arithmetic. If the pointer size is larger than the index size, this
means that the bits outside the index type width will not be affected.

The transform as implemented was doubly wrong, because it just truncated
the original base pointer to the index width, losing the top bits
entirely. Make sure we preserve the bits and use wrapping arithmetic
within the low bits.
2025-03-11 09:02:34 +01:00
Yingwei Zheng
029e10289a
[ValueTracking] Bail out on x86_fp80 when computing fpclass with knownbits (#130477)
In https://github.com/llvm/llvm-project/pull/97762, we assume the
minimum possible value of X is NaN implies X is NaN. But it doesn't hold
for x86_fp80 format. If the knownbits of X are
`?'011111111111110'????????????????????????????????????????????????????????????????`,
the minimum possible value of X is NaN/unnormal. However, it can be a
normal value.

Closes https://github.com/llvm/llvm-project/issues/130408.
2025-03-09 21:10:35 +08:00
Veera
bc35510725
[InstSimplify] Fold X * C >= X to true (#129352)
Proof: https://alive2.llvm.org/ce/z/T_ocLy

Discovered in: https://github.com/rust-lang/rust/issues/114386

This PR folds `X * C >= X` to `true` when `C` is known to be non-zero
and `mul` is `nuw`.

Folds for other math operators exist already:
https://llvm-ir.godbolt.org/z/GKcYEf5Kb
2025-03-01 12:02:57 -05:00
Paul Walker
28cf323e87 [LLVM] Port a few InstCombine tests to use splat instead of shufflevector. 2025-02-26 11:11:02 +00:00
Andreas Jonson
692db7403b [ValueTracking] Precommit test for #118406 2025-02-04 22:53:33 +01:00
Yingwei Zheng
1af627b592
[InstSimplify] Add additional checks when substituting pointers (#125385)
Compile-time impact:
https://llvm-compile-time-tracker.com/compare.php?from=d09b521624f263b5f1296f8d4771836b97e600cb&to=e437ba2cb83bb965e13ef00727671896f03ff84f&stat=instructions:u
IR diff looks acceptable.
Closes https://github.com/llvm/llvm-project/issues/115574
2025-02-02 19:04:23 +08:00
Andreas Jonson
9399a1ddb8
[InstSimplify] Handle trunc to i1 in Select with bit test folds. (#122944)
Proof: https://alive2.llvm.org/ce/z/Jncqb2
2025-02-01 08:48:32 +01:00
Florian Hahn
55815b621b
[Value] Look through inttoptr (add ..) in accumulateConstantOffsets (#124981)
Look through inttoptr (add (ptrtoint P), C) when accumulating offsets.

Adds a missing fold after
https://github.com/llvm/llvm-project/pull/123518

Alive2 for the tests with changes: https://alive2.llvm.org/ce/z/VvPrzv

PR: https://github.com/llvm/llvm-project/pull/124981
2025-01-30 20:58:38 +00:00
Florian Hahn
56ad54260c [InstSimplify] Add tests with inttoptr (add ..) ConstExprs.
Precommit tests for https://github.com/llvm/llvm-project/pull/124981.
2025-01-30 12:39:08 +00:00
Yingwei Zheng
f226cabbb1
[ValueTracking] Handle nonnull attributes at callsite (#124908)
Alive2: https://alive2.llvm.org/ce/z/yJfskv
Closes https://github.com/llvm/llvm-project/issues/124540.
2025-01-29 23:14:36 +08:00
Kshitij Paranjape
19bd2d6102
[ConstantFolding] Add ilogb in isMathLibCallNoop (#122582)
ilogb libcall was not being constant folded correctly. This patch adds 
ilogb case in isMathLibCallNoop with correct error condition.

Fixes #101873
2025-01-20 12:19:07 -05:00
Lewis Crawford
cea92446ac
[NVPTX] Constant fold NVVM fmin and fmax (#121966)
Add constant-folding for nvvm float/double fmin + fmax intrinsics,
including all combinations of xorsign.abs, nan-propagation, and ftz.
2025-01-16 14:38:51 +00:00
Andreas Jonson
cd264f09a4 [InstSimplify] Test select bit test with trunc to i1 (NFC) 2025-01-13 23:52:23 +01:00
goldsteinn
17ef436e3d
[ValueTracking] Take into account whether zero is poison when computing CR for ct{t,l}z (#122548) 2025-01-11 15:11:11 -06:00
goldsteinn
cc995ad064
[InstSimpify] Simplifying (xor (sub C_Mask, X), C_Mask) -> X (#122552)
- **[InstSimpify] Add tests for simplifying `(xor (sub C_Mask, X),
C_Mask)`; NFC**
- **[InstSimpify] Simplifying `(xor (sub C_Mask, X), C_Mask)` -> `X`**

Helps address regressions with folding `clz(Pow2)`.

Proof: https://alive2.llvm.org/ce/z/zGwUBp
2025-01-11 15:10:42 -06:00
Lewis Crawford
a629d9e102
[NVPTX] Constant-folding for f2i, d2ui, f2ll etc. (#118965)
Add constant-folding support for the NVVM intrinsics for converting
float/double to signed/unsigned int32/int64 types, including all
rounding-modes and ftz modifiers.
2025-01-07 13:17:36 +00:00
Nikita Popov
7c135e17fb
[InstSimplify] Treat float binop with identity as refining (#120098)
If x is NaN, then fmul (x, 1) may produce a different NaN value.

Our float semantics explicitly permit folding fmul (x, 1) to x, but we
can't do this when we're replacing a select input, as selects are
supposed to preserve the exact bitwise value.

Fixes
https://github.com/llvm/llvm-project/pull/115152#issuecomment-2545773114.
2024-12-17 10:58:52 +01:00
Paul Walker
3654f1baa6
[LLVM][IR] Add support for vector ConstantInt/FP to ConstandFolding:FoldBitCast. (#117163) 2024-12-10 15:42:05 +00:00
Nikita Popov
10f315dc9c
[ConstantFolding] Infer getelementptr nuw flag (#119214)
Infer nuw from nusw and nneg. This is the constant expression variant of
https://github.com/llvm/llvm-project/pull/111144.

Proof: https://alive2.llvm.org/ce/z/ihztLy
2024-12-09 16:44:05 +01:00
Benjamin Maxwell
24561f44df
Reland "[InstSimplify] Add basic constant folding for llvm.sincos" (#119192)
This calls into the existing constant folding for `llvm.sin` and
`llvm.cos`, which currently does not fold for any non-finite values, so
most tests are negative tests at the moment.

Note: The constant folding does not consider the `afn` fast-math flag
and will produce the same result regardless of if the flag is set.

This is a reland of #114527 that updates the syntax of one of the tests
from: `<float 1.000000e+00, float 1.000000e+00>` to `splat (float
1.000000e+00)`.
2024-12-09 11:16:14 +00:00
Yihang Liu
62a25a4c7c
[InstSimplify] Remove foldSelectWithBinaryOp (#118913)
As mentioned in https://github.com/llvm/llvm-project/issues/118815, the
purpose of this simplification is superseded by
https://github.com/llvm/llvm-project/pull/76621, so we should have it
deleted.
2024-12-09 10:31:54 +01:00
Benjamin Maxwell
c4aa67e866
Revert "[InstSimplify] Add basic constant folding for llvm.sincos" (#119149)
Reverts llvm/llvm-project#114527

Reverting due to buildbot failures (e.g.
https://lab.llvm.org/buildbot/#/builders/180/builds/9685)
2024-12-08 21:29:30 +00:00
Benjamin Maxwell
47df46b1e7
[InstSimplify] Add basic constant folding for llvm.sincos (#114527)
This calls into the existing constant folding for `llvm.sin` and
`llvm.cos`, which currently does not fold for any non-finite values, so
most tests are negative tests at the moment.

Note: The constant folding does not consider the `afn` fast-math flag
and will produce the same result regardless of if the flag is set.
2024-12-08 21:16:50 +00:00
Pedro Lobo
0d1e762da7
[InstSimplify] Refine abs(min/undef, true) to poison (#118669)
Calls to `@llvm.abs(undef, i1 true)` and `@llvm.abs(INT_MIN, i1 true)`
can be optimized to `poison` instead of `undef`.

[Alive2](https://alive2.llvm.org/ce/z/Hg-2ug)
2024-12-04 18:41:05 +00:00
Paul Walker
a88653a2cd
[LLVM][IR] When evaluating GEP offsets don't assume ConstantInt is a scalar. (#117162) 2024-12-04 12:45:30 +00:00
Nikita Popov
8201926ec0
[InstSimplify] Generalize simplification of icmps with monotonic operands (#69471)
InstSimplify currently folds patterns like `(x | y) uge x` and `(x & y)
ule x` to true. However, it cannot handle combinations of such
situations, such as `(x | y) uge (x & z)` etc.

To support this, recursively collect operands of monotonic instructions
(that preserve either a greater-or-equal or less-or-equal relationship)
and then check whether any of them match.

Fixes https://github.com/llvm/llvm-project/issues/69333.
2024-12-02 09:53:10 +01:00
Nikita Popov
f623df6376 [InstSimplify] Add tests for monotonic icmps (NFC) 2024-11-28 17:05:06 +01:00
Paul Walker
4872ecf1cc
[LLVM][IR] Teach extractelement folds about constant ConstantInt/FP. (#116793) 2024-11-21 12:39:53 +00:00
Paul Walker
af641ff260
[LLVM][IR] Refactor ConstantFold:FoldBitCast to fully support vector ConstantInt/FP. (#116787)
This fixes the code quality issue reported in
https://github.com/llvm/llvm-project/pull/111149.
2024-11-21 12:05:15 +00:00
Paul Walker
56c091ea71
[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
This brings the printing of scalable vector constant splats inline with
their fixed length counterparts.
2024-11-21 11:21:12 +00:00
Paul Walker
33fcd6acc7 [NFC][LLVM] Migrate tests to use update_test_checks.py.
Transforms/InstCombine/AArch64/sve-intrinsic-fmul-idempotency.ll
  Transforms/InstCombine/AArch64/sve-intrinsic-fmul_u-idempotency.ll
  Transforms/InstCombine/AArch64/sve-intrinsic-mul-idempotency.ll
  Transforms/InstCombine/AArch64/sve-intrinsic-mul_u-idempotency.ll
  Transforms/InstCombine/scalable-const-fp-splat.ll
  Transforms/InstSimplify/ConstProp/extractelement-vscale.ll
  Transforms/InstSimplify/ConstProp/vscale-shufflevector-inseltpoison.ll
  Transforms/InstSimplify/ConstProp/vscale-shufflevector.ll
2024-11-20 12:18:47 +00:00
Yingwei Zheng
42ed775783
[InstSimplify] Generalize simplifyAndOrOfFCmps to handle fabs (#116590)
This patch generalizes https://github.com/llvm/llvm-project/issues/81027
to handle pattern `and/or (fcmp ord/uno X, 0), (fcmp pred fabs(X), Y)`.
Alive2: https://alive2.llvm.org/ce/z/tsgUrz
The correctness is straightforward because `fcmp ord/uno X, 0.0` is
equivalent to `fcmp ord/uno fabs(X), 0.0`. We may generalize it to
handle fneg as well.

Address comment
https://github.com/llvm/llvm-project/pull/116065#pullrequestreview-2434796846
2024-11-19 20:10:40 +08:00
Ramkumar Ramachandra
94eebf721a
InstSimplify: support floating-point equivalences (#115152)
Since cd16b07 (IR: introduce CmpInst::isEquivalence), there is now an
isEquivalence routine in CmpInst that we can use to determine
equivalence in simplifySelectWithICmpEq. Implement this, extending the
code from integer-equalities to integer and floating-point equivalences.
2024-11-15 20:06:11 +00:00
Lee Wei
8ee638fd17
[llvm] Remove br i1 undef from some regression tests [NFC] (#116161)
This PR removes tests with `br i1 undef` under
`llvm/tests/Transforms/HotColdSplit` and `llvm/tests/Transforms/I*`.
2024-11-15 14:19:50 +00:00
Nikita Popov
dd9f1a572b
[InstSimplify] Correctly handle comparison with zero-size allocs (#115728)
InstSimplify currently folds alloc1 == alloc2 to false, even if one of
them is a zero-size allocation. A zero-size allocation may have the same
address as another allocation.

This also disables the fold for the case where we're comparing a
zero-size alloc with the middle of another allocation. It's possible
that this case is legal to fold depending on our precise zero-size
allocation semantics, but LangRef currently doesn't specify this either
way, so we shouldn't make assumptions here.
2024-11-14 11:55:19 +01:00
Paul Walker
97298853b4
[LLVM][IR] Teach constant integer binop folds about vector ConstantInts. (#115739)
The existing logic mostly works with the main changes being:
 * Use getScalarSizeInBits instead of IntegerType::getBitWidth
 * Use ConstantInt::get(Type* instead of ConstantInt::get(LLVMContext
2024-11-13 12:33:56 +00:00
Nikita Popov
36f21eedcf [InstSimplify] Fix alloca alignments in test (NFC)
These zero-sized types should be 1-aligned, but we seem to
default to 8-aligned.
2024-11-12 10:32:48 +01:00
Nikita Popov
3fcb9684cf [InstSimplify] Add tests for comparison with zero-sized allocs (NFC) 2024-11-11 16:41:35 +01:00
Nikita Popov
dd116369f6
[InstSimplify] Fix incorrect poison propagation when folding phi (#96631)
We can only replace phi(X, undef) with X, if X is known not to be
poison. Otherwise, the result may be more poisonous on the undef branch.

Fixes https://github.com/llvm/llvm-project/issues/68683.
2024-11-07 14:09:45 +01:00
Paul Walker
38fffa630e
[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548) 2024-11-06 11:53:33 +00:00
Jay Foad
f8559751fc
[llvm-project] Fix typo "propogate" (#114795) 2024-11-04 15:33:19 +00:00
Yingwei Zheng
a77dedcacb
[InstSimplify][InstCombine][ConstantFold] Move vector div/rem by zero fold to InstCombine (#114280)
Previously we fold `div/rem X, C` into `poison` if any element of the
constant divisor `C` is zero or undef. However, it is incorrect when
threading udiv over an vector select:
https://alive2.llvm.org/ce/z/3Ninx5
```
define <2 x i32> @vec_select_udiv_poison(<2 x i1> %x) {
  %sel = select <2 x i1> %x, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 0, i32 1>
  %div = udiv <2 x i32> <i32 42, i32 -7>, %sel
  ret <2 x i32> %div
}
```
In this case, `threadBinOpOverSelect` folds `udiv <i32 42, i32 -7>, <i32
-1, i32 -1>` and `udiv <i32 42, i32 -7>, <i32 0, i32 1>` into
`zeroinitializer` and `poison`, respectively. One solution is to
introduce a new flag indicating that we are threading over a vector
select. But it requires to modify both `InstSimplify` and
`ConstantFold`.

However, this optimization doesn't provide benefits to real-world
programs:

https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/IR/ConstantFold.cpp.html#L908

https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp.html#L1107

This patch moves the fold into InstCombine to avoid breaking numerous
existing tests.

Fixes #114191 and #113866 (only poison-safety issue).
2024-11-01 22:56:22 +08:00
ssijaric-nv
14db069468
[InstCombine] Fix a cycle when folding fneg(select) with scalable vector types (#112465)
The two folding operations are causing a cycle for the following case
with
scalable vector types:

define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double>
zeroinitializer, <vscale x 2 x double> %b
  %2 = fneg fast <vscale x 2 x double> %1
  ret <vscale x 2 x double> %2
}

1) fold fneg:  -(Cond ? C : Y) -> Cond ? -C : -Y

2) fold select: (Cond ? -X : -Y) -> -(Cond ? X : Y)

1) results in the following since '<vscale x 2 x double>
zeroinitializer' passes
the check for the immediate constant:

%.neg = fneg fast <vscale x 2 x double> zeroinitializer
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double> %.neg,
<vscale x 2 x double> %b.neg

and so we end up going back and forth between 1) and 2).

Attempt to fold scalable vector constants, so that we end up with a
splat instead:

define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
  %b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double>
shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x
double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double>
poison, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x double>
%b.neg
  ret <vscale x 2 x double> %1
}
2024-10-25 10:47:39 -07:00
Ramkumar Ramachandra
bdf241cab3
ValueTracking: handle more ops in isNotCrossLaneOperation (#112183)
Reuse llvm::isTriviallyVectorizable in llvm::isNotCrossLaneOperation, in
order to get it to handle more intrinsics.

Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/XSV_GT
2024-10-14 14:08:12 +01:00
Ramkumar Ramachandra
c5f82f7893
ValueTracking: introduce llvm::isNotCrossLaneOperation (#112011)
Factor out and unify common code from InstSimplify and InstCombine that
partially guard against cross-lane vector operations into
llvm::isNotCrossLaneOperation in ValueTracking.

Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/68H4ka
2024-10-14 11:37:30 +01:00
Paul Walker
87cdc8328d
[LLVM][ConstFolds] Verify a scalar src before attempting scalar->vector bitcast transformation. (#111149)
It was previously safe to assume isa<Constant{Int,FP}> meant a scalar
value. This is not true when use-constant-##-for-###-splat are enabled.
2024-10-08 13:28:44 +01:00
Matt Devereau
ccb2b79655 Fix logf128 tests to allow negative NaNs from (#104929) 2024-08-22 09:42:24 +00:00