5679 Commits

Author SHA1 Message Date
Kazu Hirata
83e6931827 [llvm] Use llvm::is_contained (NFC) 2023-09-02 09:32:46 -07:00
Fangrui Song
111fcb0df0 [llvm] Fix duplicate word typos. NFC
Those fixes were taken from https://reviews.llvm.org/D137338
2023-09-01 18:25:16 -07:00
Noah Goldstein
54ec8bcaf8 Recommit "[InstCombine] Expand foldSelectICmpAndOr -> foldSelectICmpAndBinOp to work for more binops" (3rd Try)
Fixed bug that assumed binop was commutative.
Was re-reviewed by nikic and chapuni

Differential Revision: https://reviews.llvm.org/D148414
2023-09-01 17:15:51 -05:00
Christoph Stiller
3af4590506 [InstCombine] Contracting x^2 + 2*x*y + y^2 to (x + y)^2 (float)
Resolves https://github.com/llvm/llvm-project/issues/61296 if https://reviews.llvm.org/D156026 didn't suffice.

Reviewed By: goldstein.w.n

Differential Revision: https://reviews.llvm.org/D158079
2023-09-01 15:02:12 -05:00
Matt Arsenault
5ae881ff0a InstCombine: Fold out scale-if-denormal pattern
Fold select (fcmp oeq x, 0), (fmul x, y), x => x

This cleans up a pattern left behind by denormal range checks under
denormals are zero.

The pattern starts out as something like:
  x = x < smallest_normal ? x * K : x;

The comparison folds to an == 0 when the denormal mode treats input
denormals as zero. This makes library denormal checks free after
linked into DAZ enabled code.

alive2 is mostly happy with this, but there are some issues. First,
there are many reported failures in some of the negative tests that
happen to trigger some preexisting canonicalize introducing
combine. Second, alive2 is incorrectly asserting that denormals must
be flushed with the DAZ modes. It's allowed to drop a canonicalize.

https://reviews.llvm.org/D157030
2023-09-01 07:47:12 -04:00
Matt Arsenault
70aede228a InstCombine: Recognize fneg(fabs) as bitcasted integer
Technically increases the number of instructions if the
result isn't cast back to float. Even in this case it's
still probably a better canonical form since it enables FP value
tracking.

https://reviews.llvm.org/D151939
2023-08-31 19:07:36 -04:00
Matt Arsenault
5c0da5839d InstCombine: Recognize fabs as bitcasted integer
In the past we sort of pretended float might be implementable
as a non-IEEE type but that never realistically would work. Exotic
FP types would need to be added to the IR. Turning these
into FP operations enables FP tracking optimizations.

https://reviews.llvm.org/D151937
2023-08-31 19:03:48 -04:00
Matt Arsenault
50a9b3d8a5 InstCombine: Recognize fneg when performed as bitcasted integer
This is a resurrection of D18874. This was previously wrong with
fneg conflated with fsub, but we now have a proper fneg instruction.
Additionally, I think it is now clearer that IR float=IEEE float,
and a different bit layout would require adding a different IR type.

https://reviews.llvm.org/D151934
2023-08-31 18:59:34 -04:00
Matt Arsenault
2b582440c1 InstCombine: Fold is.fpclass(x, fcInf) to fabs+fcmp
This is a better canonical form. fcmp and fabs are more widely
understood and fabs can fold for free into some sources.

Addresses todo from D146170

https://reviews.llvm.org/D159084
2023-08-29 17:58:15 -04:00
Yingwei Zheng
074f23e3e1
[InstCombine] Fold two select patterns into or-and
This patch is the follow-up improvement of D122152.
Fixes https://github.com/llvm/llvm-project/issues/64558.

`select (a | c), a, b -> select a, true, (select ~c, b, false)` where `c` is free to invert
`select (c & ~b), a, b -> select b, true, (select c, a, false)`
Alive2: https://alive2.llvm.org/ce/z/KwxtMA

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D158983
2023-08-30 00:57:08 +08:00
Matt Arsenault
033d6ffb53 IR: Add operator | and & for FastMathFlags
We only had |= and &= which was annoying.
2023-08-28 19:25:54 -04:00
Noah Goldstein
2acf00bd0a Revert "Recommit "[InstCombine] Expand foldSelectICmpAndOr -> foldSelectICmpAndBinOp to work for more binops" (2nd Try)"
Still appears to be buggy:
https://lab.llvm.org/buildbot/#/builders/124/builds/8260

This reverts commit 397a9cc4d875712a648271ecbac05ac6382c5708.
2023-08-25 02:22:23 -05:00
Noah Goldstein
397a9cc4d8 Recommit "[InstCombine] Expand foldSelectICmpAndOr -> foldSelectICmpAndBinOp to work for more binops" (2nd Try)
Was missing a nullptr check before derefencing. Fixed + test case
included in the patch.

