224 Commits

Author SHA1 Message Date
Nikita Popov
2fda200cd8 [InstCombine] Canonicalize phi order for newly inserted nodes
When new phi nodes are inserted at the start of the block, the
order of these does not get canonicalized, as we pick the first
phi node to canonicalize towards (and the other phi nodes may have
already been visited). This results in phi nodes not being
deduplicated and thus a fix-point verification failure.

Fix this by remembering the predecessors of the first phi node
we encounter -- this will usually result in the same order we
picked previously. I also considered using predecessors() order
instead, but that causes substantial test fallout. Additionally
the predecessors() order tends to be the reverse of the "natural"
order.

Fixes https://github.com/llvm/llvm-project/issues/46688.
2023-09-27 09:56:23 +02:00
Dhruv Chawla
3e992d81af
[InferAlignment] Enable InferAlignment pass by default
This gives an improvement of 0.6%:
https://llvm-compile-time-tracker.com/compare.php?from=7d35fe6d08e2b9b786e1c8454cd2391463832167&to=0456c8e8a42be06b62ad4c3e3cf34b21f2633d1e&stat=instructions:u

Differential Revision: https://reviews.llvm.org/D158600
2023-09-20 12:08:52 +05:30
Nikita Popov
ad7f02010f [InstCombine] Process blocks in RPO
InstComine currently processes blocks in an arbitrary
depth-first order. This can break the usual invariant that the
operands of an instruction should be simplified before the
instruction itself, if uses across basic blocks (particularly
inside phi nodes) are involved.

This patch switches the initial worklist population to use RPO
instead, which will ensure that predecessors are visited before
successors (back-edges notwithstanding).

This allows us to fold more cases within a single InstCombine
iteration, in preparation for D154579. This change by itself
is a minor compile-time regression of about 0.1%, which will
be more than recovered by switching to single-iteration InstCombine.

Differential Revision: https://reviews.llvm.org/D75362
2023-07-30 18:38:45 +02:00
Nikita Popov
547544112b [InstSimplify] Allow gep inbounds x, 0 -> x in non-refining op replacement
After the semantics change from https://reviews.llvm.org/D154051,
gep inbounds x, 0 can no longer produce poison. As such, we can
also perform this fold during non-refining operand replacement
and avoid unnecessary drops of the inbounds flag.

The online alive2 version has not been update to the new
semantics yet, but we can use the following proof locally:

    define ptr @src(ptr %base, i64 %offset) {
      %cmp = icmp eq i64 %offset, 0
      %gep = getelementptr inbounds i8, ptr %base, i64 %offset
      %sel = select i1 %cmp, ptr %base, ptr %gep
      ret ptr %sel
    }

    define ptr @tgt(ptr %base, i64 %offset) {
      %gep = getelementptr inbounds i8, ptr %base, i64 %offset
      ret ptr %gep
    }
2023-07-14 16:14:50 +02:00
Noah Goldstein
13f16f4dea [InstCombine] Canonicalize (icmp eq/ne (and x, C), x) -> (icmp eq/ne (and x, ~C), 0)
This increases the likelyhood `x` is single-use and is typically
easier to analyze.

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

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D154004
2023-06-29 13:14:37 -05:00
Nikita Popov
8378f1f4cd [InstCombine] Remove adjustMinMax() fold (PR62088)
This fold is buggy if the constant adjustment overflows.
Additionally, since we now canonicalize to min/max intrinsics,
the constants picked here don't actually matter, as long as SPF
still recognizes the pattern.

Fixes https://github.com/llvm/llvm-project/issues/62088.
2023-05-30 16:06:38 +02:00
Nikita Popov
271b5cf562 [InstCombine] Fix infinite combine loop (PR61361)
In the degenerate case where the select is fed by an unsimplified
icmp with two constant operands, don't try to replace one constant
with another. Wait for the icmp to be simplified first instead.

Fixes https://github.com/llvm/llvm-project/issues/61361.
2023-03-14 16:43:00 +01:00
Sanjay Patel
f48f178717 [InstCombine] canonicalize cmp+select as smin/smax
(V == SMIN) ? SMIN+1 : V --> smax(V, SMIN+1)
(V == SMAX) ? SMAX-1 : V --> smin(V, SMAX-1)

https://alive2.llvm.org/ce/z/d5bqjy

Follow-up for the unsigned variants added with:
86b4d8645fc1b866

