3554 Commits

Author SHA1 Message Date
Roman Lebedev
1337821f11
[DAGCombiner][X86] Fold a CONCAT_VECTORS of SHUFFLE_VECTOR and it's operand into wider SHUFFLE_VECTOR
This was showing as a source of *many* regressions
with more aggressive ZERO_EXTEND_VECTOR_INREG recognition.
2023-01-01 23:18:42 +03:00
Roman Lebedev
e4d25a9c23
[DAG] BUILD_VECTOR: absorb ZERO_EXTEND of a single first operand if all other ops are zeros
This kind of pattern seems to come up as regressions
with better ZERO_EXTEND_VECTOR_INREG recognition.

For initial implementation, this is quite restricted
to the minimal viable transform, otherwise there are
too many regressions to be dealt with.
2022-12-31 00:58:11 +03:00
Dmitry Borisenkov
0ec51a460a DAG: Prevent store value forwarding to distinct addrspace load
DAGCombiner replaces (load const_addr1) directly chained with (store
(val, const_addr2)) with val if address space stripped const_addr1 ==
const_addr2. The patch fixes the issue by checking address spaces as
well.  However, it might makes sense to not to chain together side
effects that belong to different address spaces in the first place and
make SelectionDAG::root address space aware.
2022-12-29 18:19:55 -05:00
Roman Lebedev
248567a327
[DAGCombiner] Try to partition ISD::EXTRACT_VECTOR_ELT to accomodate it's ISD::BUILD_VECTOR users
This mainly cleans up a few patterns that are legalized by scalarization
from a wide-element vector, but then are further split apart to build
a more narrow-sized-element vector. In particular this happens in some
cases for illegal ISD::ZERO_EXTEND_VECTOR_INREG.

Given a ISD::EXTRACT_VECTOR_ELT, which is a glorified bit sequence extract,
recursively analyse all of it's users. and try to model themselves as
bit sequence extractions. If all of them agree on the new, narrower element
type, and all of them can be modelled as ISD::EXTRACT_VECTOR_ELT's of that
new element type, do that, but only if unmodelled users are ISD::BUILD_VECTOR.
2022-12-30 01:15:53 +03:00
Roman Lebedev
c4f815d705
[DAGCombine] combineShuffleToZeroExtendVectorInReg(): widen shuffle elements before trying to match
We might have sunk a bitcast into shuffle, and now it might be operating
on more fine-grained elements than what we'd match, so we must not be
dependent on whatever the granularity the shuffle happened to be in,
but transform it into the one canonical for us - with widest elements.
2022-12-27 00:47:45 +03:00
Roman Lebedev
e26e7ed69a
[DAG] combineShuffleToZeroExtendVectorInReg(): try to match w/ commuted operands
We don't have any reason to expect that the operand we will match
is on any particular hand of the shuffle, so we should try both.
2022-12-26 22:54:03 +03:00
Roman Lebedev
62fc5f1640
[DAGCombiner] Add a most basic combineShuffleToZeroExtendVectorInReg()
Sometimes we end up with a shuffles in DAG that would be
better represented as a `ISD::ZERO_EXTEND_VECTOR_INREG`,
and a failure to do so causes suboptimal codegen in a number of cases,
especially when we will then cast vector to scalar.

I acknowledge, the test changes here are rather underwhelming,
but as with all of codegen, it's always a yak shawing,
and this is the most stripped down version of the patch
that shows *some* effect without having insurmountable amount
of fallout to deal with. The next change resolves this regression.

