Skip to content

Conversation

s-barannikov
Copy link
Contributor

@s-barannikov s-barannikov commented Sep 1, 2025

There are two classes of operands that DecoderEmitter cannot currently handle:

  1. Operands that do not participate in instruction encoding.
  2. Operands whose encoding contains no '?' bits (that is, only 0s and 1s).

Because of this, targets developed various workarounds. Some targets insert missing operands after an instruction has been (incompletely) decoded, other take into account the missing operands when printing the instruction. Some targets do neither of that and fail to correctly disassemble some instructions.

This patch makes it possible to decode both classes of operands and allows to remove post-decoding instruction adjustments.

For the case of operand with no contribution to instruction encoding, one should now add bits<0> OpName field to instruction encoding record. This will make DecoderEmitter generate a call to the decoder function specified by the operand's DecoderMethod. The function has a signature different from the usual one and looks like this:

static DecodeStatus DecodeImm42Operand(MCInst &Inst, const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createImm(42));
  return DecodeStatus::Success;
}

Notably, encoding bits are not passed to it (since there are none).

There is nothing special about the second case, the operand bits are passed as usual. The difference is that before this change, the function was not called if all the bits of the operand were known (no '?' in the operand encoding).

There are two options controlling the behavior. Passing an option enables the old behavior. They exist to allow smooth transition to the new behavior. They are temporary (yeah, I know) and will be removed once all targets migrate, possibly giving some more time to downstream targets.

Subsequent patches in the stack enable the new behavior on some in-tree targets.

Copy link

github-actions bot commented Sep 1, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@s-barannikov
Copy link
Contributor Author

Something went wrong with the graphite -_-
Sorry if that spammed someone

@s-barannikov s-barannikov changed the title [MLIR] Apply clang-tidy fixes for readability-container-size-empty in VectorTransforms.cpp (NFC) [TableGen][Decoder] Decode operands with zero width or all bits known Sep 1, 2025
@s-barannikov s-barannikov force-pushed the users/s.barannikov/decoder-operands-0 branch from 3e6a846 to d950e97 Compare September 1, 2025 18:19
@s-barannikov s-barannikov marked this pull request as ready for review September 1, 2025 18:55
@llvmbot

This comment was marked as outdated.

@llvmbot

This comment was marked as outdated.

@jayfoad jayfoad requested review from kosarev and rampitec September 3, 2025 16:34
@jurahul
Copy link
Contributor

jurahul commented Sep 3, 2025

Overall, the decoder emitter changes LGTM. I'll let other folks here chime in on the individual target changes.

@s-barannikov s-barannikov force-pushed the users/s.barannikov/decoder-operands-0 branch 2 times, most recently from 3e5abcd to 99327a7 Compare September 3, 2025 20:17
@jurahul
Copy link
Contributor

jurahul commented Sep 3, 2025

Would it also make sense to add this comment?