issue #60374
2023-02-12 07:54:43 -05:00
Sanjay Patel
14411adc3d [InstCombine] add tests for disguised smin/smax; NFC
Adapted from the existing umin/umax tests.
2023-02-12 07:54:43 -05:00
Sanjay Patel
86b4d8645f [InstCombine] canonicalize cmp+select as umin/umax
(V == 0) ? 1 : V --> umax(V, 1)
(V == UMAX) ? UMAX-1 : V --> umin(V, UMAX-1)

https://alive2.llvm.org/ce/z/pfDBAf

This is one pair of the variants discussed in issue #60374.

Enhancements for the other end of the constant range and
signed variants are potential follow-ups, but that may
require more work because we canonicalize at least one
min/max like that to icmp+zext.
2023-02-08 17:25:58 -05:00
Sanjay Patel
b98813fbb6 [InstCombine] add tests for cmp+select; NFC 2023-02-08 17:25:58 -05:00
Paul Walker
eae26b6640 [IRBuilder] Use canonical i64 type for insertelement index used by vector splats.
Instcombine prefers this canonical form (see getPreferredVectorIndex),
as does IRBuilder when passing the index as an integer so we may as
well use the prefered form from creation.

NOTE: All test changes are mechanical with nothing else expected
beyond a change of index type from i32 to i64.

Differential Revision: https://reviews.llvm.org/D140983
2023-01-11 14:08:06 +00:00
Nikita Popov
c93e7dec7e [InstCombine] Convert some tests to opaque pointers (NFC)
Check lines for these were regenerated, but without any
significant changes (mostly different GEP source element types).
2022-12-27 16:29:52 +01:00
Nikita Popov
4b04c30340 [InstCombine] Regenerate test checks (NFC) 2022-12-27 16:21:31 +01:00
Nikita Popov
cd9e2ba0b3 Revert "[InstCombine] Convert some tests to opaque pointers (NFC)"
This reverts commit 66cea84681e16f3d4ebdc69031824b114a0d5681.

I did not intend to commit all the changes in here, but only the
ones with no significant differences.
2022-12-27 16:19:13 +01:00
Nikita Popov
66cea84681 [InstCombine] Convert some tests to opaque pointers (NFC) 2022-12-27 16:12:59 +01:00
Philip Reames
2e999b7dd1 Allow scalable vectors in ComputeNumSignBits and isKnownNonNull
This is a follow up to D136470 which extends the same scheme used there to ComputeNumSignBits and isKnownNonNull. As a reminder, for scalable vectors we track a single bit which is implicitly broadcast to all lanes. We do not know how many lanes there are statically, and thus have to be conservative along paths which require exact sizes.

Differential Revision: https://reviews.llvm.org/D137046
2022-11-01 09:29:42 -07:00
Philip Reames
3f532e0524 [test] Add coverage for sign bits and known non-zero for scalable vectors 2022-10-31 12:03:29 -07:00
Philip Reames
144e38f5e5 [test] Refresh an autogened test to pickup naming change 2022-10-31 11:36:45 -07:00
Craig Topper
90b695d1f2 [IR][InstCombine] Support scalable vector splats ConstantExprs in Constant::getUniqueInteger().
I've left the getAggregateElement as a fast path for non-ConstantExprs
to avoid a call to getSplatValue in release builds.

Fixes PR57989.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D134670
2022-09-26 14:55:15 -07:00
Nikita Popov
41dde5d858 [InstSimplify] Support vectors in simplifyWithOpReplaced()
We can handle vectors inside simplifyWithOpReplaced(), as long as
cross-lane operations are excluded. The equality can hold (or not
hold) for each vector lane independently, so we shouldn't use the
replacement value from other lanes.

I believe the only operations relevant here are shufflevector (where
all previous bugs were seen) and calls (which might use shuffle-like
intrinsics and would require more careful classification).

Differential Revision: https://reviews.llvm.org/D134348
2022-09-22 10:45:42 +02:00
Nikita Popov
a342350b53 [InstSimplify] Add vector tests for simplifyWithOpReplaced (NFC) 2022-09-21 12:20:38 +02:00
Markus Böck
b751da43b2 [InstCombine] Handle integer extension in select patterns using the condition as value
These patterns were previously only implemented for i1 type but can be extended for any integer type by also handling zext and sext operands.

Differential Revision: https://reviews.llvm.org/D134142
2022-09-20 22:25:13 +02:00
Markus Böck
bba25c4c9f [InstCombine] Precommit test for D134142 2022-09-20 15:10:52 +02:00
Nikita Popov
8a519b3c21 [InstCombine] Ensure constant folding in binop of select fold
When folding a binop into a select, we need to ensure that one
of the select arms actually does constant fold, otherwise we'll
create two binop instructions and perform the reverse transform.