The transformation will be extended in follow-ups.
2022-12-26 22:54:03 +03:00
Roman Lebedev
2f6aef52f2
[NFC][DAGCombiner] canCombineShuffleToAnyExtendVectorInreg(): take matcher as callback 2022-12-26 03:56:58 +03:00
Roman Lebedev
84ea72679e
[NFC][DAG] canCombineShuffleToAnyExtendVectorInreg(): check for legal op before matching
Likewise as with legal types check, might as well not match if won't use.
2022-12-26 01:43:49 +03:00
Roman Lebedev
2999c45050
[NFC][DAGCombiner] Extract canCombineShuffleToAnyVectorExtendInReg() helper
Adding zero-ext support isn't as straight-forward, and it's easier
to to so in a new function, but this helper is useful there.
This does not change any existing behaviour.
2022-12-26 01:04:47 +03:00
Roman Lebedev
6aa7359387
[NFC][DAG] combineShuffleToVectorExtend(): check that the type is legal first
There is no point in doing any of the potentially-costly matching
if we will inevitably give up anyway.
2022-12-26 01:03:59 +03:00
Roman Lebedev
03e848293e
[DAGCombiner] visitFREEZE(): fix cycle breaking
Depending on the particular DAG, we might either create a `freeze`,
or not. And only in the former case, the cycle would be formed.
It would be nicer to have `ReplaceAllUsesOfValueWithIf()`,
like we have in IR, but we don't have that.

Fixes https://github.com/llvm/llvm-project/issues/59677
2022-12-23 18:16:22 +03:00
Roman Lebedev
d8f541efe7
[DAGCombiner] visitFREEZE(): fix handling of no maybe-poison ops
The original code was confusing. It was stripping poison-generating flags,
but the comments were saying that doing so was a TODO.

If the poison-generating flags are present, then even if all operands
are guaranteed not to be undef or poison, the whole operation may still
produce undef or poison. We can still deal with that case,
and we already do deal with it in fact, by also dropping those flags.

Refs. https://github.com/llvm/llvm-project/issues/59676
2022-12-23 17:26:05 +03:00
Roman Lebedev
d7a63a0421
[DAGCombiner] visitFREEZE(): restore previous behaviour on no maybe-poison operands
Lack of such operands implies that the op might be poison-producing due to
it's flags. We seem to drop them already, but the comments are confusing.

Fixes https://github.com/llvm/llvm-project/issues/59676
2022-12-23 17:26:05 +03:00
Roman Lebedev
6fea27662d
[DAGCombiner] visitFREEZE(): be less greedy with replacing other uses of undef 2022-12-23 02:26:36 +03:00
Roman Lebedev
f738ab9075
[DAGCombiner] visitFREEZE(): allow multiple maybe-poison operands for BUILD_VECTOR 2022-12-23 02:26:36 +03:00
Roman Lebedev
114cc45a09
[NFC][DAGCombiner] visitFREEZE(): use early return 2022-12-23 02:26:36 +03:00
Roman Lebedev
f5700e7b69
[DAGCombine][X86] Pull one-use freeze out of extract_vector_elt vector operand
This may allow us to further simplify the vector,
and freezing the extracted result is still fine:
```
----------------------------------------
define i8 @src(<2 x i8> %src, i64 %idx) {
%0:
  %i1 = freeze <2 x i8> %src
  %i2 = extractelement <2 x i8> %i1, i64 %idx
  ret i8 %i2
}
=>
define i8 @tgt(<2 x i8> %src, i64 %idx) {
%0:
  %i1 = extractelement <2 x i8> %src, i64 %idx
  %i2 = freeze i8 %i1
  ret i8 %i2
}
Transformation seems to be correct!
```

BUT, there must not be other uses of that freeze,
see `@freeze_extractelement_extra_use`.

Also, looks like we are missing some ISEL-level handling for freeze.
2022-12-23 00:03:26 +03:00
Roman Lebedev
23bc8f730d
[DAGCombiner] visitFREEZE(): allow, and update, other uses of maybe-poison operand 2022-12-22 23:23:19 +03:00
Craig Topper
3f811b26ef [DAGCombine] Fix mistake in a comment. NFC 2022-12-21 00:28:07 -08:00
Fangrui Song
036e092282 [CodeGen] 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).

