2068 Commits

Author SHA1 Message Date
David Green
2802739dfd [NFC] Replace ;; with ; 2023-06-11 10:25:24 +01:00
Matt Arsenault
02d25c82b8 GlobalISel: Remove block insertion legalizer check
This report was broken. The passed null block would crash in the
remark constructor.

I have a patch which will introduce a new block, and it seems to work
fine. It doesn't require legalizing any instructions in the new block,
so it's possible those will be missed.
2023-06-09 21:04:37 -04: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
1c2c668846 [GlobalISel] Introduce G_CONSTANT_FOLD_BARRIER and use it to prevent constant folding
hoisted constants.

The constant hoisting pass tries to hoist large constants into predecessors and also
generates remat instructions in terms of the hoisted constants. These aim to prevent
codegen from rematerializing expensive constants multiple times. So we can re-use
this optimization, we can preserve the no-op bitcasts that are used to anchor
constants to the predecessor blocks.

SelectionDAG achieves this by having the OpaqueConstant node, which is just a
normal constant with an opaque flag set. I've opted to avoid introducing a new
constant generic instruction here. Instead, we have a new G_CONSTANT_FOLD_BARRIER
operation that constitutes a folding barrier.

These are somewhat like the optimization hints, G_ASSERT_ZEXT in that they're
eliminated by the generic instruction selection code.

This change by itself has very minor improvements in -Os CTMark overall. What this
does allow is better optimizations when future combines are added that rely on having
expensive constants remain unfolded.

Differential Revision: https://reviews.llvm.org/D144336
2023-06-09 11:45: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
Matt Arsenault
eece6ba283 IR: Add llvm.ldexp and llvm.experimental.constrained.ldexp intrinsics
AMDGPU has native instructions and target intrinsics for this, but
these really should be subject to legalization and generic
optimizations. This will enable legalization of f16->f32 on targets
without f16 support.

Implement a somewhat horrible inline expansion for targets without
libcall support. This could be better if we could introduce control
flow (GlobalISel version not yet implemented). Support for strictfp
legalization is less complete but works for the simple cases.
2023-06-06 17:07:18 -04: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
Dávid Bolvanský
09515f2c20 [SDAG] Preserve unpredictable metadata, teach X86CmovConversion to respect this metadata
Sometimes an developer would like to have more control over cmov vs branch. We have unpredictable metadata in LLVM IR, but currently it is ignored by X86 backend. Propagate this metadata and avoid cmov->branch conversion in X86CmovConversion for cmov with this metadata.

Example:

```
int MaxIndex(int n, int *a) {
    int t = 0;
    for (int i = 1; i < n; i++) {
        // cmov is converted to branch by X86CmovConversion
        if (a[i] > a[t]) t = i;
    }
    return t;
}

int MaxIndex2(int n, int *a) {
    int t = 0;
    for (int i = 1; i < n; i++) {
        // cmov is preserved
        if (__builtin_unpredictable(a[i] > a[t])) t = i;
    }
    return t;
}
```

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D118118
2023-06-01 20:56:44 +02:00
Jay Foad
5022fc2ad3 [CodeGen] Make use of MachineInstr::all_defs and all_uses. NFCI.
Differential Revision: https://reviews.llvm.org/D151424
2023-06-01 19:17:34 +01:00
Felipe de Azevedo Piovezan
e8aee45be7 [IRTranslator] Implement translation of entry_value dbg.value intrinsics
For dbg.value intrinsics targeting an llvm::Argument address whose expression
starts with an entry value, we lower this to a DEBUG_VALUE targeting the livein
physical register corresponding to that Argument.

Depends on D151328

Differential Revision: https://reviews.llvm.org/D151329
2023-05-26 06:45:01 -04:00
Felipe de Azevedo Piovezan
b5983a38cb [IRTranslator][NFC] Refactor if/else chain into early returns
This will make it easier to add more cases in a subsequent commit and also
better conforms to the coding guidelines.

Differential Revision: https://reviews.llvm.org/D151328
2023-05-25 06:42:44 -04: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
Jay Foad
d8229e2f14 [KnownBits] Define and use intersectWith and unionWith
Define intersectWith and unionWith as two complementary ways of
combining KnownBits. The names are chosen for consistency with
ConstantRange.

Deprecate commonBits as a synonym for intersectWith.

Differential Revision: https://reviews.llvm.org/D150443
2023-05-16 09:23:51 +01:00
Jay Foad
71ac47f391 [KnownBits] Make use of KnownBits.isUnknown. NFC. 2023-05-16 09:19:55 +01:00
Krzysztof Drewniak
0bc739a4ae [GlobalISel] Handle ptr size != index size in IRTranslator, CodeGenPrepare
While the original motivation for this patch (address space 7 on
AMDGPU) has been reworked and is not presently planned to reach IR
translation, the incorrect (by the spec) handling of index offset
width in IR translation and CodeGenPrepare is likely to trip someone
- possibly future AMD, since we have a p7:160:256:256:32 now, so we
convert to the other API now.

Reviewed By: aemerson, arsenm

