5319 Commits

Author SHA1 Message Date
Sanjay Patel
0eedc9e567 [InstCombine] bitrev (zext i1 X) --> select X, SMinC, 0
https://alive2.llvm.org/ce/z/ZXCtgi

This breaks the infinite combine loop for issue #59897,
but we may still need more changes to avoid those loops.
2023-01-09 12:27:37 -05:00
Sanjay Patel
2dcbd740ee [InstCombine] reduce smul.ov with i1 types to 'and'
https://alive2.llvm.org/ce/z/5tLkW6

There's still a miscompile bug as shown in issue #59876 / D141214 .
2023-01-09 10:27:15 -05:00
Nikita Popov
59f91ddf90 [InstCombine] Preserve alignment in atomicrmw -> store fold
Preserve the alignment of the original atomicrmw, rather than using
the ABI alignment.

The same problem exists for loads, but that code is being removed
in D141277 anyway.
2023-01-09 15:37:24 +01:00
Jamie Hill-Daniel
6b9317f52a [InstCombine] Fold zero check followed by decrement to usub.sat
Fold (a == 0) : 0 ? a - 1 into usub.sat(a, 1).

Differential Revision: https://reviews.llvm.org/D140798
2023-01-09 14:22:25 +01:00
Noah Goldstein
6d839621da [InstCombine] Canonicalize (A & B_Pow2) eq/ne B_Pow2 patterns
1. A & B_Pow2 != B_Pow2 -> A & B_Pow2 == 0
   https://alive2.llvm.org/ce/z/KVUej4

2. A & B_Pow2 == B_Pow2 -> A & B_Pow2 != 0
   https://alive2.llvm.org/ce/z/PVv9FR

This allows the patterns to more easily be analyzed elsewhere.

Differential Revision: https://reviews.llvm.org/D141090
2023-01-09 12:48:28 +01:00
Noah Goldstein
e6375ca6dc [InstCombine] Fix potentially buggy code in ((%x & C) == 0) --> %x u< (-C) transform
While demanded bits constant shrinking appears to prevent this in
practice right now, it is principally possible for C2 to have
set bits that are known not-needed (zeroable). See: D140858

`+` will overflow here, `|` will get the right logic.

Differential Revision: https://reviews.llvm.org/D141089
2023-01-09 11:44:11 +01:00
chenglin.bi
33794cffcf [InstCombine] Fold logic-and/logic-or by distributive laws part2
Follow up https://reviews.llvm.org/D139408, support `and/or+select` patterns
X && Z || Y && Z --> (X || Y) && Z
https://alive2.llvm.org/ce/z/EMCkBG
https://alive2.llvm.org/ce/z/Q-YRvr
https://alive2.llvm.org/ce/z/SFkVQc
https://alive2.llvm.org/ce/z/S9MCuJ
https://alive2.llvm.org/ce/z/KZ7zzz

(X || Z) && (Y || Z) --> (X && Y) || Z
https://alive2.llvm.org/ce/z/Ggpa8-
https://alive2.llvm.org/ce/z/nhQRLY
https://alive2.llvm.org/ce/z/zpmEnq
https://alive2.llvm.org/ce/z/7omsrf
https://alive2.llvm.org/ce/z/CWBzBp

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D139630
2023-01-09 10:21:17 +08:00
Sanjay Patel
21d3871b7c [InstCombine] fold not-shift of signbit to icmp+zext, part 2
Follow-up to:
6c39a3aae1dc

That converted a pattern with ashr directly to icmp+zext, and
this updates the pattern that we used to convert to.

This canonicalizes to icmp for better analysis in the minimum case
and shortens patterns where the source type is not the same as dest type:
https://alive2.llvm.org/ce/z/tpXJ64
https://alive2.llvm.org/ce/z/dQ405O

This requires an adjustment to an icmp transform to avoid infinite looping.
2023-01-08 12:04:09 -05:00
luxufan
eda8e999dd [InstCombine] Combine (zext a) mul (zext b) to llvm.umul.with.overflow only if mul has NUW flag
Fixes: https://github.com/llvm/llvm-project/issues/59836

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D141031
2023-01-08 14:41:59 +08:00
serge-sans-paille
38818b60c5
Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ part
Use deduction guides instead of helper functions.

The only non-automatic changes have been:

1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*))
2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase.
3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated.
4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that).

Per reviewers' comment, some useless makeArrayRef have been removed in the process.