Re-Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148414
2023-08-24 19:43:10 -05:00
Nikita Popov
167db7ce55 [InstCombine] Guard against FP min/max in select fold (PR64937)
This is partial revert of cbca9ce91c6440f8815742b8a73a27aa81e806e6.
That commit removed the code guarding against min/max SPF patterns,
because those are now canonicalized to min/max intrinsics. However,
this is only true for integer min/max, while FP min/max can not
always be canonicalized to an intrinsic. As such, restore a
simplified version of the guard that handles only the FP case.

Fixes https://github.com/llvm/llvm-project/issues/64937.
2023-08-24 15:29:59 +02:00
Matt Arsenault
0ec9ccb39e InstCombine: Fix typo in comment 2023-08-24 07:42:37 -04:00
Maksim Kita
341443d731 [InstCombine] Fold (-a >> b) and/or/xor (~a >> b) into (-a and/or/xor ~a) >> b
Fold (-a >> b) and/or/xor (~a >> b) into (-a and/or/xor ~a) >> b.
Depends on D157289.

Differential Revision: https://reviews.llvm.org/D157290
2023-08-21 12:49:20 +03:00
Carlos Alberto Enciso
bf69217bae [instcombine] Sunk instructions with invalid source location.
When the 'int Four = Two;' is sunk into the 'case 0:' block,
the debug value for 'Three' is set incorrectly to 'poison'.

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D158171
2023-08-21 06:24:21 +01:00
David Spickett
2121e35ac2 Revert "[InstCombine] Expand foldSelectICmpAndOr -> foldSelectICmpAndBinOp to work for more binops"
This reverts commit d3402bc4460acefbc3d5278743601fa090784614.

This has caused a second stage build failure on one of our Armv7 32 bit builders:
https://lab.llvm.org/buildbot/#/builders/182/builds/7193
2023-08-17 10:13:47 +00:00
Noah Goldstein
d3402bc446 [InstCombine] Expand foldSelectICmpAndOr -> foldSelectICmpAndBinOp to work for more binops
This just expands on the existing logic that worked for `Or` and
applies it to any binop where `0` is the identity value on the RHS
i.e: `add`, `or`, `xor`, `shl`, etc...

Proofs For Some: https://alive2.llvm.org/ce/z/XZo6JD

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148414
2023-08-16 22:43:05 -05:00
Noah Goldstein
00f0381461 [InstCombine] Refactor foldSelectICmpAndOr to use decomposeBitTestICmp instead of bespoke logic
This is essentially NFC as the cases `decomposeBitTestICmp` covers
that weren't already covered explicitly, will be canonicalized into
the cases explicitly covered. As well the unsigned cases don't apply
as the `Mask` is not a power of 2.

That being said, using a well established helper is less bug prone and
if some canonicalization changes, will prevent regressions here.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148744
2023-08-16 22:43:05 -05:00
Noah Goldstein
82292d1ae5 [InstCombine] Remove requirement on trunc in slt/sgt case in foldSelectICmpAndOr
AFAICT, the trunc is not needed for correctness/performance and just
blocks what should be handlable cases.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148413
2023-08-16 22:43:05 -05:00
Noah Goldstein
2c606dc16f [InstCombine] Cleanup code in foldSelectICmpAndOr; NFC
There was just alot of boolean logic to propegate conditions that seem
clearer in conditions.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148412
2023-08-16 22:43:05 -05:00
Noah Goldstein
9c375a457e [InstCombine] Transform (add (shl (neg X), Cnt)) -> (sub (shl X, Cnt))
Just a simple instruction save.

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

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D154807
2023-08-16 22:43:04 -05:00
Dhruv Chawla
d53b3df570
[InstCombine] Remove unneeded isa<PHINode> check in foldOpIntoPhi
This check is redundant as it is covered by the call to
isPotentiallyReachable.

Depends on D155726.

Differential Revision: https://reviews.llvm.org/D155718
2023-08-16 21:09:08 +05:30
Noah Goldstein
3cf54c533d [InstCombine] Add transforms for (icmp upred (or X, Y), X)
We can simplify ule/ugt -> eq/ne and we can remove the `Or` in some
cases of eq/ne.

`icmp (X | Y) u<= X` --> `(X | Y) == X`
    - https://alive2.llvm.org/ce/z/qnbbPv
`icmp (X | Y) u> X` --> `(X | Y) != X`
    - https://alive2.llvm.org/ce/z/fvLqg3
