Commit Graph

312 Commits

Author SHA1 Message Date
Amara Emerson
6c31f20fee [GlobalISel] Fold fmul x, 1.0 -> x (#65379) 2023-09-06 03:14:16 +08:00
Amara Emerson
08e04209d8 [GlobalISel] Commute G_FMUL and G_FADD constant LHS to RHS. (#65298) 2023-09-05 23:48:34 +08:00
Amara Emerson
91746d15d2 [GlobalISel] Fix G_PTR_ADD immediate chain combine using the wrong im… (#65271) 2023-09-05 08:06:40 +08:00
Amara Emerson
0065640f40 [GlobalISel] Look through a G_PTR_ADD's def register instead of it's source operand's
uses when looking for load/store users. This was a simple logic bug during translation
of the equivalent function in SelectionDAG:
```
    for (SDNode *Node : N->uses()) {
      if (auto *LoadStore = dyn_cast<MemSDNode>(Node)) {
```
2023-09-04 00:28:57 -07:00
Amara Emerson
1ef1eec8db [GlobalISel][NFC] Use GenericMachineInstrs in CombinerHelper::reassociationCanBreakAddressingModePattern(). 2023-09-03 21:17:31 -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
Amara Emerson
c95ed6e492 [GlobalISel] Try to commute G_CONSTANT_FOLD_BARRIER LHS operands to RHS.
Differential Revision: https://reviews.llvm.org/D159097
2023-08-30 08:07:22 -07:00
Matt Arsenault
d86a7d631c GlobalISel: Add constant fold combine for zext/sext/anyext
Could use more work for vectors.

https://reviews.llvm.org/D156534
2023-08-24 08:10:01 -04:00
David Green
adaf545a50 [GlobalISel] Limit shift_of_shifted_logic_chain to non-zero folds
After D157690 we are seeing some crashes from Global ISel, which seem to be
related to the shift_of_shifted_logic_chain combine that can remove too many
instructions if the shift amount is zero.

This limits the fold to non-zero shifts, under the assumption that it is better
in that case to fold away the shift to a COPY.

Differential Revision: https://reviews.llvm.org/D158596
2023-08-23 18:17:37 +01:00
pvanhout
2d87319f06 [GlobalISel] Rewrite some simple rules using MIR Patterns
Rewrites some simple rules that cause little to no codegen regressions as MIR patterns.

I may have missed some easy cases, but some other rules have intentionally been left as-is because bigger
changes are needed to make them work.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D157690
2023-08-22 09:09:54 +02:00
Jay Foad
a1a9c53ae7 [GlobalISel] Fix infinite loop in reassociation combine
Don't reassociate (C1+C2)+Y -> C1+(C2+Y).

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

Differential Revision: https://reviews.llvm.org/D155284
2023-07-16 14:15:24 +01:00
Amara Emerson
3a80bdb316 [GlobalISel] Remove an erroneous oneuse check in the G_ADD reassociation combine.
This check was unnecessary/incorrect, it was already being done by the target
hook default implementation, and the one in the matcher was checking for a
completely different thing. This change:
 1) Removes the check and updates affected tests which now do some more reassociations.
 2) Modifies the AMDGPU hooks which were stubbed with "return true" to also do the oneuse
    check. Not sure why I didn't do this the first time.
2023-07-10 01:03:12 -07:00
pvanhout
5eb8cb0949 [NFC][GlobalISel] Don't return bool from apply functions
There is no case where those functions return false. It's always return true.
Even if they were to return false, it's not really something we should rely on I think.
With the current combiner implementation, it would just make `tryCombineAll` return false without retrying anymore rules.

I also believe that if an applyer were to return false, it would mean that the match function is not good enough. Asserting on failure in an apply function is a better idea, IMO.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D153619
2023-06-26 09:23:58 +02:00
Amara Emerson
6f6298e5b3 [GlobalISel] Fix D144336 in a different way, by choosing operands from the first of the div/rem insts.
Differential Revision: https://reviews.llvm.org/D144336
2023-06-09 15:06:06 -07:00
Amara Emerson
086601eac2 [GlobalISel] Implement some binary reassociations, G_ADD for now
- (op (op X, C1), C2) -> (op X, (op C1, C2))
- (op (op X, C1), Y) -> (op (op X, Y), C1)

Some code duplication with the G_PTR_ADD reassociations unfortunately but no
easy way to avoid it that I can see.

Differential Revision: https://reviews.llvm.org/D150230
2023-06-08 21:14:58 -07:00
Mirko Brkusanin
792667dadd [GlobalISel] Check if ShiftAmt is greater then size of operand
matchCombineShlOfExtend did not check if the size of new shift would be
wider then a size of operand. Current condition did not work if the value
being shifted was zero. Updated to support vector splat.

Patch by: Acim Maravic

Differential Revision: https://reviews.llvm.org/D151122
2023-06-08 17:37:59 +02:00
Amara Emerson
fbdcd54442 [GlobalISel] Fix DIVREM combine from inserting a divrem before its operands' defs.
In some rare corner cases where in between the div/rem pair there's a def of
the second instruction's source (but a different vreg due to the combine's
eqivalence checks), it will place the DIVREM at the first instruction's point,
causing a use-before-def. There wasn't an obvious fix that stood out to me
without doing more involved analysis than a combine should really be doing.