This is a follow-up to https://reviews.llvm.org/D140896 that introduced
the deduction guides.

Differential Revision: https://reviews.llvm.org/D140955
2023-01-05 14:11:08 +01:00
chenglin.bi
87b2c760d0 [Instcombine] fold logic ops to select
(C & X) | ~(C | Y) -> C ? X : ~Y

https://alive2.llvm.org/ce/z/4yLh_i

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D139080
2023-01-05 12:04:35 +08:00
Sanjay Patel
c43a7874a3 [InstCombine] don't let 'exact' inhibit demanded bits folds for udiv
We shouldn't penalize instructions that have extra flags.

Drop the poison-generating flags if needed instead of bailing out.
This makes canonicalization/optimization more uniform.

There is a chance that dropping flags will cause some
other transform to not fire, but we added a preliminary
patch to avoid that with:
f0faea571403

See D140665 for more details.
2023-01-04 13:13:02 -05:00
Sanjay Patel
cb9569049c [InstCombine] fold mask with not-of-sext-bool to select
~sext(A) & Op1 --> A ? 0 : Op1

With no extra uses, this pattern is already reduced,
but we would miss it in examples such as issue #59773.

https://alive2.llvm.org/ce/z/WGLcSR
2023-01-02 13:33:28 -05:00
Sanjay Patel
953cdcb989 [InstCombine] early exit to reduce indents in foldSelectIntoOp(); NFC 2023-01-02 13:33:27 -05:00
Roman Lebedev
cf58063a40
[InstCombine] Canonicalize math-y conditional negation into a select
https://alive2.llvm.org/ce/z/vPs-gZ

This is a larger pattern than would seem necessary, with minimal being:
* `and` https://alive2.llvm.org/ce/z/q9-MqK
* `or`  https://alive2.llvm.org/ce/z/AUUEMZ
* `xor` https://alive2.llvm.org/ce/z/dm3Ume
.. so for all others, we canonicalize away from math to `select`,
but there we canonicalize in the opposite direction.

Fixes https://github.com/llvm/llvm-project/issues/59791
2023-01-02 21:26:37 +03:00
Nikita Popov
81ac46445b [InstCombine] Support vectors in icmp of GEP fold
EmitGEPOffset() supports vector GEPs nowadays, so we don't need
any further code changes.

compare_gep_with_base_vector1 shows a weakness in folding the
resulting comparison if an index splat has to be performed.
2023-01-02 15:29:13 +01:00
Sanjay Patel
30af2e3191 [InstCombine] avoid miscompile in sinkNotIntoLogicalOp()
Fixes #59704
2022-12-29 14:33:41 -05:00
Sanjay Patel
f0faea5714 [InstSimplify] fold exact divide to poison if it is known to not divide evenly
This is related to the discussion in D140665. I was looking over the demanded
bits implementation in IR and noticed that we just bail out of a potential
fold if a udiv is exact:
82be8a1d2b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (L799)

Also, see tests added with 7f0c11509e8f.

Then, I saw that we could lose a fold to poison if we zap the exact with that
transform, so this patch tries to catch that as a preliminary step.

Alive2 proofs:
https://alive2.llvm.org/ce/z/zCjKM7
https://alive2.llvm.org/ce/z/-tz_RK (trailing zeros must be "less-than")
https://alive2.llvm.org/ce/z/c9CMsJ (general proof and specific example)

Differential Revision: https://reviews.llvm.org/D140733
2022-12-29 10:26:50 -05:00
Benjamin Kramer
a3d58bbaff Detemplate llvm::EmitGEPOffset and move it into a cpp file. NFC. 2022-12-29 16:24:21 +01:00
Chenbing Zheng
1f84e72b7b [InstCombine] Fold (X << Z) / (X * Y) -> (1 << Z) / Y
Alive2: https://alive2.llvm.org/ce/z/CBJLeP
2022-12-29 17:30:49 +08:00
Sanjay Patel
862e35e25a [InstCombine] preserve signbit semantics of NAN with fold to fabs
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
2022-12-28 10:28:23 -05:00
Nikita Popov
f7bc8e035d [InstCombine] Remove redundant evaluateGEPOffsetExpression() fold (NFCI)
If we go through the generic EmitGEPOffset code, the resulting
expression can be (and is) reduced in the same way this code did
manually. There are no changes in lit tests or llvm-test-suite.

This fold predates the time where we started adding nsw to the adds
created by EmitGEPOffset, so it was likely needed back then.