`icmp (X | Y) eq/ne X`
     - --> `(~X & Y) eq/ne 0` iff X is freely invertible
     - --> `(X & ~Y) eq/ne -1` iff Y is freely invertible
          - https://alive2.llvm.org/ce/z/cpPV_W

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D144610
2023-08-16 02:00:15 -05:00
Nikita Popov
c15ccfb24a [InstCombine] Fix select + cast fold with constant expression (PR64669)
The zext constant expression was detected by the fold, but then
handled as a sext. Use ZExtOperator instead of ZExtInst to handle
constant expressions.

Fixes https://github.com/llvm/llvm-project/issues/64669.
2023-08-14 17:44:23 +02:00
Nikita Popov
2827aa9daf [InstCombine] Fix evaluation order dependent fold
Make sure the function arguments are evaluated in a predictable
order.
2023-08-14 17:22:32 +02:00
Matt Arsenault
f7f5d348a3 InstCombine: Fold fneg (ldexp x, n) -> ldexp (fneg x), n
https://reviews.llvm.org/D156579
2023-08-11 19:16:20 -04:00
Nikita Popov
b5c2a19fed [InstCombine] Remove some typed pointer handling (NFC)
This bitcast is no longer needed.
2023-08-09 16:03:57 +02:00
Christoph Stiller
0bdab96a5a [InstCombine] Contract x^2 + 2*x*y + y^2 to (x + y)^2 (integer)
There are a number of variations on the pattern, depending on
order.

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

Differential Revision: https://reviews.llvm.org/D156026
2023-08-09 14:19:21 +02:00
Antonio Frighetto
211692137a [InstCombine] Fold select of srem and conditional add
Simplify a pattern that may show up when computing
the remainder of euclidean division. Particularly,
when the divisor is a power of two and never negative,
the signed remainder can be folded with a bitwise and.

Fixes 64305.

Proofs: https://alive2.llvm.org/ce/z/9_KG6c

Differential Revision: https://reviews.llvm.org/D156811
2023-08-08 00:02:16 +00:00
Zhongyunde
4225f54bf5 [InstCombine] Fold abs of known sign operand when source is sub
abs(x-y) --> x-y where x >= y, done on D122013
abs(x-y) --> y-x where x <= y

proofs: https://alive2.llvm.org/ce/z/KkeEsd

Reviewed By: goldstein.w.n, nikic
Differential Revision: https://reviews.llvm.org/D156499
2023-08-07 11:55:11 +08:00
Matt Arsenault
30fff9480a InstCombine: Don't bother skipping over pointer bitcasts
These don't really happen with opaque pointers.
2023-08-02 13:03:47 -04:00
Matt Arsenault
020d2fb771 InstCombine: Avoid repeated m_OneUse checks
The check was repeated for the fmul and fdiv case, and the caller was
already checking anyway.
2023-08-02 10:42:56 -04:00
Matt Arsenault
ed0dbfef7a InstCombine: Remove dead fsub-as-fneg handling
The above combine matching m_FNeg to produce a new fneg always would
hide this.
2023-08-02 10:42:56 -04:00
Bjorn Pettersson
fd05c34b18 Stop using legacy helpers indicating typed pointer types. NFC
Since we no longer support typed LLVM IR pointer types, the code can
be simplified into for example using PointerType::get directly instead
of using Type::getInt8PtrTy and Type::getInt32PtrTy etc.

Differential Revision: https://reviews.llvm.org/D156733
2023-08-02 12:08:37 +02:00
Nikita Popov
d01aec4c76 [InstCombine] Set dead phi inputs to poison in more cases
Set phi inputs to poison whenever we find a dead edge (either
during initial worklist population or the main InstCombine run),
instead of only doing this for successors of dead blocks.

This means that the phi operand is set to poison even if for
critical edges without an intermediate block.

There are quite a few test changes, because the pattern is fairly
common in vectorizer output, for cases where we know the vectorized
loop will be entered.
2023-08-01 11:53:47 +02:00
Maksim Kita
991855ea8a [InstCombine] Improve foldOpIntoPhi() to use isImpliedCondition
Improve foldOpIntoPhi() for icmp operator to check if incoming PHI value can be replaced with constant based on implied condition.

Depends on D156619.

Differential Revision: https://reviews.llvm.org/D156620
2023-08-01 12:15:57 +03:00
Nikita Popov
c5592f7acd [InstCombine] Fix use after free when removing unreachable code (PR64235)
In degenerate cases, it is possible for unreachable code removal
to remove the current instruction. However, we still return the
instruction to report a change, resulting in a use after free.

Instead, perform the change reporting in the same way as
eraseInstFromFunction() does, by directly setting MadeIRChange
and returning nullptr.