This fixes LLVMMIRParser, LLVMGlobalISel, LLVMAsmPrinter, LLVMSelectionDAG.
2022-12-16 23:41:36 +00:00
Juan Manuel MARTINEZ CAAMAÑO
4d852374b1 [DAGCombine] Fix always true condition in combineShiftToMULH
Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D139550
2022-12-15 13:04:42 +01:00
Kazu Hirata
6eb0b0a045 Don't include Optional.h
These files no longer use llvm::Optional.
2022-12-14 21:16:22 -08:00
Fangrui Song
67819a72c6 [CodeGen] llvm::Optional => std::optional 2022-12-13 09:06:36 +00:00
David Green
fd716925ec [DAGCombine] Fold Splat(bitcast(buildvector(x,..))) to splat(x)
This adds a fold which teaches the backend to fold
splat(bitcast(buildvector(x,..))) or
splat(bitcast(scalar_to_vector(x))) to a single splat.

This only handles lane 0 splats, which are only valid under LE, and
needs to be a little careful with the types it creates for the new
buildvector.

Differential Revision: https://reviews.llvm.org/D139611
2022-12-12 08:35:43 +00:00
jacquesguan
c2f199fa48 [DAGCombiner] Scalarize extend/truncate for splat vector.
This revision scalarizes extend/truncate for splat vector.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D122875
2022-12-12 14:53:10 +08:00
Xiang1 Zhang
7557d94bd8 [NFC] Update comment for TRUNC followed by a masked store 2022-12-12 11:24:57 +08:00
Xiang1 Zhang
9c88ccf9a9 [DAG] Stop combine for masked compressstore
Reviewed By: WangPengfei

Differential Revision: https://reviews.llvm.org/D139682
2022-12-12 10:40:20 +08:00
Kazu Hirata
f7dffc28b3 Don't include None.h (NFC)
I've converted all known uses of None to std::nullopt, so we no longer
need to include None.h.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-10 11:24:26 -08:00
Kazu Hirata
8a7cbea525 [llvm] Use std::nullopt instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-08 23:22:00 -08:00
Kazu Hirata
9f252e5567 [llvm] Use std::nullopt instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04 17:31:17 -08:00
Kazu Hirata
3c09ed006a [llvm] Use std::nullopt instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04 17:12:44 -08:00
Kazu Hirata
998960ee1f [CodeGen] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02 20:36:08 -08:00
Sanjay Patel
0037e21f28 [SDAG] bail out of mergeTruncStores() if there's any other use in the chain
This fixes the miscompile in issue #58883.

The test demonstrates that we gave up on store merging in that example.

This change should be strictly safe (just adds another clause
to avoid the transform), and it does not prohibit any existing
valid optimizations based on regression tests. I want to believe
that it's also a sufficient fix (possibly overkill), but I'm not
sure how to prove that.

Differential Revision: https://reviews.llvm.org/D137791
2022-12-02 10:08:19 -05:00
Simon Pilgrim
30eff7f29f [DAG] Attempt to replace a mul node with an existing umul_lohi/smul_lohi node (PR59217)
As discussed on Issue #59217, under certain circumstances the DAG can generate duplicate MUL and MUL_LOHI nodes, often during MULO legalization.

This patch attempts to replace MUL nodes with additional uses of the LO result from the MUL_LOHI node

