1484 Commits

Author SHA1 Message Date
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
Alex MacLean
8e9d50cdd1
[InstSimplify] fold uno/ord comparison if fpclass is always NaN (#97763)
In InstSimplify we already fold `fcmp ord/uno` to a constant when both
operands are known to be non-NaN. This change slightly generalizes this
to also handle the case where either of the operands is known to always
be NaN.

Proof: https://alive2.llvm.org/ce/z/AhCmJN
2024-07-09 14:44:48 -07:00
Jay Foad
f3a02253e9
[test] Remove immarg parameter attribute from calls (#97432)
It is documented that immarg is only valid on intrinsic declarations,
although the verifier also tolerates it on intrinsic calls.

This patch updates tests that are not specifically testing the
behavior of the IR parser or verifier.
2024-07-03 09:02:31 +01:00
Noah Goldstein
aef44e49a7 [InstSimplify] Add simplification for ({u,s}rem (mul {nuw,nsw} X, C1), C0)
We can simplify these to `0` if `C1 % C0 == 0`

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

Closes #97037
2024-07-01 22:22:36 +08:00
Noah Goldstein
5880526b87 [InstSimplify] Add test for simplifying ({u,s}rem (mul {nuw,nsw} X, C1), C0); NFC 2024-07-01 22:22:36 +08:00
Nikita Popov
c5aa983f91 [InstSimplify] Fold all poison phi to poison instead of undef 2024-06-25 14:28:13 +02: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
Matthew Devereau
d38c8a7a51
ConstantFold logl calls (#94944)
This is a follow up patch from #90611 which folds logl calls in the same
manner as log.f128 calls. logl suffers from the same problem as logf128
of having slow calls to fp128 log functions which can be constant
folded. However, logl is emitted with -fmath-errno and log.f128 is
emitted by -fno-math-errno by certain intrinsics.
2024-06-18 13:27:25 +01:00
Poseydon42
b7b3d1798d
[InstSimplify] Implement simple folds for ucmp/scmp intrinsics (#95601)
This patch adds folds for the cases where both operands are the same or
where it can be established that the first operand is less than, equal
to, or greater than the second operand.
2024-06-17 13:10:57 +08:00
Jay Foad
d4a0154902
[llvm-project] Fix typo "seperate" (#95373) 2024-06-13 20:20:27 +01:00
Nikita Popov
f98be870e4 [InstSimplify] Accept GEPNoWrapFlags instead of only InBounds flag
This preserves the flags if a constexpr GEP is created (at least
as long as they don't get dropped later -- the test cases uses a
constexpr index to avoid that).
2024-06-04 11:15:06 +02:00
Nikita Popov
deab451e7a
[IR] Remove support for icmp and fcmp constant expressions (#93038)
Remove support for the icmp and fcmp constant expressions.

This is part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179

As usual, many of the updated tests will no longer test what they were
originally intended to -- this is hard to preserve when constant
expressions get removed, and in many cases just impossible as the
existence of a specific kind of constant expression was the cause of the
issue in the first place.
2024-06-04 08:31:03 +02:00
Nikita Popov
2f1229e40e [Tests] Move some tests from Assembler to InstSimplify (NFC)
To make sure these are preserved when icmp constant expressions
are removed.
2024-06-03 15:00:25 +02:00
Nikita Popov
e8ff03b574 [Tests] Move test from Assembler to InstSimplify (NFC)
Make sure this test is preserved when icmp constant expressions
are removed.
2024-06-03 14:44:21 +02:00
Nikita Popov
63dc31b68b Reapply [IR] Avoid creating icmp/fcmp constant expressions (#92885)
Reapply after https://github.com/llvm/llvm-project/pull/93548,
which should address the lldb failure on macos.

-----

Do not create icmp/fcmp constant expressions in IRBuilder etc anymore,
i.e. treat them as "undesirable". This is in preparation for removing
them entirely.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2024-05-31 08:55:59 +02:00
Poseydon42
cc2fafa178
[InstSimplify] Add constant folding support for ucmp/scmp intrinsics (#93730)
This PR adds support for folding calls to `ucmp`/`scmp` intrinsics with
constant arguments.
2024-05-30 18:31:03 +02:00
Nikita Popov
d10b76552f
[ConstantFold] Remove notional over-indexing fold (#93697)
The data-layout independent constant folding currently has some rather
gnarly code for canonicalizing GEP indices to reduce "notional
overindexing", and then infers inbounds based on that canonicalization.

Now that we canonicalize to i8 GEPs, this canonicalization is
essentially useless, as we'll discard it as soon as the GEP hits the
data-layout aware constant folder anyway. As such, I'd like to remove
this code entirely.

This shouldn't have any impact on optimization capabilities.
2024-05-30 08:36:44 +02:00
Nikita Popov
4ffe26334e [InstSimplify] Generate test checks (NFC) 2024-05-29 15:24:19 +02:00
Matthew Devereau
3613b26831
Constant Fold logf128 calls (#90611)
This is a second attempt to land #84501 which failed on several targets.

This patch adds the HAS_IEE754_FLOAT128 define which makes the check for
typedef'ing float128 more precise by checking whether __uint128_t is
available and checking if the host does not use __ibm128 which is
prevalent on power pc targets and replaces IEEE754 float128s.
2024-05-29 06:13:02 +01:00
Nikita Popov
1383cb6e64 [ConstFold] Fix incorrect gep inbounds of undef fold
gep inbounds of undef can only be folded to poison if we know
that the offset is non-zero. I don't think precise handling here
is important, so just drop the inbounds special case. This matches
what InstSimplify does.
2024-05-28 11:14:07 +02:00
Nikita Popov
4d3284cadf [ConstFold] Add test for incorrect gep inbounds of undef fold (NFC)
If the offset is zero, then returning poison here is not correct.
2024-05-28 11:14:07 +02:00
Daniel Thornburgh
8baf96f306
Revert "[IR] Avoid creating icmp/fcmp constant expressions" (#93087)
Reverts llvm/llvm-project#92885 due to LLDB CI breakages.
2024-05-22 11:27:55 -07:00
Nikita Popov
108575f02e
[IR] Avoid creating icmp/fcmp constant expressions (#92885)
Do not create icmp/fcmp constant expressions in IRBuilder etc anymore,
i.e. treat them as "undesirable". This is in preparation for removing
them entirely.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2024-05-22 07:40:08 +02:00
Ramkumar Ramachandra
63d81311a2
VectorCombine: add tests written for InstSimplify (#92776)
2141907 (InstSimplify: increase shufflevector test coverage) was
recently merged as a pre-commit test for some work that was misguided.
It turns out that InstSimplify can never work on those tests, but the
tests are useful nevertheless; move them to VectorCombine to support the
development of VectorCombine::foldShuffleToIdentity.
2024-05-21 08:06:34 +01: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
Noah Goldstein
2a45f89aee [ValueTracking] Add tests for isKnowNonZero of X op (X != 0); NFC 2024-05-20 15:25:40 -05:00
Ramkumar Ramachandra
21419071e1
InstSimplify: increase shufflevector test coverage (#92407)
Add examples of patterns that can be simplified, but are currently not.
This patch serves as a pre-commit test.
2024-05-20 10:47:51 +01:00
Nikita Popov
8e8d2595da
[ConstantFolding] Canonicalize constexpr GEPs to i8 (#89872)
This patch canonicalizes constant expression GEPs to use i8 source
element type, aka ptradd. This is the ConstantFolding equivalent of the
InstCombine canonicalization introduced in #68882.

I believe all our optimizations working on constant expression GEPs
(like GlobalOpt etc) have already been switched to work on offsets, so I
don't expect any significant fallout from this change.

This is part of:
https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699
2024-05-20 11:47:30 +02:00