Fixes https://github.com/llvm/llvm-project/issues/64235.
2023-08-01 10:19:27 +02:00
Matt Arsenault
f9b2cbfffa InstCombine: Drop some typed pointer handling 2023-07-31 16:55:16 -04:00
Matt Arsenault
fbeda975d2 InstCombine: Drop some typed pointer cast handling 2023-07-31 10:34:31 -04:00
Nikita Popov
72ec2c007e [InstCombine] Fix handling of irreducible loops (PR64259)
Fixes a regression introduced by D75362 for irreducible control
flow. In that case, we may visit the predecessor that renders
the current block live only later, and incorrectly determine
that a block is dead.

Instead, switch to using the same DeadEdges based implementation
we also use during the main InstCombine iteration.

This temporarily regresses some cases that need replacement of
dead phi operands with poison, which is currently only done during
the main run, but not worklist population. This will be addressed
in a followup, to keep it separate from the correctness fix here.

Fixes https://github.com/llvm/llvm-project/issues/64259.
2023-07-31 16:20:22 +02:00
Nikita Popov
09156b36c6 [InstCombine] Move worklist preparation into InstCombinerImpl (NFC) 2023-07-31 15:18:12 +02:00
Matt Arsenault
d74c89fdb4 InstCombine: Drop some typed pointer bitcasts 2023-07-31 08:05:58 -04:00
Matt Arsenault
d388222be2 InstCombine: Drop some typed pointer bitcast handling 2023-07-31 08:05:12 -04:00
Nikita Popov
41895843b5 [InstCombine] Only perform one iteration
InstCombine is a worklist-driven algorithm, which works roughly
as follows:

* All instructions are initially pushed to the worklist.
  The initial order is in RPO program order.
* All newly inserted instructions get added to the worklist.
* When an instruction is folded, its users get added back to the
  worklist.
* When the use-count of an instruction decreases, it gets added
  back to the worklist.
* And a few of other heuristics on when we should revisit
  instructions.

On top of the worklist algorithm, InstCombine layers an additional
fix-point iteration: If any fold was performed in the previous
iteration, then InstCombine will re-populate the worklist from
scratch and fold the entire function again. This continues until
a fix-point is reached.

In the vast majority of cases, InstCombine will reach a fix-point
within a single iteration: However, a second iteration is performed
to verify that this is indeed the fixpoint. We can see this in the
statistics for llvm-test-suite:

    "instcombine.NumOneIteration": 411380,
    "instcombine.NumTwoIterations": 117921,
    "instcombine.NumThreeIterations": 236,
    "instcombine.NumFourOrMoreIterations": 2,

The way to read these numbers is that in 411380 cases, InstCombine
performs no folds. In 117921 cases it performs a fold and reaches
the fix-point within one iteration (the second iteration verifies
the fixpoint). In the remaining 238 cases, more than one iteration
is needed to reach the fixpoint.

In other words, only in 0.04% of cases are additional iterations
needed to reach a fixpoint. Conversely, in 22.3% of cases InstCombine
performs a completely useless extra iteration to verify the fix point.

This patch removes the fixpoint iteration from InstCombine, and always
only perform a single iteration. This results in a major compile-time
improvement of around 4% at negligible codegen impact.

This explicitly does accept that we will not reach a fixpoint in all
cases. However, this is mitigated by two factors: First, the data
suggests that this happens very rarely in practice. Second,
InstCombine runs many times during the optimization pipeline
(8 times even without LTO), so there are many chances to recover
such cases.

In order to prevent accidental optimization regressions in the
future, this implements a verify-fixpoint option, which is enabled
by default when instcombine is specified in -passes and disabled
when InstCombinePass() is constructed from C++. This means that
test cases need to explicitly use the no-verify-fixpoint option
if they fail to reach a fixed point (for a well understand reason
we cannot / do not want to avoid).

Differential Revision: https://reviews.llvm.org/D154579
2023-07-31 10:56:49 +02:00
Noah Goldstein
09b6765e7d [InstCombine] Remove trailing space in comment; NFC 2023-07-30 18:05:56 -05:00
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
Nuno Lopes
eb1617a582 [InstCombineVectorOps] Use poison instead of undef as placeholder [NFC]
It's used to create a vector where only 1 element is used
While at it, change OOB extractelement to yield poison per LangRef
2023-07-29 15:28:13 +01:00
Noah Goldstein
edf2e0e075 [InstCombine] Folding @llvm.ptrmask with itself
`@llvm.ptrmask` is basically just `and` with a `ptr` operand. This is
a trivial combine to do with `and` (many others could also be added).

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D154006
2023-07-27 17:43:08 -05:00