This reverts commit 27c4e233104ba765cd986b3f8b0dcd3a6c3a9f89.
I think I made a mistake with the use in RemoveConditionFromAssume(),
because the instruction being changed is not the current one, but
the next assume. Revert the change for now.
Same as with other replacement methods, it's generally necessary
to report a change on the instruction itself, e.g. by returning
it from the visit method (or possibly explicitly adding it to the
worklist).
Return Instruction * from replaceUse() to encourage the usual
"return replaceXYZ" pattern.
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.
This overlaps partially with the codegen patch D144789. This needs no-wrap
for correctness, and I'm not sure if there's an unsigned equivalent:
https://alive2.llvm.org/ce/z/ErmQ-9https://alive2.llvm.org/ce/z/mr-c_A
This is obviously an improvement in IR, and it looks like a codegen win
for all targets and data types that I sampled.
The 'nabs' case is left as a potential follow-up (and seems less likely
to occur in real code).
Differential Revision: https://reviews.llvm.org/D145073
This avoids the danger shown in issue #60906.
There were no regression tests for these patterns, so these potential
failures have been around for a long time.
We freeze the condition and preserve the optimization because
getting rid of a div/rem is always a win.
Here are a couple of examples that can be corrected by freezing the
condition:
https://alive2.llvm.org/ce/z/sXHTTC
Differential Revision: https://reviews.llvm.org/D144671
Added the condition 'TrueVal->getType()->isIntOrIntVectorTy' to a block of code
in foldSelectInstWithICmp which is only valid if the TrueVal is integer type.
This change was split off from D136861.
(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.
As discussed in issue #59279, we want fneg/fabs to conform to the
IEEE-754 spec for signbit operations - quoting from section 5.5.1
of IEEE-754-2008:
"negate(x) copies a floating-point operand x to a destination in
the same format, reversing the sign bit"
"abs(x) copies a floating-point operand x to a destination in the
same format, setting the sign bit to 0 (positive)"
"The operations treat floating-point numbers and NaNs alike."
So we gate this transform with "nnan" in addition to "nsz":
(X > 0.0) ? X : -X --> fabs(X)
Without that restriction, we could have for example:
(+NaN > 0.0) ? +NaN : -NaN --> -NaN
(because an ordered compare with NaN is always false)
That would be different than fabs(+NaN) --> +NaN.
More fabs/fneg patterns demonstrated here:
https://godbolt.org/z/h8ecc659d
(without any FMF, these are correct independently of this patch -
no fabs should be created)
The code change is a one-liner, but we have lots of tests diffs
because there are many variations of the basic pattern.
Differential Revision: https://reviews.llvm.org/D139785
This mirrors a similar shufflevector transformation so the same
effect is obtained for scalable vectors. The transformation is
only performed when it can be proven the number of resulting
reversals is not increased. By bubbling the reversals from operand
to result this should typically be the case and ideally leads to
back-back shuffles that can be elimitated entirely.
Differential Revision: https://reviews.llvm.org/D139339
In the X == C ? f(X) : Y -> X == C ? f(C) : Y fold, perform the
replacement in f(X) recursively. For now, this just goes two
instructions up rather than one instruction up.
One of these two changes is exposing (or causing) some more miscompiles.
A reproducer is in progress, so reverting until resolved.
This reverts commit 9ddff66d0c9c3e18d56e6b20aa26a2a8cdfb6d2b.
Matches what we do for binary operations, but a special care needs
is needed to preserve operand order, as the logical operations
are not strictly commutative!
This is intended to mitigate potential regressions that
would result from restricting this fold for NANs as
discussed in issue #59279.
Ideally, we could do this more generally because we have
known problems seeing/generating FMF on a select, but there
are likely many corner cases that need to verified.
For example, I thought this propagation would be valid
without looking at the condition value and for 'nsz' too,
but according to Alive2, it is not:
https://alive2.llvm.org/ce/z/AnG6As
There was a code comment about detecting min/max, and we were already
doing that later.
The real motivation is hinted at by the new TODO comment. I'm hoping
to untangle some FMF ambiguity in follow-on patches. See discussion
in issue #59279.
There are enough unknowns in FMF handling that I can't say with
certainty that this change is NFC, but it doesn't cause any existing
regression tests to change.
Follow-on to:
ec0b406e16c44f1554
This should prevent crashing for example like issue #58552
by not matching a select-of-vectors-with-scalar-condition.
The test that shows a regression seems unlikely to occur
in real code.
This also picks up an optimization in the case where a real
(bitwise) logic op is used. We could already convert some
similar select ops to real logic via impliesPoison(), so
we don't see more diffs on commuted tests. Using commutative
matchers (when safe) might also handle one of the TODO tests.
This should prevent crashing for the example in issue #58552
by not matching a select-of-vectors-with-scalar-condition.
A similar change is likely needed for the related fold to
properly fix that kind of bug.
The test that shows a regression seems unlikely to occur
in real code.
This also picks up an optimization in the case where a real
(bitwise) logic op is used. We could already convert some
similar select ops to real logic via impliesPoison(), so
we don't see more diffs on commuted tests. Using commutative
matchers (when safe) might also handle one of the TODO tests.
This is a sibling transform to the fold just above it. That was changed
to allow the corresponding commuted patterns with:
307307456277
e1bd759ea567
8628e6df7000
Without a freeze, this transform can leak poison to the output:
https://alive2.llvm.org/ce/z/GJuF9i
This makes the transform as uniform as possible, and it can help
reduce patterns like issue #58313 (although that particular
example probably still needs another transform).
Differential Revision: https://reviews.llvm.org/D136527
When the common value is part of either select condition,
this is safe to reduce. Otherwise, it is not poison-safe
(with the select form of the pattern):
https://alive2.llvm.org/ce/z/FxQTzB
This is another patch motivated by issue #58313.
This is obviously correct for real logic instructions,
and it also works for the poison-safe variants that use
selects:
https://alive2.llvm.org/ce/z/wyHiwX
This is motivated by the lack of 'xor' folding seen in issue #58313.
This more general fold should help reduce some of those patterns,
but I'm not sure if this specific case does anything for that
particular example.
This allows the regular bitwise logic opcodes in addition to the
poison-safe select variants:
https://alive2.llvm.org/ce/z/8xB9gy
Handling commuted variants safely is likely trickier, so that's
left to another patch.
(A | B) & ~(A & B) --> A ^ B
https://alive2.llvm.org/ce/z/qpFMns
We already have the equivalent fold for real
logic instructions, but this pattern may occur
with selects too.
This is part of solving issue #58313.
Perform the simplifyWithOpReplaced() fold even for non-bool
selects. This subsumes a number of recently added folds for
zext/sext of the condition.
We still need to manually handle variations with both sext/zext
and not, because simplifyWithOpReplaced() only performs one
level of replacements.
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
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
Canonicalize ((x + C1) & C2) --> ((x & C2) + C1) for suitable constants
C1 and C2, instead of the other way round. This should allow more
constant ADDs to be matched as part of addressing modes for loads and
stores.
Differential Revision: https://reviews.llvm.org/D130080