Ensure this by performing an explicit constant folding attempt,
and failing the transform if neither side simplifies.

A simple alternative here would have been to limit the fold to
ImmConstants, but given the current representation of scalable
vector splats, this wouldn't be ideal.
2022-07-15 11:03:10 +02:00
Nuno Lopes
952e069393 [NFC] remove 'br undef' from InstCombine test cases
This is UB and allows the compiler to give any result, so these tests weren't meaningful
InstCombine tests are now clean of 'br undef'
2022-06-10 15:28:57 +01:00
Chenbing Zheng
51df77f36d [InstCombine] Allow undef vectors when foldSelectToCopysign
Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D125671
2022-05-19 10:57:49 +08:00
Chenbing Zheng
6c81079edf [InstCombine] precommit tests for foldSelectToCopysign 2022-05-17 16:51:54 +08:00
Sanjay Patel
c8ed784ee6 [InstCombine] fold freeze of partial undef/poison vector constants
We can always replace the undef elements in a vector constant
with regular constants to get rid of the freeze:
https://alive2.llvm.org/ce/z/nfRb4F

The select diffs show that we might do better by adjusting the
logic for a frozen select condition. We may also want to refine
the vector constant replacement to consider forming a splat.

Differential Revision: https://reviews.llvm.org/D123962
2022-04-26 14:16:11 -04:00
Sanjay Patel
5f7c385498 [InstCombine] add tests for freeze of partial undef vector constants; NFC 2022-04-19 12:41:50 -04:00
Sanjay Patel
3a27b51b27 [InstCombine] reduce code for freeze of undef
The description was ambiguous about the behavior
when boths select arms are constant or both arms
are not constant. I don't think there's any
evidence to support either way, but this matches
the code with a more specified description.

We can extend this to deal with vector constants
with undef/poison elements. Currently, those don't
get folded anywhere.
2022-04-18 15:14:02 -04:00
Sanjay Patel
60de144119 [InstCombine] add tests for select with frozen condition; NFC 2022-04-18 15:14:02 -04:00
Sanjay Patel
84812b9b07 [InstCombine] drop FMF in select->copysign transform
It is not correct to propagate flags from the select
to the new instructions:
https://alive2.llvm.org/ce/z/tNATrd
https://alive2.llvm.org/ce/z/VwcVzn

Fixes #54077
2022-03-01 08:51:41 -05:00
Sanjay Patel
53dbedcd18 [InstCombine] add test for copysign with FMF propagation; NFC
This is a miscompile as noted in #54077.
2022-03-01 08:51:40 -05:00
Sanjay Patel
f422c5d871 [InstCombine] fold select-of-zero-or-ones with negated op
(X u< 2) ? -X : -1 --> sext (X != 0)
(X u> 1) ? -1 : -X --> sext (X != 0)

https://alive2.llvm.org/ce/z/U3y5Bb
https://alive2.llvm.org/ce/z/hgi-4p

This is part of solving:
2022-02-28 12:07:49 -05:00
Sanjay Patel
614f36fd38 [InstCombine] add tests for select of zero or all ones; NFC
See #54053
2022-02-28 11:20:02 -05:00
Nikita Popov
a266af7211 [InstCombine] Canonicalize SPF to min/max intrinsics
Now that integer min/max intrinsics have good support in both
InstCombine and other passes, start canonicalizing SPF min/max
to intrinsic min/max.

Once this sticks, we can stop matching SPF min/max in various
places, and can remove hacks we have for preventing infinite loops
and breaking of SPF canonicalization.

Differential Revision: https://reviews.llvm.org/D98152
2022-02-24 09:01:20 +01:00
Bjorn Pettersson
acdc419c89 [test] Use -passes=instcombine instead of -instcombine in lots of tests. NFC
Another step moving away from the deprecated syntax of specifying
pass pipeline in opt.

Differential Revision: https://reviews.llvm.org/D119081
2022-02-07 14:26:59 +01:00
Filipp Zhinkin
f5d8952356 [InstCombine] Transform X == 0 ? 0 : X * Y --> X * freeze(Y)
Enabled mul folding optimization that was previously disabled
by being incorrect.
To preserve correctness, mul's operand that is not compared
with zero in select's condition is now frozen.

Related bug: https://bugs.llvm.org/show_bug.cgi?id=51286

Correctness:
https://alive2.llvm.org/ce/z/bHef7J
https://alive2.llvm.org/ce/z/QcR7sf
https://alive2.llvm.org/ce/z/vvBLzt
https://alive2.llvm.org/ce/z/jGDXgq
https://alive2.llvm.org/ce/z/3Pe8Z4
https://alive2.llvm.org/ce/z/LGga8M
https://alive2.llvm.org/ce/z/CTG5fs