Fixes issue #60516

I'm open to new suggestions on how to approach this, as I'm not too happy
at bailing out here. It's not the first time we run into issues with value liveness
that the DAG world isn't affected by.

Differential Revision: https://reviews.llvm.org/D144336
2023-06-04 00:24:38 -07:00
Matt Arsenault
a5e03972f7 GlobalISel: Move fconstant matching into tablegen
I don't really understand what the point of wip_match_opcode is.
It doesn't seem to have any purpose other than to list opcodes
to have all the logic in pure C++. You can't seem to  use it to
select multiple opcodes in the same way you use match.

Something is wrong with it, since the match emitter prints
"errors" if an opcode is covered by wip_match_opcode and
then appears in another pattern. For exmaple with this patch,
you see this several times in the build:

  error: Leaf constant_fold_fabs is unreachable
  note: Leaf idempotent_prop will have already matched

The combines are actually produced and the tests for them
do pass, so this seems to just be a broken warning.
2023-05-19 22:44:12 +01:00
Matt Arsenault
7f54b38e28 GlobalISel: Refactor unary FP op constant folding 2023-05-18 08:33:43 +01:00
Mikael Holmen
6647f3cd01 [CombinerHelper] Fix gcc warning [NFC]
Without the fix gcc complains with
 ../lib/CodeGen/GlobalISel/CombinerHelper.cpp:1652:52: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  1652 |          SrcDef->getOpcode() == TargetOpcode::G_OR && "Unexpected op");
       |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
2023-05-10 09:08:06 +02:00
Amara Emerson
e1472db58e [GlobalISel] Implement commuting shl (add/or x, c1), c2 -> add/or (shl x, c2), c1 << c2
There's a target hook that's called in DAGCombiner that we stub here, I'll
implement the equivalent override for AArch64 in a subsequent patch since it's
used by different shift combine.

This change by itself has minor code size improvements on arm64 -Os CTMark:
Program                                       size.__text
                                              outputg181ppyy output8av1cxfn diff
consumer-typeset/consumer-typeset             410648.00      410648.00       0.0%
tramp3d-v4/tramp3d-v4                         364176.00      364176.00       0.0%
kimwitu++/kc                                  449216.00      449212.00      -0.0%
7zip/7zip-benchmark                           576128.00      576120.00      -0.0%
sqlite3/sqlite3                               285108.00      285100.00      -0.0%
SPASS/SPASS                                   411720.00      411688.00      -0.0%
ClamAV/clamscan                               379868.00      379764.00      -0.0%
Bullet/bullet                                 452064.00      451928.00      -0.0%
mafft/pairlocalalign                          246184.00      246108.00      -0.0%
lencod/lencod                                 428524.00      428152.00      -0.1%
                           Geomean difference                               -0.0%

Differential Revision: https://reviews.llvm.org/D150086
2023-05-08 22:37:43 -07:00
NAKAMURA Takumi
d45fae6010 Move CodeGen/LowLevelType => CodeGen/LowLevelTypeUtils
Before restoring `CodeGen/LowLevelType`, rename this to `LowLevelTypeUtils`.

Differential Revision: https://reviews.llvm.org/D148768
2023-04-25 08:53:17 +09:00
Amara Emerson
29c851f4e2 [GlobalISel] Move the truncstore_merge combine to the LoadStoreOpt pass and add support for an extra case.
If we have set of mergeable stores of shifts, but the original source value being shifted
is wider than the merged size, we should still be able to merge if we truncate first. To do this
however we need to search for stores speculatively up the block, without knowing exactly how
many stores we should see before we stop. The old algorithm has to match an exact number of
stores to fit the wide type, or it dies. The new one will try to set the wide type to however
many stores we found in the upwards block traversal and use later checks to verify if they're
a valid mergeable set.