Differential Revision: https://reviews.llvm.org/D143526
2023-05-12 16:21:01 +00:00
Felipe de Azevedo Piovezan
3f6e4e5b6e [IRTranslator][DebugInfo] Implement translation of entry_value vars
This commit implements IRTranslator lowering of dbg.declare intrinsics targeting
swiftasync Arguments, by putting them in the MachineFunction's table of
variables whose location doesn't change throughout the function.

Depends on D149881

Differential Revision: https://reviews.llvm.org/D149882
2023-05-12 11:55:39 -04: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
Mateja Marjanovic
cf76074a36 [AMDGPU][GlobalISel] Check exact width in get*ClassForBitWidth and widen if necessary
Instead of checking if the given bitwidth is less or equal to a bitwidth of an existing RegClass,
check if it has the exact same value.

For LLVM vector types that don't have a corresponding Register Class, widen them during legalization.
That goes for G_EXTRACT_VECTOR_ELT, G_INSERT_VECTOR_ELT and G_BUILD_VECTOR.

Differential revision: https://reviews.llvm.org/D148096
Reviewers: foad, arsenm
2023-05-03 17:32:24 +02:00
Mateja Marjanovic
6175ec0bb6 Revert "[AMDGPU][GlobalISel] Widen the vector operand in G_BUILD/INSERT/EXTRACT_VECTOR"
This reverts commit b25c7cafcbe1b52ea2d1ff5e5c2f13674b5f297d.
2023-05-03 17:28:01 +02:00
Mateja Marjanovic
b25c7cafcb [AMDGPU][GlobalISel] Widen the vector operand in G_BUILD/INSERT/EXTRACT_VECTOR
Widen the vector operand type in G_BUILD_VECTOR, G_INSERT_VECTOR_ELT,
G_EXTRACT_VECTOR_ELT to the nearest larger RegClass.
2023-05-03 17:14:38 +02:00
NAKAMURA Takumi
5d71ec6e44 Split out CodeGenTypes from CodeGen for LLT/MVT
This reduces dependencies on `llvm-tblgen` so much.

`CodeGenTypes` depends on `Support` at the moment.
Be careful to append deps on this, since Targets' tablegens
depend on this.

Depends on D149024

Differential Revision: https://reviews.llvm.org/D148769
2023-05-03 00:13:20 +09:00
NAKAMURA Takumi
9cfeba5b12 Restore CodeGen/LowLevelType from Support
This is rework of;
  - D30046 (LLT)

Since I have introduced `llvm-min-tblgen` as D146352, `llvm-tblgen`
may depend on `CodeGen`.

`LowLevlType.h` originally belonged to `CodeGen`. Almost all userse are
still under `CodeGen` or `Target`. I think `CodeGen` is the right place
to put `LowLevelType.h`.

`MachineValueType.h` may be moved as well. (later, D149024)

I have made many modules depend on `CodeGen`. It is consistent but
inefficient. It will be split out later, D148769

Besides, I had to isolate MVT and LLT in modmap, since
`llvm::PredicateInfo` clashes between `TableGen/CodeGenSchedule.h`
and `Transforms/Utils/PredicateInfo.h`.
(I think better to introduce namespace llvm::TableGen)

Depends on D145937, D146352, and D148768.

Differential Revision: https://reviews.llvm.org/D148767
2023-05-03 00:13:19 +09:00
Mingming Liu
9879e5865a [InlineAsm][AArch64]Add backend support for flag output parameters
- The set of flag is from https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Flag-Output-Operands

Before:
- ARM64 GCC supports flag output constraints, while Clang doesn't parse condition code, as shown in https://gcc.godbolt.org/z/7jzMEK796
- LLVM ISel won't lower them either (as shown in https://gcc.godbolt.org/z/Pv4PPf56c)

After:
- Given flag output constraints in LLVM IR, condition code is parsed and flag output is lowered to 'cset'.
- Clang parse is not added in this patch.

Differential Revision: https://reviews.llvm.org/D149032
2023-04-26 09:18:41 -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
Shraiysh Vaishay
7021182d6b [nfc][llvm] Replace pointer cast functions in PointerUnion by llvm casting functions.
This patch replaces the uses of PointerUnion.is function by llvm::isa,
PointerUnion.get function by llvm::cast, and PointerUnion.dyn_cast by
llvm::dyn_cast_if_present. This is according to the FIXME in
the definition of the class PointerUnion.

This patch does not remove them as they are being used in other
subprojects.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D148449
2023-04-17 13:40:51 -05:00
Sergei Barannikov
38d84e3d76 [GISel] Legalize G_FSUB to G_FADD + G_FNEG even if G_FNEG is illegal
`G_FNEG` used to be legalized to `G_FSUB -0, x` causing infinite loop.
This is no longer the case after D84287.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D148187
2023-04-15 08:11:49 +03:00
Amara Emerson
719024a0d0 [GlobalISel][NFC] Add MachineInstr::getFirst[N]{Regs,LLTs}() helpers to extract regs & types.
These reduce the typing and clutter from:
Register Dst = MI.getOperand(0).getReg();
Register Src1 = MI.getOperand(1).getReg();
Register Src2 = MI.getOperand(2).getReg();
Register Src3 = MI.getOperand(3).getReg();
LLT DstTy = MRI.getType(Dst);
... etc etc