This might not actually be NFC due to worklist order changes etc.
2022-12-27 17:17:21 +01:00
Sanjay Patel
a0c8017286 [InstCombine] do not add "nuw" to 1<<X if the "1" has undefined elements
This was noted as a potential miscompile in the post-commit feedback
for the patch that added this fold:
d4493dd1ed58ac3f1eab0
2022-12-26 13:16:03 -05:00
Chenbing Zheng
bff1f8c79b [InstCombine] complete (X << Z) / (Y << Z) --> X / Y
Add one more situations for this fold.
For unsigned div, 'nsw' on both shifts + 'nuw' on the dividend.

Alive2: https://alive2.llvm.org/ce/z/sELF76

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D139997
2022-12-23 11:56:52 +08:00
Paul Walker
0bca44680a [InstCombine] Bubble vector.reverse of binop operands to their result.
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/D139342
2022-12-21 15:53:14 +00:00
Paul Walker
87c494b897 [InstCombine] Bubble vector.reverse of select operands to their result.
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
2022-12-21 15:53:14 +00:00
Paul Walker
362c52ad5a [InstCombine] Bubble vector.reverse of compare operands to their result.
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/D139340
2022-12-21 15:53:14 +00:00
Nikita Popov
79068275e7 [InstCombine] Recursively replace select value equivalence
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.
2022-12-21 15:55:44 +01:00
luxufan
561ee10a25 [InstCombine] Combine ZExt (B - A) + ZExt(A) to ZExt(B)
Combine ZExt (B - A) + ZExt(A) to ZExt(B)
https://alive2.llvm.org/ce/z/ESUwPi

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D139930
2022-12-21 22:53:29 +08:00
Matt Arsenault
8ab032fbe5 InstCombine: Fold fneg (copysign x, y) -> copysign x, (fneg y) 2022-12-20 17:14:34 -05:00
Roman Lebedev
a7b898b49a
[InstCombine] Disallow constant expressions in not canonicalization
As per post-commit feedback - we generally do not like Constant Expressions,
and trying to deal with them leads to inconsistent results
that may very well be non-optimal. So just don't.
2022-12-20 19:56:37 +03:00
Roman Lebedev
d73383c145
Revert "[InstCombine] Fold nested selects"
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.
2022-12-20 18:36:42 +03:00
Roman Lebedev
e51b7bff19
[InstCombine] Fix inversion of constants
`canFreelyInvertAllUsersOf()`, in general, does not make sense
for constants, and constant expressions are likely even more problematic.
For those, we just want to create a simple constant expression and be done.

Fixes https://github.com/llvm/llvm-project/issues/59613
2022-12-20 18:20:32 +03:00
Matt Arsenault
effde7f43e InstCombine: Match pattern that appears in clang's __builtin_isnormal
and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
and (fcmp ord x, 0), (fcmp u* fabs(x), inf) -> fcmp o* x, inf

Clang emits this peculiar pattern as an isfinite check in
__builtin_isnormal which can be simplified. We should fix clang to
emit this in the first place, but should also fold it here.
2022-12-19 08:09:22 -05:00
Roman Lebedev
3ae00753c1
[InstCombine] sinkNotIntoOtherHandOfLogicalOp(): don't forget to re-set insert position
Several bots are unhappy, and this appears to be the reason:
we might be inserting into wrong basic block,
one that does not dominate the I.
2022-12-19 05:17:03 +03:00
Roman Lebedev
6adeec881a
[InstCombine] sinkNotIntoOtherHandOfLogicalOp(): allow extra invertible uses of hand-to-invert 2022-12-19 05:00:58 +03:00
Roman Lebedev
b20ccccda2
[InstCombine] Support sinking not into logical operand with invertible hands
The important bit here is that we gracefully handle other uses,
iff they can be adapted to inversion.