The reason I need to move this to LoadStoreOpt is because the combiner works going top down
inside a block, which means that we end up doing partial merges because we haven't seen all
the possible stores before we mutate the MIR. In LoadStoreOpt we can go bottom up.

As a side effect of this change, we also end up doing better on an existing test case (missing_store)
since we manage to do a partial merge there.
2023-04-12 16:43:14 -07:00
Amara Emerson
4bc6434624 [GlobalISel] Fix an assertion failure in matchHoistLogicOpWithSameOpcodeHands().
We use this combine in the AArch64 postlegalizer combiner, which causes this
function to query the legalizer rules for the action for an invalid opcode/type
combination (G_AND and p0). Moving the legalizer query until after the validity
check in matchHoistLogicOpWithSameOpcodeHands() fixes this.
2023-02-26 15:42:57 -08:00
Kazu Hirata
9e5d2495ac Use APInt::isOne instead of APInt::isOneValue (NFC)
Note that isOneValue has been soft-deprecated in favor of isOne.
2023-02-19 23:06:36 -08:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Amara Emerson
ddf167c442 [GlobalISel] Fix G_ZEXTLOAD being converted to G_SEXTLOAD incorrectly.
The extending loads combine tries to prefer sign-extends folding into loads vs
zexts, and in cases where a G_ZEXTLOAD is first used by a G_ZEXT, and then used
by a G_SEXT, it would select the G_SEXT even though the load is already
zero-extending.

Fixes issue #59630
2023-02-18 10:05:08 -08:00
Amara Emerson
b309bc04ee [GlobalISel] Combine out-of-range shifts to undef.
Differential Revision: https://reviews.llvm.org/D144303
2023-02-17 15:05:00 -08:00
Kazu Hirata
7e6e636fb6 Use llvm::has_single_bit<uint32_t> (NFC)
This patch replaces isPowerOf2_32 with llvm::has_single_bit<uint32_t>
where the argument is wider than uint32_t.
2023-02-15 22:17:27 -08:00
Pierre van Houtryve
d9a6fc82f5 [AMDGPU] Run unmerge combines post regbankselect
RegBankSelect can insert G_UNMERGE_VALUES in a lot of places which
left us with a lot of unmerge/merge pairs that could be simplified.
These often got in the way of pattern matching and made codegen
worse.

This patch:
  - Makes the necessary changes to the merge/unmerge combines so they can run post RegBankSelect
  - Adds relevant unmerge combines to the list of RegBankSelect combines for AMDGPU
  - Updates some tablegen patterns that were missing explicit cross-regbank copies (V_BFI patterns were causing constant bus violations with this change).

This seems to be mostly beneficial for code quality.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D142192
2023-02-10 08:34:23 +01:00
Vladislav Dzhidzhoev
2a45d061ef [GlobalISel] Don't combine instructions with unknown type in hoist_logic_op_with_same_opcode_hands.
This fixes failure for some LLVM IR.

Differential Revision: https://reviews.llvm.org/D142791
2023-02-01 00:54:15 +01:00
Kazu Hirata
55e2cd1609 Use llvm::count{lr}_{zero,one} (NFC) 2023-01-28 12:41:20 -08:00
Diana Picus
f95a5fbe7c MachineIRBuilder: Rename buildMerge. NFC
`buildMerge` may build a G_MERGE_VALUES, G_BUILD_VECTOR or
G_CONCAT_VECTORS. Rename it to `buildMergeLikeInstr`.

This is a follow-up suggested in https://reviews.llvm.org/D140964

Differential Revision: https://reviews.llvm.org/D141372
2023-01-13 09:32:58 +01:00
Diana Picus
0f831aa805 GlobalISel: s/Op/Instr in some places. NFC
This patch replaces `GMergeLikeOp` with `GMergeLikeInstr` and
`MachineIRBuilder::buildAssertOp` with `buildAssertInstr` in order to
remove ambiguity. Discussed in: https://reviews.llvm.org/D141372
2023-01-13 09:32:58 +01:00
Craig Topper
3f749a5d9d [Support][SelectionDAG][GlobalISel] Hoist PostShift adjustment for IsAdd into UnsignedDivideUsingMagic.
Instead of doing the adjustment in 3 different places in the code
base, do it inside UnsignedDivideUsingMagic::get.

