931 Commits

Author SHA1 Message Date
Nikita Popov
b8df88b41c [InstCombine] Support zext nneg in gep of sext add fold
Add m_NNegZext() and m_SExtLike() matchers to make doing these kinds
of changes simpler in the future.
2023-12-21 16:38:09 +01:00
Chia
8674a023bc
[InstCombine] fold (Binop phi(a, b) phi(b, a)) -> (Binop a, b) while Binop is commutative. (#75765)
Alive2 proof: https://alive2.llvm.org/ce/z/2P8gq-
This patch closes #73905
2023-12-21 22:47:21 +08:00
Nikita Popov
cd54c47424 [InstCombine] Match poison instead of undef in foldVectorBinop()
Some negative tests turn into positive tests, as the differences
between undef and poison propagation allow additional transforms.
2023-12-18 17:01:59 +01:00
Nikita Popov
ddd11537e2 [InstCombine] Match poison instead of undef in binop of same-mask shuffle fold 2023-12-18 16:41:38 +01:00
Nikita Popov
465ecf872e [InstCombine] Rename UndefElts -> PoisonElts (NFC)
In line with updated shufflevector semantics, this represents the
poison elements rather than undef elements now. This commit is a
pure rename, without any logic changes.
2023-12-18 12:36:19 +01:00
Yingwei Zheng
af2d740d2d
[InstCombine] Treat lshr nneg as ashr in getBinOpsForFactorization (#75521)
This patch reinterprets `lshr nneg C, X` as `ashr nneg C, X` to allow
more factorization opportunities.
Fixes #70582.
2023-12-15 16:32:18 +08:00
Yingwei Zheng
9cf3e31172
[InstCombine] Explicitly fold ~(~X >>u Y) into X >>s Y (#75473)
Fixes #75369.

This patch explicitly folds `~(~X >>u Y)` into `X >>s Y` to fix assertion failure in #75369.
2023-12-14 23:06:38 +08:00
Sizov Nikita
88cc35b27e
[InstCombine] Fold binop (select cond, a, b), (select cond, b, a) to binop a, b (#74953)
```
CommutativeBinOp(select(V, A, B), select(V, B, A) --> CommutativeBinOp(A, B)
CommutativeIntrinsicCall(select(V, A, B), select(V, B, A), ...) --> CommutativeIntrinsicCall(A, B, ...)
```

https://alive2.llvm.org/ce/z/8CDUZ4

Closes #73904
2023-12-13 14:09:27 +08:00
Craig Topper
09a05f5dcb [InstCombine] Drop poison generating flags on Or in simplifyAssocCastAssoc.
Fixes #74739.
2023-12-07 13:35:28 -08:00
Nikita Popov
d77067d08a
[ValueTracking] Add dominating condition support in computeKnownBits() (#73662)
This adds support for using dominating conditions in computeKnownBits()
when called from InstCombine. The implementation uses a
DomConditionCache, which stores which branches may provide information
that is relevant for a given value.

DomConditionCache is similar to AssumptionCache, but does not try to do
any kind of automatic tracking. Relevant branches have to be explicitly
registered and invalidated values explicitly removed. The necessary
tracking is done inside InstCombine.

The reason why this doesn't just do exactly the same thing as
AssumptionCache is that a lot more transforms touch branches and branch
conditions than assumptions. AssumptionCache is an immutable analysis
and mostly gets away with this because only a handful of places have to
register additional assumptions (mostly as a result of cloning). This is
very much not the case for branches.

This change regresses compile-time by about ~0.2%. It also improves
stage2-O0-g builds by about ~0.2%, which indicates that this change results
in additional optimizations inside clang itself.

Fixes https://github.com/llvm/llvm-project/issues/74242.
2023-12-06 14:17:18 +01:00
Nikita Popov
faebb1b2e6 Reapply [InstCombine] Support inverting lshr with non-negative operand
My initial patch contained a typo, resulting in the wrong value
being checked for non-negativeness.

-----

If the lshr operand is non-negative, we can treat it the same
way as an ashr. Ideally we would represent this as "lshr nneg",
but for now just perform the necessary ValueTracking query.

Proof: https://alive2.llvm.org/ce/z/Ahg4ri
2023-12-01 16:09:54 +01:00
Nikita Popov
8c130996c0 Revert "[InstCombine] Support inverting lshr with non-negative operand"
This reverts commit b92693ac6afc522ea56bede0b9805ca7c138754c.

I've made a silly typo in the condition. Will reapply the corrected
version.
2023-12-01 16:05:17 +01:00
Nikita Popov
b92693ac6a [InstCombine] Support inverting lshr with non-negative operand
If the lshr operand is non-negative, we can treat it the same
way as an ashr. Ideally we would represent this as "lshr nneg",
but for now just perform the necessary ValueTracking query.

Proof: https://alive2.llvm.org/ce/z/Ahg4ri
2023-12-01 15:55:27 +01:00
Jeremy Morse
4424903156
[DebugInfo][RemoveDIs] Handle DPValues at remaining dbg.value using sites (#73788)
This patch updates the last few places in LLVM using findDbgValues that
don't also collect and handle DPValue objects. This largely involves
instcombine and mem2reg changes, and are largely mechanical, calling
existing utilities on collections of DPValues instead of just
DbgValuesInsts.

A variety of tests have had RemoveDIs RUN lines added to them to cover
these behaviours. We have some technical debt of the instcombine sinking
code for DPValues not being implemented yet, so I've left FIXME stubs
indicating that we intend to cover tests with RemoveDIs but haven't yet.
2023-11-30 16:30:32 +00:00
Jeremy Morse
2425e2940e
[DebugInfo][RemoveDIs] Have getInsertionPtAfterDef return an iterator (#73149)
Part of the "RemoveDIs" project to remove debug intrinsics requires
passing block-positions around in iterators rather than as instruction
pointers, allowing some debug-info to reside in BasicBlock::iterator.
This means getInsertionPointAfterDef has to return an iterator, and as
it can return no-instruction that means returning an optional iterator.

This patch changes the signature for getInsertionPtAfterDef and then
patches up the various places that use it to handle the different type.
This would overall be an NFC patch, however in
InstCombinerImpl::freezeOtherUses I've started skipping any debug
intrinsics at the returned insert-position. This should not have any
_meaningful_ effect on the compiler output: at worst it means variable
assignments that are skipped will now cover the freeze instruction and
anything inserted before it, which should be inconsequential.

Sadly: this makes the function signature ugly. This is probably the
ugliest piece of fallout for the "RemoveDIs" work, but it serves the
overall purpose of improving compile times and not allowing `-g` to
affect compiler output, so should be worthwhile in the end.
2023-11-30 12:19:57 +00:00
LiqinWeng
f7247d5041
[InstCombine] Canonicalise SextADD + GEP (#69581) 2023-11-29 09:50:58 +08:00
Noah Goldstein
3039691f53 [InstCombine] add getFreeInverted to perform folds for free inversion of op
With the current logic of `if(isFreeToInvert(Op)) return Not(Op)` its
fairly easy to either 1) cause regressions or 2) infinite loops
if the folds we have for `Not(Op)` ever de-sync with the cases we
know are freely invertible.

This patch adds `getFreeInverted` which is able to build the free
inverted op along with check for free inversion to alleviate this
problem.
2023-11-20 17:59:27 -06:00
Jeremy Morse
f42482def2
[DebugInfo][RemoveDIs] Don't convert debug-intrinsics to Unreachable (#72380)
It might seem obvious, but it's not a good idea to convert a
debug-intrinsic instruction into an UnreachableInst, as this means
things operate differently with and without the -g option. However this
can happen due to the "mutate the next instruction" API calls we make.
With RemoveDIs eliminating debug intrinsics, this behaviour is at risk
of changing, hence this patch ensures we only ever mutate the next _non_
debuginfo instruction into an Unreachable.

The tests instrumented with the --try... flag all exercise this, I've
added some metadata to a SCCP test to ensure it's exercised.
2023-11-20 20:53:24 +00:00
Jeremy Morse
80d3a4c39f
[DebugInfo][RemoveDIs] Add local-utility plumbing for DPValues (#72276)
This patch re-implements a variety of debug-info maintenence functions
to use DPValues instead of DbgValueInst's: supporting the "new"
non-intrinsic representation of debug-info. As per [0], we need to have
parallel implementations of various utilities for a time, and these are
the most fundamental utilities used throughout the compiler.

I've added --try-experimental-debuginfo-iterators to a variety of RUN
lines: this is a flag that turns on "new debug-info" if it's built into
LLVM, and not otherwise. This should ensure that we have the same
behaviour for the same IR inputs, but using a different internal
representation. For the most part these changes affect SROA/Mem2Reg
promotion of dbg.declares into dbg.value intrinsics (now DPValues),
we're leaving dbg.declares as instructions until later in the day.
There's also some salvaging changes made.

I believe the tests that I've added cover almost all the code being
updated here. The only thing I'm not confident about is SimplifyCFG,
which calls rewriteDebugUsers down a variety of code paths. Those
changes can't immediately get full coverage as an additional patch is
needed that updates handling of Unreachable instructions, will upload
that shortly.

[0]
https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939/9
2023-11-20 16:56:31 +00:00
Florian Hahn
1c05fe3500
[InstCombine] Pass InstCombineOptions instead of separate flags (NFC). (#72566)
This makes it simpler to pass additional flags/options in the future.
2023-11-17 09:57:05 +00:00
Craig Topper
2fbd088524
[InstCombine] Queue Xor for deletion after replacing its uses in freelyInvertAllUsersOf. (#72445)
Fixes #72433
2023-11-16 09:46:34 -08:00
Nikita Popov
b43b2a64b5 [InstCombine] Avoid use of shift constant expressions (NFCI)
Use the constant folding API instead. As we're working on
ImmConstants, these folds are guaranteed to succeed.
2023-11-10 16:58:10 +01:00
Nikita Popov
1b1c81772f [InstCombine] Drop poison flags in simplifyAssocCastAssoc()
The nneg flag on zext may no longer hold after the reassociation.
2023-11-09 11:58:02 +01:00
Nikita Popov
03110ddeb2 [IR] Remove ZExtOperator (NFC)
Now that zext constant expressions are no longer supported,
ZExtInst should be used instead.
2023-11-03 14:52:59 +01:00
Florian Hahn
0af5c0668a
[InstCombine] Don't consider aligned_alloc removable if icmp uses result (#69474)
At the moment, all alloc-like functions are assumed to return non-null
pointers, if their return value is only used in a compare. This is based
on being allowed to substitute the allocation function with one that
doesn't fail to allocate the required memory.

aligned_alloc however must also return null if the required alignment
cannot be satisfied, so I don't think the same reasoning as above can be
applied to it.

This patch adds a bail-out for aligned_alloc calls to
isAllocSiteRemovable.
2023-10-19 18:35:27 +01:00
Leonard Chan
ef388334ee Revert "Reapply "InstCombine: Introduce SimplifyDemandedUseFPClass""
This reverts commit 5a36904c515b.

Reverted because this breaks some floating point operations. See the
comment on https://github.com/llvm/llvm-project/commit/5a36904c515b.
2023-10-12 20:23:39 +00:00
Dmitriy Smirnov
e13bed4c5f [PATCH] [llvm] [InstCombine] Canonicalise ADD+GEP
This patch tries to canonicalise add + gep to gep + gep.

Co-authored-by: Paul Walker <paul.walker@arm.com>

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D155688
2023-10-06 12:29:06 +01:00
Matt Arsenault
5a36904c51 Reapply "InstCombine: Introduce SimplifyDemandedUseFPClass"
This reverts commit 26bb22b0c89e9b27576fd1f5683e0bc9ac3b4ec9.
2023-10-05 07:49:38 -07:00
Jonas Hahnfeld
26bb22b0c8 Revert "InstCombine: Introduce SimplifyDemandedUseFPClass"
It causes a test failure of clang/test/Headers/__clang_hip_math.hip:
https://lab.llvm.org/buildbot/#/builders/109/builds/75022

This reverts commit 59c6e2e9c1beee0bc73922fe44c9fd4462289847.
2023-10-05 10:26:10 +02:00
Matt Arsenault
59c6e2e9c1 InstCombine: Introduce SimplifyDemandedUseFPClass
This is the floating-point analog of SimplifyDemandedBits. If we know
the edge cases are assumed impossible in uses, it's possible to prune
upstream edge case handling.

Start by only using this on returns in functions with nofpclass
returns (where I'm surprised there are no other combines), but this
can be extended to include any other nofpclass use or FPMathOperator
with flags.

Partially addresses issue #64870

https://reviews.llvm.org/D158648
2023-10-04 21:06:24 -07:00
Nikita Popov
6ce7461eea [InstCombine] Avoid uses of ConstantExpr::getCast()
Add a generalized getLosslessTrunc() helper to simplify this.
2023-09-29 11:32:41 +02:00
Nikita Popov
c00f49cf12 [InstCombine] Remove instcombine-infinite-loop-threshold option
This option has been superseded by the fixpoint verification
functionality.
2023-09-21 15:30:05 +02:00
Paul Walker
c7d65e4466 [IR] Enable load/store/alloca for arrays of scalable vectors.
Differential Revision: https://reviews.llvm.org/D158517
2023-09-14 13:49:01 +00:00
Jeremy Morse
d529943a27 [NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
As per my proposal for how to eliminate debug intrinsics [0], for various
places in InstCombine prefer to insert using an instruction iterator rather
than an instruction pointer. This is so that we can eventually pass more
information in the iterator class. These call-sites where I've changed the
spelling are those that necessary to build a stage2clang to produce an
identical binary in the coming no-debug-intrinsics mode.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152543
2023-09-11 15:04:51 +01:00
Jeremy Morse
6942c64e81 [NFC][RemoveDIs] Prefer iterator-insertion over instructions
Continuing the patch series to get rid of debug intrinsics [0], instruction
insertion needs to be done with iterators rather than instruction pointers,
so that we can communicate information in the iterator class. This patch
adds an iterator-taking insertBefore method and converts various call sites
to take iterators. These are all sites where such debug-info needs to be
preserved so that a stage2 clang can be built identically; it's likely that
many more will need to be changed in the future.

At this stage, this is just changing the spelling of a few operations,
which will eventually become signifiant once the debug-info bearing
iterator is used.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D152537
2023-09-11 11:48:45 +01:00
Jeremy Morse
4427407a29 [NFC][RemoveDIs] Create a new spelling of the moveBefore method
As outlined in my proposal of how to get rid of debug intrinsics, this
patch adds a moveBefore method that signals the caller /intends/ the order
of moved instructions is to stay the same. This semantic difference has an
effect on debug-info, as it signals whether debug-info needs to move with
instructions or not.

The patch just replaces a few calls to moveBefore with calls to
moveBeforePreserving -- and the latter just calls the former, so it's all
NFC right now. A future patch will add an implementation of
moveBeforePreserving that takes action to correctly preserve debug-info,
but that's tightly coupled with our non-instruction debug-info
representation that's still being reviewed.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

Differential Revision: https://reviews.llvm.org/D156369
2023-09-07 18:37:57 +01: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
Matt Arsenault
033d6ffb53 IR: Add operator | and & for FastMathFlags
We only had |= and &= which was annoying.
2023-08-28 19:25:54 -04: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
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
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
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
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
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
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