8234 Commits

Author SHA1 Message Date
Nikita Popov
002da67d01 [InstCombine] Require ImmConstant in shift of shift fold
This fixes an infinite loop reported at:
82f68a992b (commitcomment-132406739)
2023-11-13 14:56:06 +01:00
Yingwei Zheng
44cdbef715
[InstCombine] Infer nneg flag from shift users (#71947)
This patch sets `nneg` flag when the zext is only used by a shift.

Alive2: https://alive2.llvm.org/ce/z/h3xKjP
Compile-time impact:
https://llvm-compile-time-tracker.com/compare.php?from=bd611264993f64decbce178d460caf1d1cb05f59&to=26bc473b239010bb24ff1bc39d58b42ecbbc4730&stat=instructions:u

This is an alternative to #71906.
2023-11-13 21:05:05 +08:00
Léonard Oest O'Leary
ff36411b23
[InstCombine] Use zext's nneg flag for icmp folding (#70845)
This PR fixes https://github.com/llvm/llvm-project/issues/55013 : the
max intrinsics is not generated for this simple loop case :
https://godbolt.org/z/hxz1xhMPh. This is caused by a ICMP not being
folded into a select, thus not generating the max intrinsics.

For the story :

Since LLVM 14, SCCP pass got smarter by folding sext into zext for
positive ranges : https://reviews.llvm.org/D81756. After this change,
InstCombine was sometimes unable to fold ICMP correctly as both of the
arguments pointed to mismatched zext/sext. To fix this, @rotateright
implemented this fix : https://reviews.llvm.org/D124419 that tries to
resolve the mismatch by knowing if the argument of a zext is positive
(in which case, it is like a sext) by using ValueTracking, however
ValueTracking is not smart enough to infer that the value is positive in
some cases. Recently, @nikic implemented #67982 which keeps the
information that a zext is non-negative. This PR simply uses this
information to do the folding accordingly.

TLDR : This PR uses the recent nneg tag on zext to fold the icmp
accordingly in instcombine.

This PR also contains test cases for sext/zext folding with InstCombine
as well as a x86 regression tests for the max/min case.
2023-11-13 00:53:53 +08:00
David Green
73af455f57
[InstCombine] Handle more scalable geps in EmitGEPOffset (#71699)
Following up on #71565, this makes scalable splats in EmitGEPOffset use
the ElementCount as opposed to assuming it is fixed width, and attempts
to handle scalable offsets with vector geps by splatting the vscale to
each vector lane.
2023-11-11 18:21:31 +00:00
Nikita Popov
c2a1966627 [InstCombine] Remove bitcast handling from SimplifyDemandedBits
The complex set of type checks in this code reduces down to
"always return nullptr". Drop the code to use the default
implementation instead, which will just compute the KnownBits
for the bitcast.
2023-11-10 15:25:39 +01:00
Noah Goldstein
9ef829097b [InstCombine] Fix buggy transform in foldNestedSelects; PR 71330
The bug is that `IsAndVariant` is used to assume which arm in the
select the output `SelInner` should be placed but match the inner
select condition with `m_c_LogicalOp`. With fully simplified ops, this
works fine, but its possible if the select condition is not
simplified, for it match both `LogicalAnd` and `LogicalOr` i.e `select
true, true, false`.

In PR71330 for example, the issue occurs in the following IR:
```
define i32 @bad() {
  %..i.i = select i1 false, i32 0, i32 3
  %brmerge = select i1 true, i1 true, i1 false
  %not.cmp.i.i.not = xor i1 true, true
  %.mux = zext i1 %not.cmp.i.i.not to i32
  %retval.0.i.i = select i1 %brmerge, i32 %.mux, i32 %..i.i
  ret i32 %retval.0.i.i
}
```

When simplifying:
```
%retval.0.i.i = select i1 %brmerge, i32 %.mux, i32 %..i.i
```

We end up matching `%brmerge` as `LogicalAnd` for `IsAndVariant`, but
the inner select (`%..i.i`) condition which is `false` with
`LogicalOr`.

Closes #71489
2023-11-09 16:36:49 -06:00
Noah Goldstein
5cc9347aa3 [InstCombine] Add reduced test for PR 71330; NFC 2023-11-09 16:36:49 -06: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
0bd0d721cd [InstCombine] Add test for zext nneg miscompile (NFC)
Exposed by https://github.com/llvm/llvm-project/pull/71534 and
reported there.
2023-11-09 11:58:02 +01:00
David Green
3ccbd68480
[InstCombine] Handle scalable geps in EmitGEPOffset (#71565)
This adds scalable handling for scalable vectors in emitGEPOffset. This
was noticed in some tests that Biplob was creating, so might be unlikely
to come up much in practice. I've attempted to add test coverage for
various places EmitGEPOffset is called. The vscale intrinsics will
currently emit multiple copies, relying on later CSE to combine them.
2023-11-08 15:50:32 +00:00
Nikita Popov
567c02a80e [InstCombine] Remove inttoptr/ptrtoint handling from indexed compare fold
Looking through inttoptr / ptrtoint intermixed with GEPs is very
questionable from a provenance perspective. We also don't seem to
have any test coverage that shows this is useful (apart from one
test I added to guard against a crash).
2023-11-08 11:13:57 +01:00
Nikita Popov
5918f62301
[InstCombine] Infer zext nneg flag (#71534)
Use KnownBits to infer the nneg flag on zext instructions.

Currently we only set nneg when converting sext -> zext, but don't set
it when we have a zext in the first place. If we want to use it in
optimizations, we should make sure the flag inference is consistent.
2023-11-08 09:34:40 +01:00
Antonio Frighetto
7d39838948 [InstCombine] Favour CreateZExtOrTrunc in narrowFunnelShift (NFC)
Use `CreateZExtOrTrunc`, reduce test and regenerate checks.
2023-11-07 22:48:14 +01:00
Anna Thomas
f0cdf4b468 [InstCombine] Check FPMathOperator for Ctx before FMF check
We need to check FPMathOperator for Ctx instruction before checking fast
math flag on this Ctx.

Ctx is not always an FPMathOperator, so explicitly check for it.

Fixes #71548.
2023-11-07 10:50:19 -05:00
Antonio Frighetto
caa124b58d [InstCombine] Zero-extend shift amounts in narrow funnel shift ops
An issue arose when handling shift amounts while performing
narrowed funnel shifts simplification. Specifically, shift
amounts were incorrectly truncated when their type was
narrower than the target bit width. This has been addressed
by zero-extending `ShAmt` in such cases.

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

Proof: https://alive2.llvm.org/ce/z/5draKz.
2023-11-07 14:15:32 +01:00
Nikita Popov
17764d2c87
[IR] Remove FP cast constant expressions (#71408)
Remove support for the fptrunc, fpext, fptoui, fptosi, uitofp and sitofp
constant expressions. All places creating them have been removed
beforehand, so this just removes the APIs and uses of these constant
expressions in tests.

With this, the only remaining FP operation that still has constant
expression support is fcmp.

This is part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
2023-11-07 09:34:16 +01:00
Philip Reames
23099ac239
Add known and demanded bits support for zext nneg (#70858)
zext nneg was recently added to the IR in #67982.   This patch teaches
demanded bits and known bits about the semantics of the instruction, and
adds a couple of test cases to illustrate basic functionality.
2023-11-06 18:47:56 -08:00
LiqinWeng
5d3d08463d
[InstCombinePHI] Remove dead PHI on UnaryOperator (#71386)
This patch mainly solves the problem of dead PHI on UnaryOperator
2023-11-07 09:45:33 +08:00
Noah Goldstein
ad9147399f [InstCombine] Improve eq/ne by parts to handle ult/ugt equality pattern.
(icmp eq/ne (lshr x, C), (lshr y, C) gets optimized to `(icmp
ult/uge (xor x, y), (1 << C)`. This can cause the current equal by
parts detection to miss the high-bits as it may get optimized to the
new pattern.

This commit adds support for detecting / combining the ult/ugt
pattern.

Closes #69884
2023-11-04 19:00:28 -05:00
Noah Goldstein
9fea6bbf26 [InstCombine] Add tests for new eq/ne patterns combining eq/ne by parts; NFC 2023-11-04 19:00:23 -05:00
Nikita Popov
e4a4122eb6
[IR] Remove zext and sext constant expressions (#71040)
Remove support for zext and sext constant expressions. All places
creating them have been removed beforehand, so this just removes the
APIs and uses of these constant expressions in tests.

There is some additional cleanup that can be done on top of this, e.g.
we can remove the ZExtInst vs ZExtOperator footgun.

This is part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
2023-11-03 10:46:07 +01:00
Nikita Popov
060de415af Reapply [InstCombine] Simplify and/or of icmp eq with op replacement (#70335)
Relative to the first attempt, this contains two changes:

First, we only handle the case where one side simplifies to true or
false, instead of calling simplification recursively. The previous
approach would return poison if one operand simplified to poison
(under the equality assumption), which is incorrect.

Second, we do not fold llvm.is.constant in simplifyWithOpReplaced().
We may be assuming that a value is constant, if the equality holds,
but it may not actually be constant. This is nominally just a QoI
issue, but the std::list implementation in libstdc++ relies on the
precise behavior in a way that causes miscompiles.

-----

and/or in logical (select) form benefit from generic simplifications via
simplifyWithOpReplaced(). However, the corresponding fold for plain
and/or currently does not exist.

Similar to selects, there are two general cases for this fold
(illustrated with `and`, but there are `or` conjugates).

The basic case is something like `(a == b) & c`, where the replacement
of a with b or b with a inside c allows it to fold to true or false.
Then the whole operation will fold to either false or `a == b`.

The second case is something like `(a != b) & c`, where the replacement
inside c allows it to fold to false. In that case, the operand can be
replaced with c, because in the case where a == b (and thus the icmp is
false), c itself will already be false.

As the test diffs show, this catches quite a lot of patterns in existing
test coverage. This also obsoletes quite a few existing special-case
and/or of icmp folds we have (e.g. simplifyAndOrOfICmpsWithLimitConst),
but I haven't removed anything as part of this patch in the interest of
risk mitigation.

Fixes #69050.
Fixes #69091.
2023-11-03 10:16:15 +01:00
Philip Reames
9593cde70b
[instcombine] Drop zext nneg flag when simplify operand (#71088)
This fixes a miscompile introduced in the recent #67982, and likely
exposed in changes since to infer and leverage the same. No active bug
reports as of yet.

This was noticed in
https://github.com/llvm/llvm-project/pull/70858#discussion_r1378203532.
2023-11-02 11:43:57 -07:00
Philip Reames
3b589fe6e6 [tests] Add coverage for demanded bits of zext nneg
Precommit of tests from 70858, requested in review.
2023-11-02 11:08:08 -07:00
David Green
fee2953f23
[ARM] Fix for undef elements from demanded elements (#70504)
I think this is right, that the undef bits should be the undef bits from
the passthrough (operand 0), with the top/bottom lanes cleared, as they
come from the second arg (operand 1). We don't yet attempt to look for
undef elements in the second operand, but this should fix the bug with
all elements being marked as undef and the instruction being optimized
away.
2023-11-02 14:28:40 +00:00
Noah Goldstein
bd29197fd8 [InstCombine] Fold (ptrtoint (ptrmask p0, m0)) -> (and (ptrtoint p0), m0)
`and` is generally more supported so if we have a `ptrmask` anyways
might as well use `and`.

Differential Revision: https://reviews.llvm.org/D156640

Closes #67166
2023-11-01 23:50:36 -05:00
Noah Goldstein
cc8341872d [InstCombine] Preserve return attributes when merging llvm.ptrmask
If we have assosiated attributes i.e `([ret_attrs] (ptrmask (ptrmask
p0, m0), m1))` we should preserve `[ret_attrs]` when combining the two
`llvm.ptrmask`s.

Differential Revision: https://reviews.llvm.org/D156638
2023-11-01 23:50:36 -05:00
Noah Goldstein
51abbf98d1 [InstCombine] Deduce align and nonnull return attributes for llvm.ptrmask
We can deduce the former based on the mask / incoming pointer
alignment.  We can set the latter based if know the result in non-zero
(this is essentially just caching our analysis result).

Differential Revision: https://reviews.llvm.org/D156636
2023-11-01 23:50:35 -05:00
Noah Goldstein
edb9e9a5fb [InstCombine] Implement SimplifyDemandedBits for llvm.ptrmask
Logic basically copies 'and' but we can't return a constant if the
result == rhs (mask) so that case is skipped.
2023-11-01 23:50:35 -05:00
Noah Goldstein
2c5f2b33ae [InstCombine] Add tests for combining llvm.ptrmask; NFC
Differential Revision: https://reviews.llvm.org/D156634
2023-11-01 23:50:35 -05:00
Noah Goldstein
8c2fcf5b77 [InstSimplify] Add some basic simplifications for llvm.ptrmask
Mostly the same as `and`. We also have a check for a useless
`llvm.ptrmask` if the ptr is already known aligned.

Differential Revision: https://reviews.llvm.org/D156633
2023-11-01 23:50:35 -05:00
Nikita Popov
c7f0e49915 [InstCombine] Fix canAlwaysEvaluateInTy() with constant exprs
The m_ZExtOrSExt / m_Trunc in the following code can match constant
expressions, which we don't want here. Make sure we bail out early
for non-immediate constants.
2023-11-01 14:52:50 +01:00
Nikita Popov
aca9c891a2 [InstCombine] Avoid use of ConstantExpr::getIntegerCast()
Require that constants are ImmConstant for this transform, as we
may otherwise generate constant expressions, which are not
necessarily free.
2023-11-01 12:56:30 +01:00
Philip Reames
3f2ed812f0
[InstCombine] Infer nneg on zext when forming from non-negative sext (#70706)
Builds on #67982 which recently introduced the nneg flag on a zext
instruction. InstCombine is one of our largest canonicalizers of zext
from non-negative sext instructions, so set the flag there.
2023-10-30 12:09:43 -07:00
Philip Reames
89564f0b69 Regenerate a set of auto-update tests [nfc]
To reduce the spurious test delta in an upcoming change.
2023-10-30 11:36:43 -07:00
Nikita Popov
e46dd6fbc0 Revert "[InstCombine] Simplify and/or of icmp eq with op replacement (#70335)"
This reverts commit 1770a2e325192f1665018e21200596da1904a330.

Stage 2 llvm-tblgen crashes when generating X86GenAsmWriter.inc and
other files.
2023-10-30 18:33:03 +01:00
Nikita Popov
1770a2e325
[InstCombine] Simplify and/or of icmp eq with op replacement (#70335)
and/or in logical (select) form benefit from generic simplifications via
simplifyWithOpReplaced(). However, the corresponding fold for plain
and/or currently does not exist.

Similar to selects, there are two general cases for this fold
(illustrated with `and`, but there are `or` conjugates).

The basic case is something like `(a == b) & c`, where the replacement
of a with b or b with a inside c allows it to fold to true or false.
Then the whole operation will fold to either false or `a == b`.

The second case is something like `(a != b) & c`, where the replacement
inside c allows it to fold to false. In that case, the operand can be
replaced with c, because in the case where a == b (and thus the icmp is
false), c itself will already be false.

As the test diffs show, this catches quite a lot of patterns in existing
test coverage. This also obsoletes quite a few existing special-case
and/or of icmp folds we have (e.g. simplifyAndOrOfICmpsWithLimitConst),
but I haven't removed anything as part of this patch in the interest of
risk mitigation.

Fixes #69050.
Fixes #69091.
2023-10-30 10:05:39 +01:00
Nikita Popov
ed3f06b9b3
[IR] Add zext nneg flag (#67982)
Add an nneg flag to the zext instruction, which specifies that the
argument is non-negative. Otherwise, the result is a poison value.

The primary use-case for the flag is to preserve information when sext
gets replaced with zext due to range-based canonicalization. The nneg
flag allows us to convert the zext back into an sext later. This is
useful for some optimizations (e.g. a signed icmp can fold with sext but
not zext), as well as some targets (e.g. RISCV prefers sext over zext).

Discourse thread: https://discourse.llvm.org/t/rfc-add-zext-nneg-flag/73914

This patch is based on https://reviews.llvm.org/D156444 by
@Panagiotis156, with some implementation simplifications and additional
tests.

---------

Co-authored-by: Panagiotis K <karouzakispan@gmail.com>
2023-10-30 09:04:04 +01:00
Amara Emerson
2228b35f93 Revert "Revert "[InstCombine] Add oneuse checks to shr + cmp constant folds.""
This reverts commit d37b283cdd37feca5ea71456cf350005add268e7.

There was a simple logic bug in the else path. Tests codegen is different with
the fix.
2023-10-28 03:12:15 -07:00
Noah Goldstein
0289dad538 [InstCombine] Add folds for (icmp eq/ne (and (add/sub/xor A, P2), P2), 0/P2)
- `(icmp eq/ne (and (add/sub/xor X, P2), P2), P2)`
    -> `(icmp eq/ne (and X, P2), 0)`
- `(icmp eq/ne (and (add/sub/xor X, P2), P2), 0)`
    -> `(icmp eq/ne (and X, P2), P2)`

Folds like this come up with reasonable regularity in odd/even loops.

Proofs: https://alive2.llvm.org/ce/z/45pq2x

Closes #67836
2023-10-27 17:36:30 -05:00
Noah Goldstein
731bdcef2e [InstCombine] Add tests for folding (icmp eq/ne (and (add/sub/xor A, P2), P2), 0/P2); NFC 2023-10-27 17:36:30 -05:00
Amara Emerson
d37b283cdd Revert "[InstCombine] Add oneuse checks to shr + cmp constant folds."
This reverts commit a66051c68a43af39f9fd962f71d58ae0efcf860d.

This seems to have caused issue #70509 so reverting until I have time
to investigate.
2023-10-27 14:27:58 -07:00
David Green
58bdd165d5 [ARM] Add a test for incorrect demand bits / undef fold. NFC 2023-10-27 16:38:46 +01:00
Alex Richardson
0359a78f77 Add target REQUIRES to 3 more tests
These tests all need an x86 backend for the correct data layout.
2023-10-26 17:41:05 -07:00
Alex Richardson
1e029cf53b Add missing REQUIRES lines to unbreak buildbots
Since e39f6c1844fab59c638d8059a6cf139adb42279a these tests require
a valid target in order to compute the data layout.
2023-10-26 14:28:40 -07:00
Alex Richardson
e39f6c1844 [opt] Infer DataLayout from triple if not specified
There are many tests that specify a target triple/CPU flags but no
DataLayout which can lead to IR being generated that has unusual
behaviour. This commit attempts to use the default DataLayout based
on the relevant flags if there is no explicit override on the command
line or in the IR file.

One thing that is not currently possible to differentiate from a missing
datalayout `target datalayout = ""` in the IR file since the current
APIs don't allow detecting this case. If it is considered useful to
support this case (instead of passing "-data-layout=" on the command
line), I can change IR parsers to track whether they have seen such a
directive and change the callback type.

Differential Revision: https://reviews.llvm.org/D141060
2023-10-26 12:07:37 -07:00
Amara Emerson
a66051c68a [InstCombine] Add oneuse checks to shr + cmp constant folds.
This change has virtually no code size regressions on the llvm test suite (+ SPECs)
while having these improvements (measured with -Os on Darwin arm64):

External/S.../CFP2006/450.soplex/450.soplex    214024.00      213920.00     -0.0%
External/S...7speed/641.leela_s/641.leela_s     93412.00       93348.00     -0.1%
External/S...17rate/541.leela_r/541.leela_r     93412.00       93348.00     -0.1%
MultiSourc.../Applications/JM/lencod/lencod    426044.00      425748.00     -0.1%
MultiSourc...rks/mediabench/gsm/toast/toast     20436.00       20416.00     -0.1%
MultiSourc...ench/telecomm-gsm/telecomm-gsm     20436.00       20416.00     -0.1%
MultiSourc...Prolangs-C/assembler/assembler     16172.00       16156.00     -0.1%
MultiSourc...nch/mpeg2/mpeg2dec/mpeg2decode     35332.00       35256.00     -0.2%
SingleSour...Adobe-C++/stepanov_abstraction      6904.00        6888.00     -0.2%
External/SPEC/CINT2000/254.gap/254.gap         366060.00      365132.00     -0.3%
MultiSourc...-ProxyApps-C++/PENNANT/PENNANT     79688.00       79484.00     -0.3%
External/S...NT2006/464.h264ref/464.h264ref    352044.00      351132.00     -0.3%
SingleSour...arks/Adobe-C++/functionobjects     15524.00       15480.00     -0.3%
SingleSour...arks/Adobe-C++/stepanov_vector     10728.00       10696.00     -0.3%
SingleSour...ks/Misc-C++/stepanov_container     16900.00       16848.00     -0.3%
MultiSource/Applications/oggenc/oggenc         124184.00      123780.00     -0.3%
SingleSour...tout-C++/Shootout-C++-wordfreq      7060.00        7036.00     -0.3%
MultiSourc...ity-rijndael/security-rijndael      8976.00        8936.00     -0.4%
MultiSource/Benchmarks/McCat/18-imp/imp          9816.00        9772.00     -0.4%
SingleSour...chmarks/Misc-C++/stepanov_v1p2      1772.00        1764.00     -0.5%
MultiSourc...iabench/g721/g721encode/encode      5492.00        5464.00     -0.5%
MultiSourc...rks/McCat/03-testtrie/testtrie      1364.00        1344.00     -1.5%
SingleSour.../execute/GCC-C-execute-pr42833       400.00         364.00     -9.0%

Doing so also prevents a regression described in https://reviews.llvm.org/D143624

Differential Revision: https://reviews.llvm.org/D149918
2023-10-26 11:36:10 -07:00
Nikita Popov
b47ff36134
[InstCombine] Drop exact flag instead of increasing demanded bits (#70311)
Demanded bit simplification for lshr/ashr will currently demand the low
bits if the exact flag is set. This is because these bits must be zero
to satisfy the flag.

However, this means that our demanded bits simplification is worse for
lshr/ashr exact than it is for plain lshr/ashr, which is generally not
desirable.

Instead, drop the exact flag if a demanded bits simplification of the
operand succeeds, which may no longer satisfy the exact flag.

This matches what we do for the exact flag on udiv, as well as the
nuw/nsw flags on add/sub/mul.
2023-10-26 13:12:30 +02:00
Nikita Popov
cf3ac964dc [InstCombine] Add additional demanded bits tests for shifts (NFC) 2023-10-26 11:03:58 +02:00
Nikita Popov
f386045640 [InstCombine] Test extra and use in processUMulZExtIdiom() fold (NFC) 2023-10-25 10:52:39 +02:00