I'll note, the previous logic was actively bad,
it increased instruction count since it didn't actually ensure
that the inversions happened.
2022-12-19 04:11:16 +03:00
Roman Lebedev
9f0c9e4725
[InstCombine] Try to sink not of one operand of logical operation into another hand
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!
2022-12-19 01:10:16 +03:00
Roman Lebedev
4def99e642
[InstCombine] Try to fold not into cmp iff other users of cmp are freely invertible
There is still some such patterns that require collaboration
of folds to handle,that we don't currently do.
2022-12-19 00:24:28 +03:00
Roman Lebedev
f61de3c1aa
[NFC][PatternMatching] Promote m_LogicalOp matchers into PatternMatch.h 2022-12-19 00:24:28 +03:00
Sanjay Patel
86b4a2355e [InstCombine] fold flooring sdiv by power-of-2 to ashr
It's a bigger match than usual, but I have not found any
sub-patterns that reduce:
(X / DivC) + sext ((X & (SMin | (DivC - 1)) >u SMin) --> X >>s log2(DivC)

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

Fixes issue #55741
2022-12-18 08:17:07 -05:00
Sanjay Patel
d5f8878a6e [InstCombine] canonicalize insertelement order based on index
This puts lower insert indexes before higher. This is independent
of endian, so it requires an adjustment to a fold added with
4446f71ce392, but it makes that fold more robust.
That's also where this patch was suggested - D139668.

This matches what we already do in DAGCombiner, but there is one
more constraint because there's an existing canonicalization for
insert-of-scalar-constant. I'm not sure if that is still needed,
so it may be adjusted/removed as a follow-up.
2022-12-18 07:08:48 -05:00
Roman Lebedev
dfacb8d211
[NFC][InstCombine] Add some readability by using DecomposedSelect struct 2022-12-17 05:18:54 +03:00
Fangrui Song
fb8eb84e5f [Transforms,InstCombine] std::optional::value => operator*/operator->
value() has undesired exception checking semantics and calls
__throw_bad_optional_access in libc++. Moreover, the API is unavailable without
_LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).
2022-12-16 22:57:56 +00:00
Craig Topper
ad476fb217 [InstCombine] Remove code duplication between InstCombiner.h and InstCombineInternal.h.
The class in InstCombineInternal.h inherits from InstCombiner.h.
I think this split was created when target specific InstCombines
were moved to go through TTI.

I had to update some of the code in InstCombiner.h to match changes
that had been made to InstCombineInternal.h.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D140230
2022-12-16 11:42:23 -08:00
Nikita Popov
379de1239e [InstCombine] Preserve instruction name in replaceInstUsesWith()
Currently InstCombine folds using the
`return replaceInstUsesWith(V, Builder.CreateFoo())`
pattern do not preserve the original name of the instruction.
To preserve the name, you either have to use something like
`return FooInst::Create(...)` which is usually less nice, or go
out of the way to preserve the name with takeName(). We often
don't do that.

This patch instead preserves the name in replaceInstUsesWith()
when replacing a named instruction with an unnamed instruction.
To be conservative, I also added a zero-use check, which is a
proxy for the case where the instruction was just created, rather
than an existing one reused. Possibly we could drop that part.

As InstCombine tests are robust against renames this does not
cause any test diffs, so I regenerated a random test to show the
effects.

Differential Revision: https://reviews.llvm.org/D140192
2022-12-16 16:01:25 +01:00
Vasileios Porpodas
32b38d248f [NFC] Rename Instruction::insertAt() to Instruction::insertInto(), to be consistent with BasicBlock::insertInto()
Differential Revision: https://reviews.llvm.org/D140085
2022-12-15 12:27:45 -08:00
Matt Arsenault
191c1d95e8 APFloat: Add isSmallestNormalized predicate function
It was annoying to write the check for this in the one case I added,
and I'm planning on adding another, so add a convenient PatternMatch
like for other special case values.

I have no idea what is going on in the DoubleAPFloat case, I reversed
this from the makeSmallestNormalized test. Also could implement this
as *this == getSmallestNormalized() for less code, but this avoids the
construction of a temporary APFloat copy and follows the style of the
other functions.
2022-12-15 14:04:26 -05:00
Sanjay Patel
d4493dd1ed [InstCombine] add nuw to any (1<<x)
https://alive2.llvm.org/ce/z/9EjDKE

This was mentioned as a missing fold in D139598.

It can unlock follow-on folds in some cases.
This verifies one of the changed tests:
https://alive2.llvm.org/ce/z/B_btDM
2022-12-15 12:03:47 -05:00
Sanjay Patel
8efee510be [InstCombine] limit pair-of-insertelement folds to avoid miscompile
This transform was added with 4446f71ce392. However, as noted in
the post-commit feedback, the transform is not safe with an
arbitrary base vector because we may leak poison from a narrow
element into an adjacent element when bitcasting.

I made the least invasive code change in case we do figure out
a way to make this safe.
2022-12-15 08:27:43 -05:00