Differential Revision: https://reviews.llvm.org/D138790
2022-11-29 12:51:30 +00:00
Kazu Hirata
dd698b7777 [SelectionDAG] Use std::optional in DAGCombiner.cpp (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-26 15:00:23 -08:00
chenglin.bi
cdb7b804f6 [DAGCombiner] fold or (xor x, y),? patterns
or (xor x, y), x --> or x, y
or (xor x, y), y --> or x, y
or (xor x, y), (and x, y) --> or x, y
or (xor x, y), (or x, y) --> or x, y

Reviewed By: foad

Differential Revision: https://reviews.llvm.org/D138401
2022-11-23 09:28:10 +08:00
Han-Kuan Chen
caa9f63022 [CodeGen] Refactor visitSCALAR_TO_VECTOR. NFC.
Differential Revision: https://reviews.llvm.org/D137688
2022-11-22 01:29:04 -08:00
chenglin.bi
ac1b999e85 [DAGCombiner] fold or (and x, y), x --> x
Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D138398
2022-11-21 22:11:12 +08:00
Benjamin Maxwell
34d88cf6cf [DAG] Allow folding AND of anyext masked_load with >1 user to zext version
This now allows folding an AND of a anyext masked_load to a
zext_masked_load even if the masked load has multiple users.  Doing is
eliminates some redundant ANDs/MOVs for certain AArch64 SVE code.

I'm not sure if there's any cases where doing this could negatively the
other users of the masked_load.  Looking at other optimizations of
masked loads, most don't apply if the load is used more than once, so it
doesn't look like this would interfere.

Reviewed By: c-rhodes

Differential Revision: https://reviews.llvm.org/D137844
2022-11-18 10:38:09 +00:00
Stanislav Mekhanoshin
bcaf31ec3f [AMDGPU] Allow finer grain control of an unaligned access speed
A target can return if a misaligned access is 'fast' as defined
by the target or not. In reality there can be different levels
of 'fast' and 'slow'. This patch changes the boolean 'Fast'
argument of the allowsMisalignedMemoryAccesses family of functions
to an unsigned representing its speed.

A target can still define it as it wants and the direct translation
of the current code uses 0 and 1 for current false and true. This
makes the change an NFC.

Subsequent patch will start using an actual value of speed in
the load/store vectorizer to compare if a vectorized access going
to be not just fast, but not slower than before.

Differential Revision: https://reviews.llvm.org/D124217
2022-11-17 09:23:53 -08:00
zhongyunde
8fbb6f8678 [NFC] Fix typo in comment
Address comment in https://reviews.llvm.org/D137936

Differential Revision: https://reviews.llvm.org/D138124
2022-11-16 23:35:53 +08:00
Sanjay Patel
fe05a0a3dd [SDAG] avoid udiv/urem transform for vector/scalar type mismatches
This solves the crashing from issue #58994.
I don't know anything about VE, so I don't know if the output
is as expected or even correct.
2022-11-15 11:01:18 -05:00
Amaury Séchet
82209fd96e [NFC] Refactor DAGCombiner::foldSelectOfConstants to reduce nesting 2.0 2022-11-05 17:10:06 +00:00
Amaury Séchet
7c05f092c9 [NFC] Refactor DAGCombiner::foldSelectOfConstants to reduce nesting 2022-11-05 16:17:58 +00:00
Simon Pilgrim
78739fdb4d [DAG] Enable combineShiftOfShiftedLogic folds after type legalization
This was disabled to prevent regressions, which appear to be just occurring on AMDGPU (at least in our current lit tests), which I've addressed by adding AMDGPUTargetLowering::isDesirableToCommuteWithShift overrides.

Fixes #57872

Differential Revision: https://reviews.llvm.org/D136042
2022-10-29 12:30:04 +01:00
Sanjay Patel
1e7c1dd67c [SDAG] avoid crash from mismatched types in scalar-to-vector fold
This bug was introduced with D136713 / 54eeadcf442df91aed0 .

As an enhancement, we could cast operands to the expected type,
but we need to make sure that is done correctly (zext vs. sext).
It's also possible (but seems unlikely) that an operand can have
a type larger than the result type.

Fixes #58661
2022-10-28 09:14:08 -04:00
Simon Pilgrim
d47f056cd2 [DAG] visitXOR - fold XOR(A,B) -> OR(A,B) iff A and B have no common bits
Alive2: https://alive2.llvm.org/ce/z/7wvfns

Part of Issue #58624
2022-10-28 12:11:12 +01:00
Simon Pilgrim
28bfd853ab [DAG] visitFSUBForFMACombine - pass callbacks by reference in isContractableAndReassociableFMUL lambda capture. NFC.
Fixes a coverity remark about large copies by value
2022-10-28 11:48:45 +01:00
Pierre van Houtryve
088a816824 [DAGCombiner] Use getAnyExtOrTrunc instead of TRUNCATE in ExtractVectorElt combine
ScalarVT isn't guaranteed to be smaller than the BCSrc.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D136849
2022-10-28 06:33:29 +00:00