// Represents a span of bits in the instruction encoding that's based on a span
// of bits in an operand's encoding.
//
// Width is the width of the span.
// Base is the starting position of that span in the instruction encoding.
// Offset if the starting position of that span in the operand's encoding.
// That is, bits {Base + Width - 1, Base} in the instruction encoding form
// bits {Offset + Width - 1, Offset} in the operands encoding.
struct EncodingField {

If you want to incorporate it here, or I can create a separate PR as well.

@s-barannikov
Copy link
Contributor Author

s-barannikov commented Sep 3, 2025

Would it also make sense to add this comment?

// Represents a span of bits in the instruction encoding that's based on a span
// of bits in an operand's encoding.
//
// Width is the width of the span.
// Base is the starting position of that span in the instruction encoding.
// Offset if the starting position of that span in the operand's encoding.
// That is, bits {Base + Width - 1, Base} in the instruction encoding form
// bits {Offset + Width - 1, Offset} in the operands encoding.
struct EncodingField {

If you want to incorporate it here, or I can create a separate PR as well.

Please create a separate PR and also borrow that comment we discussed so that this PR gets smaller after rebasing.

@jurahul
Copy link
Contributor

jurahul commented Sep 3, 2025

Would it also make sense to add this comment?

// Represents a span of bits in the instruction encoding that's based on a span
// of bits in an operand's encoding.
//
// Width is the width of the span.
// Base is the starting position of that span in the instruction encoding.
// Offset if the starting position of that span in the operand's encoding.
// That is, bits {Base + Width - 1, Base} in the instruction encoding form
// bits {Offset + Width - 1, Offset} in the operands encoding.
struct EncodingField {

If you want to incorporate it here, or I can create a separate PR as well.

Please create a separate PR and also borrow that comment we discussed so that this PR gets smaller after rebasing.

Sounds good, will do,

@jurahul
Copy link
Contributor

jurahul commented Sep 3, 2025

Borrowed the comment, if you want to revert that part.

s-barannikov added a commit that referenced this pull request Sep 4, 2025
The `$asr18` operand is not decoded/encoded/printed,
and ASR18 is already in the `Uses` list.
Extracted from #156358, where the extra operand causes DecoderEmitter
to emit an error about an operand with a missing encoding.
@s-barannikov s-barannikov force-pushed the users/s.barannikov/decoder-operands-0 branch from 99327a7 to 743d22e Compare September 4, 2025 13:37
s-barannikov added a commit that referenced this pull request Sep 4, 2025
The operand is not encoded, decoded, or printed and would break MCInst
verification if we had one.
Extracted from #156358, where the extra operand causes DecoderEmitter
to emit an error about an operand with a missing encoding.
@s-barannikov s-barannikov force-pushed the users/s.barannikov/decoder-operands-0 branch from 743d22e to a4624de Compare September 4, 2025 14:14
@s-barannikov
Copy link
Contributor Author

Can I get an approval here? I've extracted most of the target-specific changes into separate PRs, and the ones that remain should be trivial.

@s-barannikov s-barannikov enabled auto-merge (squash) September 4, 2025 14:30
@s-barannikov s-barannikov merged commit ed3597e into main Sep 4, 2025
9 checks passed
@s-barannikov s-barannikov deleted the users/s.barannikov/decoder-operands-0 branch September 4, 2025 14:48
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 4, 2025

LLVM Buildbot has detected a new failure on builder llvm-clang-aarch64-darwin running on doug-worker-4 while building llvm at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/26729

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'lld :: MinGW/driver.test' FAILED ********************
Exit Code: 127

Command Output (stdout):
--
# RUN: at line 1
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld -### foo.o -m i386pe 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=X86 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld '-###' foo.o -m i386pe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=X86 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 7
echo "-### foo.o -m i386pe" > /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/lld/test/MinGW/Output/driver.test.tmp.rsp
# executed command: echo '-### foo.o -m i386pe'
# note: command had no output on stdout or stderr
# RUN: at line 8
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld @/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/lld/test/MinGW/Output/driver.test.tmp.rsp 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=X86 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld @/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/tools/lld/test/MinGW/Output/driver.test.tmp.rsp
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=X86 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 10
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld -### foo.o -m i386pep 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=X64 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld '-###' foo.o -m i386pep
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=X64 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 16
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld -### foo.o -m thumb2pe 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld '-###' foo.o -m thumb2pe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 22
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld -### foo.o -m arm64pe 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM64 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld '-###' foo.o -m arm64pe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM64 /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 28
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld -### foo.o -m arm64ecpe 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM64EC /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld '-###' foo.o -m arm64ecpe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM64EC /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# note: command had no output on stdout or stderr
# RUN: at line 34
/Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld -### foo.o -m arm64xpe 2>&1 | /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM64X /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/ld.lld '-###' foo.o -m arm64xpe
# note: command had no output on stdout or stderr
# executed command: /Volumes/RAMDisk/buildbot-root/aarch64-darwin/build/bin/FileCheck -check-prefix=ARM64X /Users/buildbot/buildbot-root/llvm-project/lld/test/MinGW/driver.test
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants