1. Remove 'AllModes' and 'DefaultMode' suffixes for DecoderTables under
default HwMode.
2. Introduce a less aggressive suppression for HwMode DecoderTable, only
reduce necessary tables duplications. This allows encodings under
different HwModes to retain the original DecoderNamespace.
3. Change 'suppress-per-hwmode-duplicates' command option from bool type
to enum type, allowing users to choose what level of suppression to use.
This is needed to provide proper size and offset for the GPRPair subreg
indices on RISC-V. The size of a GPR already uses HwMode. Previously we
said the subreg indices have unknown size and offset, but this stops
DwarfExpression::addMachineReg from being able to find the registers
that make up the pair.
I believe this fixes https://github.com/llvm/llvm-project/issues/85864
but need to verify.
Currently operand constraint checks on "$dest = $src" are inadvertently
accepting any token that contains "=". This has surprising results, e.g,
"$dest != $src" is accepted as a constraint but then treated as "=".
This patch ensures that only exactly the token "=" is accepted.
If the second instruction is commutable, we should be able to check
its commutable operands.
A simple RISCV fusion is contained in this PR to show the functionality
is correct, I may remove it when landing.
Fixes#82738
APX assembly syntax recommendations:
https://cdrdv2.intel.com/v1/dl/getContent/817241
NOTE:
The change in llvm/tools/llvm-exegesis/lib/X86/Target.cpp is for test
LLVM ::
tools/llvm-exegesis/X86/latency/latency-SETCCr-cond-codes-sweep.s
For `SETcc`, llvm-exegesis would randomly choose 1 other instruction to
test with `SETcc`, after selecting the instruction, llvm-exegesis would
check if the operand is initialized and valid, if not
`randomizeTargetMCOperand` would choose a value for invalid operand, it
misses support for condition code operand, which cause the flaky failure
after `CCMP` supported.
llvm-exegesis can choose `CCMP` without specifying ccmp feature b/c it
use `MCSubtarget` and only16/32/64 bit is considered.
llvm-exegesis doesn't choose other instructions b/c requirement in
`hasAliasingRegistersThrough`: the instruction should use GPR (defined
by `SETcc`) and define `EFLAGS` (used by `SETcc`).
Add members "leafConstructs" and "association" to .td describing
OpenMP/ACC directives. The naming follows the terminology used in the
OpenMP standard: a "leaf" construct is a construct that is itself not a
composition or a combination of other constructs, and "association" is
the source language construct to which the directive applies (e.g. loop,
block, etc.)
The tblgen-generated output then contains two additional functions
- getLeafConstructs(D), and
- getDirectiveAssociation(D)
plus "enum class Association", all in namespaces "llvm::omp" and
"llvm::acc".
Note: getLeafConstructs returns an empty sequence for a construct that
is itself a leaf construct.
Use the new functions to simplify a few OpenMP-related functions in
clang.
This restores commit c7fdd8c11e.
Previously reverted in f010b1bef4.
LLVM function calls carry convergence control tokens as operand bundles, where
the tokens themselves are produced by convergence control intrinsics. This patch
implements convergence control tokens in MIR as follows:
1. Introduce target-independent ISD opcodes and MIR opcodes for convergence
control intrinsics.
2. Model token values as untyped virtual registers in MIR.
The change also introduces an additional ISD opcode CONVERGENCECTRL_GLUE and a
corresponding machine opcode with the same spelling. This glues the convergence
control token to SDNodes that represent calls to intrinsics. The glued token is
later translated to an implicit argument in the MIR.
The lowering of calls to user-defined functions is target-specific. On AMDGPU,
the convergence control operand bundle at a non-intrinsic call is translated to
an explicit argument to the SI_CALL_ISEL instruction. Post-selection adjustment
converts this explicit argument to an implicit argument on the SI_CALL
instruction.
Original commit 79889734b9.
Perviously reverted in commit a2afcd5721.
LLVM function calls carry convergence control tokens as operand bundles, where
the tokens themselves are produced by convergence control intrinsics. This patch
implements convergence control tokens in MIR as follows:
1. Introduce target-independent ISD opcodes and MIR opcodes for convergence
control intrinsics.
2. Model token values as untyped virtual registers in MIR.
The change also introduces an additional ISD opcode CONVERGENCECTRL_GLUE and a
corresponding machine opcode with the same spelling. This glues the convergence
control token to SDNodes that represent calls to intrinsics. The glued token is
later translated to an implicit argument in the MIR.
The lowering of calls to user-defined functions is target-specific. On AMDGPU,
the convergence control operand bundle at a non-intrinsic call is translated to
an explicit argument to the SI_CALL_ISEL instruction. Post-selection adjustment
converts this explicit argument to an implicit argument on the SI_CALL
instruction.
Previously, tblgen would reject patterns where one of its nested
instructions produced more than one result. These arise when the
instruction definition contains 'outs' as well as 'Defs'. This patch
fixes that by always taking the first result, which is how these
situations are handled in SelectionIDAG.
Original patch: https://reviews.llvm.org/D86617
Continued as: https://github.com/llvm/llvm-project/pull/81130
Currently the decoder and encoder emitters will crash if DefaultMode is
used within an EncodingByHwMode. As can be done today for
RegInfoByHwMode and ValueTypeByHwMode, this patch adds support for this
usage in EncodingByHwMode:
let EncodingInfos =
EncodingByHwMode<[ModeA, DefaultMode], [EncA, EncDefault]>;
Forming a `ReadAdvance` with an entry in the `ValidWrites` list that is
not used by any instruction results in the entire `ReadAdvance` to be
ignored by the scheduler due to an invalid entry.
The `SchedRW` collection code only picks up `SchedWrites` that are
reachable from `Instructions`, `InstRW`, `ItinRW` and `SchedAlias`,
leaving the unreachable ones with an invalid entry (0) in
`SubtargetEmitter::GenSchedClassTables` when going through the list of
`ReadAdvances`
`__CLAUSE_NO_CLASS` was not undefined inside the
`GEN_CLANG_CLAUSE_CLASS` block, resulting in macro redifinition warnings
when several generated directives are used simultaneously.
Currently, for per-HwMode encoding/decoding, those instructions that do
not have a HwMode override are duplicated into the decoder tables for
all HwModes. This includes inducing multiple tables for instructions
that are otherwise unrelated (e.g., different namespace with no
overrides at all).
This patch adds support to suppress instruction and table duplicates.
TableGen option "-gen-disassembler --suppress-per-hwmode-duplicates"
enables the suppression (off by default).
For one downstream backend with a complicated ISA and major
cross-generation encoding differences, this eliminates ~32000 duplicate
table entries at the time of this patch.
There are legitimate reasons to suppress or not suppress duplicates. If
there are relatively few non-overridden related instructions, it can be
convenient to pull them into the per-mode tables (only need to decode
the per-mode tables, slightly simpler decode function in disassembler).
On the other hand, in some backends, the opposite is true or the size is
too large to tolerate any duplication in the first place. We let the
user decide which makes sense.
This is currently off by default, though there is no reason it couldn't
be enabled by default. Any existing backends downstream using the
per-HwMode feature will function as before. Turning on the feature
requires minor modifications to their disassembler due to more/less
tables and naming.
LLVM function calls carry convergence control tokens as operand bundles, where
the tokens themselves are produced by convergence control intrinsics. This patch
implements convergence control tokens in MIR as follows:
1. Introduce target-independent ISD opcodes and MIR opcodes for convergence
control intrinsics.
2. Model token values as untyped virtual registers in MIR.
The change also introduces an additional ISD opcode CONVERGENCECTRL_GLUE and a
corresponding machine opcode with the same spelling. This glues the convergence
control token to SDNodes that represent calls to intrinsics. The glued token is
later translated to an implicit argument in the MIR.
The lowering of calls to user-defined functions is target-specific. On AMDGPU,
the convergence control operand bundle at a non-intrinsic call is translated to
an explicit argument to the SI_CALL_ISEL instruction. Post-selection adjustment
converts this explicit argument to an implicit argument on the SI_CALL
instruction.
Today, if any instruction uses EncodingInfos/EncodingByHwMode to
override the default encoding, the opcode field of the decoder table is
generated incorrectly. This causes failed disassemblies and other
problems.
Specifically, the main correctness issue is that the EncodingID is
inadvertently stored in the table rather than the actual opcode. This is
caused by having set up the IndexOfInstruction map incorrectly during
the loop to populate NumberedEncodings-- which is then propagated around
when OpcMap is set up with a bad EncodingIDAndOpcode.
Instead, do away with IndexOfInstruction altogether and use opcode value
queried from CodeGenTarget::getInstrIntValue to set up OpcMap. This
itself exposed another problem where emitTable was using the decoded
opcode to index into NumberedEncodings. Instead pass in the
EncodingIDAndOpcode vector, and create the reverse mapping from Opcode
to EncodingID, which is then used to index NumberedEncodings.
This problem is not currently exposed upstream since no in-tree targets
yet use the per-HwMode feature. It does show up in at least two
downstream targets.
Summary:
This patch adds a new intrinsic and builtin function mirroring the
existing `__builtin_readcyclecounter`. The difference is that this
implementation targets a separate counter that some targets have which
returns a fixed frequency clock that can be used to determine elapsed
time, this is different compared to the cycle counter which often has
variable frequency.
This patch only adds support for the NVPTX and AMDGPU targets.
This is done as a new and separate builtin rather than an argument to
`readcyclecounter` to avoid needing to change existing code and to make
the separation more explicit.
Currently, for some tables involving a single primary key field which is
integral and densely numbered, a direct lookup is generated rather than
a binary search. This patch extends the direct lookup function
generation to instructions, where the integral value corresponds to the
instruction's enum value.
While this isn't as common as for other tables, it does occur in at
least one downstream backend and one in-tree backend.
Added a unit test and minimally updated the documentation.
We can use `deftype` (not using `typedef` here to be consistent
with `def`, `defm`, `defset`, `defvar`, etc) to define type aliases.
Currently, only primitive types and type aliases are supported to be
the source type and `deftype` statements can only appear at the top
level.
Reviewers: fpetrogalli, Artem-B, nhaehnle, jroelofs
Reviewed By: jroelofs, nhaehnle, Artem-B
Pull Request: https://github.com/llvm/llvm-project/pull/79570
Both OPC_ExtractField and OPC_CheckField are currently defined to take
an unsigned 8-bit start value. On some architectures with long
instruction words, this value can silently overflow, resulting in a bad
decoder table.
This patch changes each to take a ULE128B-encoded start value instead.
Additionally, a range assertion is added for the 8-bit length to
prominently notify a user in case that field ever overflows.
This problem isn't currently exposed upstream since all in-tree targets
use small instruction words (i.e., bitwidth <= 64 bits). It does show up
in at least one downstream target with instructions > 64 bits long.
Co-authored-by: Jason Eckhardt <jeckhardt@nvidia.com>
`Fusion` is inherited from `SubtargetFeature` now. Each definition
of `Fusion` will define a `SubtargetFeature` accordingly.
Method `getMacroFusions` is added to `TargetSubtargetInfo`, which
returns a list of `MacroFusionPredTy` that will be evaluated by
MacroFusionMution.
`getMacroFusions` will be auto-generated if the target has `Fusion`
definitions.
This tries to fix a bug by resolving a few FIXMEs. The bug is that
`EraseInstAction` is emitted after emitting the _first_ `BuildMIAction`,
which is too early because the erased instruction may still be used by
subsequent `BuildMIAction`s (in particular, by `CopyRenderer`).
An example of the bug (from `match-table-operand-types.td`):
```
def InstTest0 : GICombineRule<
(defs root:$a),
(match (G_MUL i32:$x, i32:$b, i32:$c),
(G_MUL $a, i32:$b, i32:$x)),
(apply (G_ADD i64:$tmp, $b, i32:$c),
(G_ADD i8:$a, $b, i64:$tmp))>;
GIR_EraseFromParent, /*InsnID*/0,
GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_ADD),
GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // a
GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/1, // b
GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/0,
```
Here, the root instruction is destroyed before copying its operands ('a'
and 'b') to the new instruction.
The solution is to emit `EraseInstAction` for the root instruction as
the last action in the emission pipeline.
We record the usage of each `Predicate` and sort them by usage.
For the top 8 `Predicate`s, we will emit a `PC_CheckPredicateN` to
save one byte.
Overall this reduces the llc binary size with all in-tree targets by
about 61K.
This is a recommit of 1a57927, which was reverted in bc98c31.
The CI failures occurred when doing expensive checks (with option
`LLVM_ENABLE_EXPENSIVE_CHECKS` being ON).
The key point here is that we need stable sorting result in the
test, but doing expensive checks uncovered the non-determinism of
`llvm::sort`. So `llvm::sort` is changed to `llvm::stable_sort`
in this revised patch.
And we use `llvm::MapVector` to keep insertion order.
We record the usage of each `Predicate` and sort them by usage.
For the top 8 `Predicate`s, we will emit a `PC_CheckPredicateN` to
save one byte.
Overall this reduces the llc binary size with all in-tree targets by
about 61K.