To just:
auto [Dst, Src1, Src2, Src3] = MI.getFirst4Regs();
auto [DstTy, Src1Ty, Src2Ty, Src3Ty] = MI.getFirst4LLTs();

Or even more concise:
auto [Dst, DstTy, Src1, Src1Ty, Src2, Src2Ty, Src3, Src3Ty] =
     MI.getFirst4RegLLTs();

Differential Revision: https://reviews.llvm.org/D144687
2023-04-12 16:43:14 -07: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
Felipe de Azevedo Piovezan
79a1e32915 [GlobalISel] Improve stack slot tracking in dbg.values
For IR like:

```
%alloca = alloca ...
dbg.value(%alloca, !myvar, OP_deref(<other_ops>))
```

GlobalISel lowers it to MIR:

```
%some_reg = G_FRAME_INDEX <stack_slot>
DBG_VALUE %some_reg, !myvar, OP_deref(<other_ops>)
```

In other words, if the value of `!myvar` can be obtained by
dereferencing an alloca, in MIR we say that the _location_ of a variable
is obtained by dereferencing register %some_reg (plus some
`<other_ops>`).

We can instead remove the use of `%some_reg`: the location of `!myvar`
_is_ `<stack_slot>` (plus some `<other_ops>`). This patch implements
this transformation, which improves debug information handling in O0, as
these registers hardly ever survive register allocation.

A note about testing: similar to what was done in D76934
(f24e2e9eebde4b7a1d), this patch exposed a bug in the Builder class when
using `-debug`, where we tried to print an incomplete instruction. The
changes in `MachineIRBuilder.cpp` address that.

Differential Revision: https://reviews.llvm.org/D147536
2023-04-05 08:21:00 -04:00
Kazu Hirata
b9c4b95b11 [llvm] Use ConstantInt::{isZero,isOne} (NFC) 2023-03-21 17:40:35 -07:00
Matt Arsenault
9356ec1516 CodeGen: Reorder case handling for is.fpclass legalization
Subnormal and zero checks can be combined into one, so move
the code closer to reduce the diff in a future change.
2023-03-17 11:29:50 -04:00
Matt Arsenault
61f2f2c64a GlobalISel: Use FPClassTest in is.fpclass lowering 2023-03-17 10:23:01 -04:00
Aditya Nandakumar
00e55531df [GISel][CSE][NFC]: Handle mutual recursion when inserting node
GISel's CSE mechanism lazily inserts instructions into the CSE List
to improve on efficiency as well as efficacy of CSE
(for allowing partially built instructions to be fully built).

There's unfortunately a mutual recursion via
 `handleRecordedInsts -> handleRecordedInst -> insertNode-> handleRecordedInsts`.

So this change simply records that we're already draining this list so we can just bail out on the recursion.

No changes to codegen are expected as we're still draining/handling the temporary
list via pop_back and we should get the same sequence of instructions
whether we call pop_back in a loop at the top level or recursive.

https://reviews.llvm.org/D145006

reviewed by: dsanders
2023-03-02 14:42:38 -08:00
Vladislav Dzhidzhoev
3a51eed948 [AArch64][GlobalISel] Legalize G_SHUFFLE_VECTOR with smaller dest size
Legalize G_SHUFFLE_VECTOR having destination vector length smaller than
source vector length by reshaping destination vector.

Differential Revision: https://reviews.llvm.org/D144670
2023-02-27 23:46:44 +01: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
Jessica Del
fc672b6a8b [AMDGPU] Improved wide multiplies
These checks show optimized instructions if an operand is known to be
(partially) zero.

Change-Id: Ie2f6d0d3ee9d5b279d1f4c1dd0787492e39cc77a

Differential Revision: https://reviews.llvm.org/D140208
2023-02-22 16:39:06 +01: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
b7ffd9686d Use APInt::getAllOnes instead of APInt::getAllOnesValue (NFC)
Note that getAllOnesValue has been soft-deprecated in favor of
getAllOnes.
2023-02-19 22:54:23 -08:00
Kazu Hirata
f8f3db2756 Use APInt::count{l,r}_{zero,one} (NFC) 2023-02-19 22:04:47 -08:00
Amara Emerson
66d64aac36 [GlobalISel] Fix a store-merging bug due to use of >= instead of >.
This fixes a corner case where we would skip doing an alias check because of a
>= vs > bug, due to the presence of a non-aliasing instruction, in this case
the load %safeld.

Fixes issue #59376
2023-02-19 15:55:50 -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
Chen Zheng
6ee2f770ef [PowerPC][GISel] add support for fpconstant
Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D133340
2023-02-14 02:39:22 +00: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
Jay Foad
d170a254a5 [CodeGen] Define and use MachineOperand::getOperandNo
This is a helper function to very slightly simplify many calls to
MachineInstruction::getOperandNo.

Differential Revision: https://reviews.llvm.org/D143250
2023-02-07 11:50:57 +00: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