Differential Revision: https://reviews.llvm.org/D108408
2021-09-15 09:04:06 -04:00
Filipp Zhinkin
745f82b8d9 [InstCombine] add tests for X == 0 ? 0 : X * Y ; NFC
These are the tests for D108408 with current baseline results.
2021-09-10 09:06:48 -04:00
David Sherwood
8439415333 [IR] Let ConstantVector::getSplat use poison instead of undef
This patch updates ConstantVector::getSplat to use poison instead
of undef when using insertelement/shufflevector to splat.

This follows on from D93793.

Differential Revision: https://reviews.llvm.org/D107751
2021-08-10 08:27:43 +01:00
Philip Reames
e75a2dfe20 [tests] Stablize tests for possible change in deref semantics
There's a potential change in dereferenceability attribute semantics in the nearish future.  See llvm-dev thread "RFC: Decomposing deref(N) into deref(N) + nofree" and D99100 for context.

This change simply adds appropriate attributes to tests to keep transform logic exercised under both old and new/proposed semantics.  Note that for many of these cases, O3 would infer exactly these attributes on the test IR.

This change handles the idiomatic pattern of a dereferenceable object being passed to a call which can not free that memory.  There's a couple other tests which need more one-off attention, they'll be handled in another change.
2021-07-14 13:05:43 -07:00
Sanjay Patel
b70fe92f08 [InstCombine] avoid 'tmp' usage in test file; NFC
The update script ( utils/update_test_checks.py ) warns against this.
2021-05-26 08:32:07 -04:00
Sanjay Patel
ca7eaa0a54 [InstSimplify] allow undef element match in vector select condition value
The semantics of select with undefined/poison condition
are not explicitly stated in the LangRef, but this matches
comments in the code and Alive2 appears to concur:
https://alive2.llvm.org/ce/z/KXytmd

We can find this pattern after demanded elements transforms.

As noted in D101191, fuzzers are finding infinite loops because
we may not account for this pattern in other passes.
2021-05-25 14:25:34 -04:00
Sanjay Patel
ae1bc9ebf3 [InstCombine] avoid infinite loop from vector select transforms
The 2nd test is based on the fuzzer example in post-commit
comments of D101191 -
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34661

The 1st test shows that we don't deal with this symmetrically.
We should be able to reduce both examples (possibly in
instsimplify instead of instcombine).
2021-05-25 13:28:38 -04:00
Juneyoung Lee
8a156d1c27 [InstCombine] Fully disable select to and/or i1 folding
This is a patch that disables the poison-unsafe select -> and/or i1 folding.

It has been blocking D72396 and also has been the source of a few miscompilations
described in llvm.org/pr49688 .
D99674 conditionally blocked this folding and successfully fixed the latter one.
The former one was still blocked, and this patch addresses it.

Note that a few test functions that has `_logical` suffix are now deoptimized.
These are created by @nikic to check the impact of disabling this optimization
by copying existing original functions and replacing and/or with select.

I can see that most of these are poison-unsafe; they can be revived by introducing
freeze instruction. I left comments at fcmp + select optimizations (or-fcmp.ll, and-fcmp.ll)
because I think they are good targets for freeze fix.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D101191
2021-05-06 09:29:52 +09:00
Nikita Popov
7e18cd887c [InstCombine] Whitelist non-refining folds in SimplifyWithOpReplaced
This is an alternative to D98391/D98585, playing things more
conservatively. If AllowRefinement == false, then we don't use
InstSimplify methods at all, and instead explicitly implement a
small number of non-refining folds. Most cases are handled by
constant folding, and I only had to add three folds to cover
our unit tests / test-suite. While this may lose some optimization
power, I think it is safer to approach from this direction, given
how many issues this code has already caused.

Differential Revision: https://reviews.llvm.org/D99027
2021-03-22 22:12:56 +01:00
Philip Reames
854de7c4d0 [tests] Refresh a bunch of autogen test to adjust for format changes 2021-03-22 10:41:39 -07:00
Nikita Popov
fb063c933f [InstCombine] Duplicate tests for logical and/or (NFC)
This replicates existing and/or tests to also test variants using
select. This should help us get a more accurate view on which
optimizations we're missing if we disable the select -> and/or
fold.
2021-01-12 21:50:41 +01:00
Jun Ma
2ac58e21a1 [InstCombine] Remove scalable vector restriction when fold SelectInst
Differential Revision: https://reviews.llvm.org/D93083
2020-12-15 20:36:57 +08:00