1512 Commits

Author SHA1 Message Date
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
Yingwei Zheng
ff80e1ffe7
[InstSimplify] Simplify uadd.sat(X, Y) u>= X + Y and usub.sat(X, Y) u<= X, Y (#104698)
These patterns are found in harfbuzz/typst.

Alive2: https://alive2.llvm.org/ce/z/cxyjYV
2024-08-18 20:55:05 +08:00
Nikita Popov
afa0f53f96 [ValueTracking] Fix f16 fptosi range for large integers
We were missing the signed flag on the negative value, so the
range was incorrectly interpreted for integers larger than 64-bit.

Split out from https://github.com/llvm/llvm-project/pull/80309.
2024-08-15 18:18:19 +02:00
Nikita Popov
46fb225f3a [InstSimplify] Add tests for f16 to i128 range (NFC) 2024-08-15 18:18:19 +02:00
Nikita Popov
6300233de1 Revert "Reland logf128 constant folding (#103217)"
This reverts commit 3cab7c555ad6451f2b1b4dc918a4b4f4e4a3e45d.

The modified test fails on ppc64le buildbots.
2024-08-14 12:30:33 +02:00
Matthew Devereau
3cab7c555a
Reland logf128 constant folding (#103217)
This is a reland of #96287. This change makes tests in logf128.ll ignore
the sign of NaNs for negative value tests and moves an #include <cmath>
to be blocked behind #ifndef _GLIBCXX_MATH_H.
2024-08-14 08:55:52 +01:00
Benjamin Kramer
c31ac81091
[InstSimplify] Fold (insertelement Splat(C), C, X) -> Splat(C) (#102315)
The index doesn't matter here.
2024-08-07 16:39:08 +02: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
zhongyunde 00443407
c41da14570 [tests] precommit tests for ValueTracking
x-y+1 is positive when x > y, so abs (x-y+1) --> x-y+1

Fixes https://github.com/llvm/llvm-project/issues/54735
2024-08-06 10:30:03 +08:00
James Y Knight
b7e4fba6e5
Cleanup x86_mmx after removing IR type (#100646)
After #98505, the textual IR keyword `x86_mmx` was temporarily made to
parse as `<1 x i64>`, so as not to require a lot of test update noise.

This completes the removal of the type, by removing the`x86_mmx` keyword
from the IR parser, and making the (now no-op) test updates via `sed -i
's/\bx86_mmx\b/<1 x i64>/g' $(git grep -l x86_mmx llvm/test/)`.
Resulting bitcasts from <1 x i64> to itself were then manually deleted.

Changes to llvm/test/Bitcode/compatibility-$VERSION.ll were reverted, as
they're intended to be equivalent to the .bc file, if parsed by old
LLVM, so shouldn't be updated.

A few tests were removed, as they're no longer testing anything, in the
following files:
- llvm/test/Transforms/GlobalOpt/x86_mmx_load.ll
- llvm/test/Transforms/InstCombine/cast.ll
- llvm/test/Transforms/InstSimplify/ConstProp/gep-zeroinit-vector.ll

Works towards issue #98272.
2024-07-28 18:12:47 -04:00
James Y Knight
dfeb3991fb
Remove the x86_mmx IR type. (#98505)
It is now translated to `<1 x i64>`, which allows the removal of a bunch
of special casing.

This _incompatibly_ changes the ABI of any LLVM IR function with
`x86_mmx` arguments or returns: instead of passing in mmx registers,
they will now be passed via integer registers. However, the real-world
incompatibility caused by this is expected to be minimal, because Clang
never uses the x86_mmx type -- it lowers `__m64` to either `<1 x i64>`
or `double`, depending on ABI.

This change does _not_ eliminate the SelectionDAG `MVT::x86mmx` type.
That type simply no longer corresponds to an IR type, and is used only
by MMX intrinsics and inline-asm operands.

Because SelectionDAGBuilder only knows how to generate the
operands/results of intrinsics based on the IR type, it thus now
generates the intrinsics with the type MVT::v1i64, instead of
MVT::x86mmx. We need to fix this before the DAG LegalizeTypes, and thus
have the X86 backend fix them up in DAGCombine. (This may be a
short-lived hack, if all the MMX intrinsics can be removed in upcoming
changes.)

Works towards issue #98272.
2024-07-25 09:19:22 -04:00
Nikita Popov
de29b850f0
[InstSimplify] Fix simplifyAndOrWithICmpEq with undef refinement (#98898)
The final case in Simplify (where Res == Absorber and the predicate is
inverted) is not generally safe when the simplification is a refinement.
In particular, we may simplify assuming a specific value for undef, but
then chose a different one later.

However, it *is* safe to refine poison in this context, unlike in the
equivalent select folds. This is the reason why this fold did not use
AllowRefinement=false in the first place, and using that option would
introduce a lot of test regressions.

This patch takes the middle path of disabling undef refinements in
particular using the getWithoutUndef() SimplifyQuery option. However,
this option doesn't actually work in this case, because the problematic
fold is inside constant folding, and we currently don't propagate this
option all the way from InstSimplify over ConstantFolding to
ConstantFold. Work around this by explicitly checking for undef operands
in simplifyWithOpReplaced().

Finally, make sure that places where AllowRefinement=false also use
Q.getWithoutUndef(). I don't have a specific test case for this (the
original one does not work because we don't simplify selects with
constant condition in this mode in the first place) but this seems like
the correct thing to do to be conservative.

Fixes https://github.com/llvm/llvm-project/issues/98753.
2024-07-16 11:40:04 +02:00
Nikita Popov
93d7d9bfd4 [InstSimplify] Add test for #98753 (NFC) 2024-07-15 14:37:53 +02:00
Nikita Popov
9d34b673c0
[InstSimplify] Fold ptrtoint(ptradd(P,X-ptrtoint(P))) to X (#98649)
This is a special case of the general ptrtoint(gep) to add(ptrtoint)
transform that is particularly profitable, as everything folds away.

Proof: https://alive2.llvm.org/ce/z/fwv8_L

Fixes https://github.com/llvm/llvm-project/issues/86417.
2024-07-15 09:26:03 +02:00
Nikita Popov
25871b3505 [InstSimplify] Add tests for ptrtoint of gep fold (NFC) 2024-07-12 17:13:56 +02:00
Yingwei Zheng
6f619c98ae
[InstSimplify] Only handle canonical forms in simplifyAndOrOfFCmps. NFC. (#98136)
This patch avoids calling `isKnownNeverNaN` in `simplifyAndOrOfFCmps`
since `fcmp ord/uno X, NNAN` will be canonicalized into `fcmp ord/uno X,
0.0` in InstCombine.
2024-07-10 12:59:27 +08:00