Differential Revision: https://reviews.llvm.org/D141014
2023-01-04 15:18:12 -08:00
Craig Topper
8bca60fb0a [SelectionDAG][GlobalISel] Don't use UnsignedDivisionByConstantInfo for divisor of 1.
The magic algorithm sets IsAdd indication for division by 1 that
the caller had to ignore.

I considered folding the ignore into UnsignedDivisionByConstantInfo,
but we only allow 1 for vectors of mixed visiors. And really what we
want to end up with is undef. Currently, we get to undef via
DemandedElts optimizations using the select instruction. We could
directly emit undef.

Differential Revision: https://reviews.llvm.org/D140940
2023-01-04 10:01:15 -08:00
Craig Topper
84daed7fd4 [SelectionDAG][GlobalISel] Move even divisor optimization for division by constant into UnsignedDivideUsingMagic implementation. NFC
I've added a bool to UnsignedDivideUsingMagic so we can continue
testing it in the unit test with and without this optimization in
the unit test.

This is a step towards supporting "uncooperative" odd divisors.
See https://ridiculousfish.com/blog/posts/labor-of-division-episode-iii.html

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D140924
2023-01-03 16:34:13 -08:00
Matt Arsenault
0dc4bdd888 GlobalISel: Enable CSE of G_SELECT
Stop trying to delete a select in one combine since it would
be deleting the CSE'd instruction if that happened.
2022-12-19 21:26:47 -05:00
Fangrui Song
b1df3a2c0b [Support] llvm::Optional => std::optional
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-16 08:49:10 +00:00
Fangrui Song
67819a72c6 [CodeGen] llvm::Optional => std::optional 2022-12-13 09:06:36 +00:00
Pierre van Houtryve
3612d9eaac [GISel] Rework trunc/shl combine in a generic trunc/shift combine
This combine only handled left shifts, but now it can handle right shifts as well. It handles right shifts conservatively and only truncates them to the size returned by TLI.

AMDGPU benefits from always lowering shifts to 32 bits for instance, but AArch64 would rather keep them at 64 bits.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D136319
2022-12-09 04:46:45 -05: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
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
Kazu Hirata
4531b61208 [GlobalISel] Use std::optional in CombinerHelper.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 14:33:45 -08:00
chenglin.bi
fe07eeb825 [GlobalISel] Fix crash in applyShiftOfShiftedLogic caused by CSEMIRBuilder reuse instruction
If LogicNonShiftReg is the same to Shift1Base, and shift1 const is the same to MatchInfo.Shift2 const, CSEMIRBuilder will reuse the old shift1 when build shift2.
So, if we erase MatchInfo.Shift2 at the end, actually we remove old shift1. And it will cause crash later.

Solution for this issue is just erase it earlier to avoid the crash.

Fix #58423

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D138187
2022-11-19 09:13:44 +08: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
chenglin.bi
8482247900 [GlobalISel] Correct constant type in matchReassocConstantInnerLHS
When we match a pattern from m_GCst, the register type could be different from original op. So we can't replace the original op to vreg direct.
This code create a new constant with original op type then replace the original op.

Fix #58906

Reviewed By: arsenm, aemerson

Differential Revision: https://reviews.llvm.org/D137778
2022-11-13 19:20:07 +08:00
Petar Avramovic
838d5d371a AMDGPU/GlobalISel: Fix combine crash because LI is not set in prelegalizer
Caused by legacy min/max combines (select + cmp) asking for legalizer info
in prelegalizer (D135047 added combine to all_combines).
Combine still does not work for AMDGPU since destination opcode is custom,
not legal. Similar combine works on DAG since it asks for legal or custom.

Differential Revision: https://reviews.llvm.org/D137274
2022-11-08 12:46:16 +01:00
Pierre van Houtryve
020a9d7b20 [GISel] Add (fsub +-0.0, X) -> fneg combine
Allows for better matching of VOP3 mods.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D136442
2022-11-03 08:21:50 +00:00
Jessica Paquette
0f1a51e173 [GlobalISel] Allow vectors in redundant or + add combines
We support KnownBits for vectors, so we can enable these.

https://godbolt.org/z/r9a9W4Gj1

Differential Revision: https://reviews.llvm.org/D135719
2022-10-11 15:31:09 -07:00