Commit Graph

982 Commits

Author SHA1 Message Date
luxufan
1ac99bc452 [InstSimplify] Simplify select i1 ConstExpr, i1 true, i1 false to ConstExpr
`select i1 non-const, i1 true, i1 false` has been optimized to
`non-const`. There is no reason that we can not optimize `select i1
ConstExpr, i1 true, i1 false` to `ConstExpr`.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D151631
2023-06-03 15:09:00 +08:00
Matt Arsenault
2ca21e8775 InstSimplify: Remove null parent checks
The feature to operate on incomplete IR was barely used
an poorly tested.
2023-06-02 18:14:28 -04:00
Matt Arsenault
1536e299e6 InstSimplify: Require instruction be parented
Unlike every other analysis and transform, simplifyInstruction
permitted operating on instructions which are not inserted
into a function. This created an edge case no other code needs
to really worry about, and limited transforms in cases that
can make use of the context function. Only the inliner and a handful
of other utilities were making use of this, so just fix up these
edge cases. Results in some IR ordering differences since
cloned blocks are inserted eagerly now. Plus some additional
simplifications trigger (e.g. some add 0s now folded out that
previously didn't).
2023-06-02 18:14:28 -04:00
Matt Arsenault
4023ca1292 Reapply "InstSimplify: Pass AssumptionCache to isKnownNeverInfinity"
This reverts commit 481191b0a8.
2023-05-23 08:48:25 +01:00
Matt Arsenault
1e34a17926 Reapply "InstSimplify: Use isKnownNeverInfOrNaN"
This reverts commit f55224735e.
2023-05-23 08:48:25 +01:00
Alina Sbirlea
f55224735e Revert "InstSimplify: Use isKnownNeverInfOrNaN"
This reverts commit 494dee0f7a.
Related to the other reverts, causes test failure due to nan/inf
mismatch.
2023-05-19 22:27:42 -07:00
Alina Sbirlea
481191b0a8 Revert "InstSimplify: Pass AssumptionCache to isKnownNeverInfinity"
This reverts commit 0012b94a4e.
Reverting due to test failures introduced by 73925ef8b0
Updated floating-point-compare.ll to keep the assume declaration.
2023-05-18 23:31:50 -07:00
Matt Arsenault
c9bbc64eeb InstSimplify: Pass AssumptionCache through fcmp ord/uno simplification 2023-05-19 00:48:04 +01:00
Matt Arsenault
84e64d9bee InstSimplify: Pass AssumptionCache to isKnownNeverNaN queries 2023-05-19 00:48:03 +01:00
Matt Arsenault
b42ee1d6c3 InstSimplify: Pass AssumptionCache through more isKnownNeverNaN queries 2023-05-19 00:48:03 +01:00
Matt Arsenault
0012b94a4e InstSimplify: Pass AssumptionCache to isKnownNeverInfinity
Makes these cases work with assumes.
2023-05-19 00:48:03 +01:00
Matt Arsenault
494dee0f7a InstSimplify: Use isKnownNeverInfOrNaN 2023-05-18 23:29:47 +01:00
Matt Arsenault
07365f4a40 InstSimplify: Combine computeKnownFPClass calls and pass AssumptionCache 2023-05-18 23:29:47 +01:00
Matt Arsenault
faa32734bf SimplifyLibCalls: Pass AssumptionCache to isKnownNeverInfinity
Let's assumes work for determining no infinities.
2023-05-18 19:44:56 +01:00
Zhongyunde
cd87fe0c8b [Instsimplfy] X == Y ? 0 : X ^ Y --> X ^ Y
Alive2: https://alive2.llvm.org/ce/z/cykffE
Fixes: https://github.com/llvm/llvm-project/issues/62753

Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D150750
2023-05-17 18:36:39 +08:00
Matt Arsenault
86d0b524f3 ValueTracking: Expand signature of isKnownNeverInfinity/NaN
This is in preparation for replacing the implementation
with a wrapper around computeKnownFPClass.
2023-05-16 20:42:58 +01:00
Jun Zhang
a47b56f4ef [Instsimplfy] X == Y ? 0 : X - Y --> X - Y
Alive2: https://alive2.llvm.org/ce/z/rPN1GB
Fixes: https://github.com/llvm/llvm-project/issues/62238

Depends on D150377

Signed-off-by: Jun Zhang <jun@junz.org>

Differential Revision: https://reviews.llvm.org/D150378
2023-05-16 19:15:47 +08:00
Noah Goldstein
ab1b42ac5c [InstCombine] Add simplifications for div/rem with i1 operands; PR62607
This is generally handled already in early CSE.

If a specialized pipeline is used, however, its possible for `i1`
operand with known-zero denominator to slip through. Generally the
known-zero denominator is caught and poison is returned, but if it is
indirect enough (known zero through a phi node) we can miss this case
in `InstructionSimplify` and then miss handling `i1`. This is because
`i1` is current handled with the following check:
    `if(Known.countMinLeadingZeros() == Known.getBitWidth() - 1)`

which only works on the assumption we don't know the denominator to be
zero. If we know the denominator to be zero, this check fails:
https://github.com/llvm/llvm-project/issues/62607

This patch simply adds an explicit `if(Known.isZero) return poison;`
which fixes the issue.

Alive2 Link for tests:
    https://alive2.llvm.org/ce/z/VTw54n

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D150142
2023-05-13 14:35:57 -05:00
ManuelJBrito
853d212e32 [InstSimplify] Update to handle new shufflevector semantics
Simplifying poison mask elements yields poison values.

Differential Revision: https://reviews.llvm.org/D149544
2023-05-03 21:31:19 +01:00
ManuelJBrito
d22edb9794 [IR][NFC] Change UndefMaskElem to PoisonMaskElem
Following the change in shufflevector semantics,
poison will be used to represent undefined elements in shufflevector masks.

Differential Revision: https://reviews.llvm.org/D149256
2023-04-27 18:01:54 +01:00
Serguei Katkov
faf8407aec [InstSimplify] Extend handlng of fp min/max.
Add support the cases like
  m(m(X,Y),m'(X,Y)) => m(X,Y)
where m is one of maxnum, minnum, maximum, minimum and
m' is m or inverse of m.

alive2 correctness check:
maxnum(maxnum,maxnum) https://alive2.llvm.org/ce/z/kSyAzo
maxnum(maxnum,minnum) https://alive2.llvm.org/ce/z/Vra8j2
minnum(minnum,minnum) https://alive2.llvm.org/ce/z/B6h-hW
minnum(minnum,maxnum) https://alive2.llvm.org/ce/z/rG2u_b
maximum(maximum,maximum) https://alive2.llvm.org/ce/z/N2nevY
maximum(maximum,minimum) https://alive2.llvm.org/ce/z/23RFcP
minimum(minimum,minimum) https://alive2.llvm.org/ce/z/spHZ-U
minimum(minimum,maximum) https://alive2.llvm.org/ce/z/Aa-VE8

Reviewed By: dantrushin, RKSimon
Differential Revision: https://reviews.llvm.org/D147137
2023-04-27 10:45:27 +07:00
Zhongyunde
f9478f729e [InstSimplify] with logical ops: (X & Y) == -1 ? X : -1 --> -1
Use simplifySelectWithICmpEq to handle the implied equalities from the icmp-and,
then both of ICMP_NE and ICMP_EQ will be addressed including vector type.
    (X & Y) == -1 ?  X : -1 --> -1 (commuted 2 ways)
    (X & Y) != -1 ? -1 :  X --> -1 (commuted 2 ways)
This is a supplement to the icmp-or scenario on D148986.

Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D149229
2023-04-26 15:53:02 +08:00
Zhongyunde
b80f31c48d [InstSimplify] with logical ops: (X | Y) ? 0 : X --> 0
Use simplifySelectWithICmpEq to handle the implied equalities from the icmp-or,
then both of ICMP_NE and ICMP_EQ will be addressed
  (X | Y) == 0 ?  X : 0 --> 0 (commuted 2 ways)
  (X | Y) != 0 ?  0 : X --> 0 (commuted 2 ways)
Fixes https://github.com/llvm/llvm-project/issues/62263

Reviewed By: nikic, RKSimon
Differential Revision: https://reviews.llvm.org/D148986
2023-04-25 21:51:41 +08:00
Nikita Popov
9d92f479c3 Reapply [InstSimplify] Support all instructions in simplifyWithOpReplaced()
Relative to the previous attempt, this includes a bailout for phi
nodes, whose arguments might refer to a previous cycle iteration.

We did not hit this before by a fortunate deficiency of the
ConstantFoldInstOperands() API, which doesn't handle phi nodes,
unlike ConstantFoldInstruction().

-----

Instead of hardcoding a few instruction kinds, use the generic
interface now that we have it.

The primary effect of this is that intrinsics are now supported.

It's worth noting that this is still limited in that it does not
support vectors, so we can't remove e.g. existing fshl special
cases.
2023-04-25 15:45:32 +02:00
Nikita Popov
4d05d846ec Revert "[InstSimplify] Support all instructions in simplifyWithOpReplaced()"
This reverts commit 3e3e41b263.

This appears to cause a stage2 miscompile of llvm-profgen.
2023-04-24 16:51:54 +02:00
Nikita Popov
3e3e41b263 [InstSimplify] Support all instructions in simplifyWithOpReplaced()
Instead of hardcoding a few instruction kinds, use the generic
interface now that we have it.

The primary effect of this is that intrinsics are now supported.

It's worth noting that this is still limited in that it does not
support vectors, so we can't remove e.g. existing fshl special
cases.
2023-04-24 15:22:20 +02:00
Siyuan Zhu
946b326803 [InstSimplify] sdiv a (1 srem b) --> a
Extend the existing fold for division by zero or one to use known
bits, so it catches additional patterns like division by
(1 srem b).

Fixes https://github.com/llvm/llvm-project/issues/62163.

Differential Revision: https://reviews.llvm.org/D149001
2023-04-24 14:37:07 +02:00
Nikita Popov
22eb8342bf [InstSimplify] Move more folds into simplifyDivRem() (NFCI)
The threading folds are the same for div/rem and the isDivZero()
fold only differes in the return value.

This should be NFC, but as this slightly shuffles around the
order of the folds it might not be exactly the same.
2023-04-24 14:26:55 +02:00
Nikita Popov
34d2d7f565 [InstSimplify] Drop redundant div fold (NFCI)
This is nowadays handled generically via isDivZero() and icmp
simplification, specifically the computeConstantRange() based
logic.
2023-04-24 14:14:02 +02:00
Nikita Popov
77b010474e [InstSimplify] Move fold into isDivZero() (NFCI)
This is a special case where we know the division result is zero.
For the unsigned case this is handled by generic icmp code, for
the signed case we do need to special case it.
2023-04-24 12:44:52 +02:00
Congcong Cai
ee3a260e78 [InstCombine] support fold select(X|Y,X|Y,X) to X|Y
Fixed: https://github.com/llvm/llvm-project/issues/62113
Add addtional check in `visitSelectInst` to:
1. match `select(X|Y==0, X, X|Y)` and replaced with `X|Y`
2. match `select(X&Y==-1, X, X&Y)` and replaced with `X&Y`

alive proof:
https://alive2.llvm.org/ce/z/4qHmv-
https://alive2.llvm.org/ce/z/c2MBGy

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D148275
2023-04-17 22:07:01 +02:00
Matt Arsenault
a517b4ad2d InstSimplify: Perform cheaper check first 2023-04-14 14:36:56 -04:00
Nikita Popov
0b88adacd6 [InstSimplify] Add MaxRecurse argument to simplifyInstructionWithOperands (NFC) 2023-04-14 11:19:19 +02:00
Nikita Popov
c508e93327 [InstSimplify] Remove unused ORE argument (NFC) 2023-04-14 10:38:32 +02:00
Craig Topper
1f60c8d025 [IR] Replace calls to ConstantFP::getNullValue with ConstantFP::getZero. NFC
There is no getNullValue in ConstantFP. Due to inheritance, we're calling
Constant::getNullValue which handles any type including FP.
Since we already know we want an FP constant we can use ConstantFP::getZero
which might be faster and is a more readable name for an FP zero.
2023-04-03 23:14:02 -07:00
Noah Goldstein
87c97d052c [InstSimplify] Extend simplifications for (icmp ({z|s}ext X), C) where C is vector
Previous logic only applied for `ConstantInt` which misses all vector
cases. New code works for splat/non-splat vectors as well. No change
to the underlying simplifications.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D147275
2023-04-03 11:04:57 -05:00
Arthur Eubanks
3f23c7f5be [InstSimplify] Actually use NewOps for calls in simplifyInstructionWithOperands
Resolves a TODO.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D146599
2023-03-22 09:22:00 -07:00
Arthur Eubanks
852cfc2ed3 [NFC] Fix incorrect comment for simplifyRightShift 2023-03-21 12:05:37 -07:00
Paul Walker
62e46f2621 [LLVM] Remove support for constant scalable vector GEPs.
This work has fallen out from D134648 as a requirement to loosen
the "constness" of vscale.

Differential Revision: https://reviews.llvm.org/D145404
2023-03-14 16:48:33 +00:00
Nikita Popov
be687aff05 [InstSimplify] Adjust context instruction when threading phi (PR61312)
When threading operations over phis, we need to adjust the context
instruction to the terminator of the incoming block. This was
handled when threading icmps, but not when threading binops.

Fixes https://github.com/llvm/llvm-project/issues/61312.
2023-03-10 10:34:27 +01:00
Noah Goldstein
46864f3b68 [InstSimplify] Simplify (shl nsw nuw X, BitWidth - 1) -> 0
https://alive2.llvm.org/ce/z/uFy5zT

Reviewed By: nikic, spatel

Differential Revision: https://reviews.llvm.org/D145327
2023-03-06 20:29:53 -06:00
Zhongyunde
15d5c59280 [InstCombine] Improvement the analytics through the dominating condition
Address the dominating condition, the urem fold is benefit from the analytics improvements.
Fix https://github.com/llvm/llvm-project/issues/60546

NOTE: delete the calls in simplifyBinaryIntrinsic and foldICmpWithDominatingICmp
is used to reduce compile time.

Reviewed By: nikic, arsenm, erikdesjardins
Differential Revision: https://reviews.llvm.org/D144248
2023-03-01 17:03:34 +08:00
Sanjay Patel
ae2322a0dc [InstSimplify] enhance simplifyWithOpReplaced() to allow more 'select' removal
This is a generalization of a suggestion from issue #60799
that allows removing a redundant guard of an input value
via icmp+select. It should also solve issue #60801.

This only comes into play for a select with an equality
condition where we are trying to substitute a constant into
the false arm of a select. (A 'true' select arm substitution
allows "refinement", so it is not on this code path.)

The constant must be the same in the compare and the select,
and it must be a "binop absorber" (X op C = C). That query
currently includes 'or', 'and', and 'mul', so there are tests
for all of those opcodes.

We then use "impliesPoison" on the false arm binop and the
original "Op" to be replaced to ensure that the select is not
actually blocking poison from leaking. That could be
potentially expensive as we recursively test each operand, but
it is currently limited to a depth of 2. That's enough to catch
our motivating cases, but probably nothing more complicated
(although that seems unlikely).

I don't know how to generalize a proof for Alive2 for this, but
here's a positive and negative test example to help illustrate
the subtle logic differences of poison/undef propagation:
https://alive2.llvm.org/ce/z/Sz5K-c

Differential Revision: https://reviews.llvm.org/D144493
2023-02-21 17:03:40 -05:00
Nikita Popov
4d192f2d2a [InstSimplify][CaptureTracking] Reduce scope of special case
As described in PR54002, the "icmp of load from global" special
case in CaptureTracking is incorrect, as is the InstSimplify code
that makes use of it.

This moves the special case from CaptureTracking into InstSimplify
to limit its scope to the buggy transform only, and not affect
other code using CaptureTracking as well.
2023-02-21 09:01:55 +01:00
Nikita Popov
be88b5814d [InstCombine] Call simplifyLoadInst()
InstCombine is supposed to be a superset of InstSimplify, but
failed to invoke load simplification.

Unfortunately, this causes a minor compile-time regression, which
will be mitigated in a future commit.
2023-02-20 10:49:44 +01:00
Matt Devereau
8299c764bd [InstSimplify] Simplify icmp between Shl instructions of the same value
define i1 @compare_vscales() {
  %vscale = call i64 @llvm.vscale.i64()
  %vscalex2 = shl nuw nsw i64 %vscale, 1
  %vscalex4 = shl nuw nsw i64 %vscale, 2
  %cmp = icmp ult i64 %vscalex2, %vscalex4
  ret i1 %cmp
}

This IR is currently emitted by LLVM. This icmp is redundant as this snippet
can be simplified to true or false as both operands originate from the same
@llvm.vscale.i64() call.

Differential Revision: https://reviews.llvm.org/D142542
2023-02-20 09:25:34 +00:00
Kohei Asano
a4d6c7dd99 [InstSimplify] Fold LoadInst for uniform constant global variables
Fold LoadInst for uniformly initialized constants, even if there
are non-constant GEP indices.

Goal proof: https://alive2.llvm.org/ce/z/oZtVby

Motivated by https://github.com/rust-lang/rust/issues/107208

Differential Revision: https://reviews.llvm.org/D144184
2023-02-20 09:43:52 +01:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Nikita Popov
eeb125659c [InstSimplify] Slightly optimize simplifyLoad() (NFC)
Check upfront whether the load is based on a constant global
with definitive initializer. Don't bother computing offsets
otherwise.
2023-02-16 10:41:23 +01:00
Nikita Popov
9ca2c309ab [InstSimplify] Fix poison safety in insertvalue fold
We can only fold insertvalue undef, (extractvalue x, n) to x
if x is not poison, otherwise we might be replacing undef with
poison (https://alive2.llvm.org/ce/z/fnw3c8). The insertvalue
poison case is always fine.

I didn't go to particularly large effort to preserve cases where
folding with undef is still legal (mainly when there is a chain of
multiple inserts that end up covering the whole aggregate),
because this shouldn't really occur in practice: We should always
be generating the insertvalue poison form when constructing
aggregates nowadays.

Differential Revision: https://reviews.llvm.org/D144106
2023-02-16 09:39:44 +01:00