Skip to content

[mlir][dxsa] Refine operands#164

Open
tagolog wants to merge 1 commit into
dxsa-mlirfrom
dxsa-mlir-refine-operands
Open

[mlir][dxsa] Refine operands#164
tagolog wants to merge 1 commit into
dxsa-mlirfrom
dxsa-mlir-refine-operands

Conversation

@tagolog

@tagolog tagolog commented Jun 12, 2026

Copy link
Copy Markdown

Example:
dxsa.add r<0>, r<1>, r<2>
dxsa.add_sat r<0>, r<1>, r<2>
dxsa.add r<0>, r<1>, l(1.0, 2.0, 3.0, 4.0)
dxsa.add r<0>, -r<1>, |r<2>|

@tagolog tagolog requested review from asavonic and asl June 12, 2026 02:58
DXSA_SrcOperandAttr:$rhs,
OptionalAttr<DXSA_ComponentMaskAttr>:$precise);
let results = (outs);
let assemblyFormat = "$dst `,` $lhs `,` $rhs attr-dict";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assemblyFormat does not use $precise. Unused?

return success();
}
if (auto intAttr = llvm::dyn_cast<IntegerAttr>(attr)) {
outBits = intAttr.getValue().getZExtValue();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This asserts in the case of value not fitting into 64 bits.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@asavonic asavonic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall. With "default" attributes hidden, text format doesn't look too verbose.

canonical count for the operand type.
- `min16f` / `min2_8f` / `min16i` / `min16u` - the
`#dxsa.operand_min_precision` hint.
- `<chans>` - positional channel list, parsed as a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps rename <chans> to <mask>?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole operand documentation has been reafctored.

StringRef text(out.data(), out.size());
if (text.contains('.'))
return out;
size_t exponentPos = text.find_first_of("eE");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can instead use LLVM write_double function with FloatStyle::Fixed style.

case 4:
return OperandComponents::vector;
default:
return OperandComponents::reserved;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need this? Can we do anything with "reserved" number of components other than to emit an error?

Comment thread mlir/lib/Dialect/DXSA/IR/DXSAOperand.cpp Outdated
/// Parses one literal element of an `l(...)` / `d(...)` payload. Accepts a
/// float literal, a decimal integer, or a hex integer, and reinterprets the
/// value as the raw bit pattern at the requested width.
static ParseResult parseImmValue(AsmParser &parser, bool is64,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need floating point immediate here at all? IIRC, a type is not encoded, just bit size.

The original disassembler prints them as integer and floats, but I think it does this by looking at the corresponding instruction. If an immediate operand is used in an FP instruction, then it is printed as FP. I don't think we have to do the same here.

The point is, to avoid dancing around different formats, we can support only integer format (or hex - whatever format MLIR can parse by default).

@tagolog tagolog force-pushed the dxsa-mlir-refine-operands branch from ce14854 to 2960121 Compare June 12, 2026 18:09
<x>
```
}];
let parameters = (ins ArrayRefParameter<"int64_t">:$channels);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why int64_t? Can it be, say, -1? If not, why not just plain `unsigned?

if (auto intAttr = llvm::dyn_cast<IntegerAttr>(attr)) {
auto width = is64 ? 64u : 32u;
auto value = intAttr.getValue();
if (value.getBitWidth() < width) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that it would automatically accept, say 42 : i13 and just drop the type promoting to 32-bit int? Is sign-extension always desired? Say, we're having 0x7FFFFFFF: i31, you will extend this to 0xFFFFFFFF. Is this ok?

}

template <typename Float, typename UInt>
static bool floatSpellingReparsesToIdenticalBits(Float value, UInt bits) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is terrible.... Do we really need this?

imm.bits = bits;
imm.byteWidth = sizeof(UInt);

// Positive zero is the only value spelled as a bare `0`; every other pattern,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to guess in the IR? This is not in general user-written code. IR should be precise.

//===----------------------------------------------------------------------===//

/// Parses the body of a 32-bit immediate-literal operand.
ParseResult mlir::dxsa::parseImm32Body(AsmParser &parser,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to export all these functions? Aren't these internal business of the parser?


/// Parses a single channel keyword `x`, `y`, `z` or `w`.
static ParseResult parseChannel(AsmParser &parser,
SmallVectorImpl<int64_t> &channels) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why it takes vectors and pushes to it rather than returning item inderectly? This seems to differ from existing parser API.

return channel == 0 ? 'x' : channel == 1 ? 'y' : channel == 2 ? 'z' : 'w';
}

static std::optional<int64_t> channelFromKeyword(StringRef keyword) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need to wrap integer into optional? It seems to be used only once, fold into parseChannel and you will be able to return error directly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, btw, and there is llvm::StringSwitch for you.

}

/// Parses an index entry that begins with the already-parsed integer `value`,
/// e.g. `2`, `2 : i64`, `2 : i64 + r<...>`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really allow, say, i17? It seems you silently ignore it.

void IndexAttr::print(AsmPrinter &printer) const {
if (auto imm = getImm()) {
printer << imm.getValue();
if (imm.getType().isInteger(64))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't you hardcode everything to i32 during parsing (in parseIntIndexEntry)?

mask = ComponentMaskAttr::get(ctx, ComponentMask::x | ComponentMask::y |
ComponentMask::z | ComponentMask::w);

return parser.getChecked<DstOperandAttr>(loc, ctx, *operandType, components,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing is great, but for mere mortals you'd probably add some additional attr builders that would automatically add defaults

return {};

applySrcOperandDefaults(ctx, *type, body);
return parser.getChecked<SrcOperandAttr>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment about about default attribute builders

Comment on lines +29 to +34
dxsa.add r<0>, cb<2 : i64 + r<3, <x>>>, r<2>

// -----

// CHECK: dxsa.add r<0>, cb<[1 : i64, 2 + r<3, <x>>, r<5, <y>>]>, r<2>
dxsa.add r<0>, cb<[1 : i64, 2 + r<3, <x>>, r<5, <y>>]>, r<2>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're allowing other types (e.g. i17 and i43). You need either disallow them or test

@asl asl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See all comments above

@@ -0,0 +1,47 @@
// RUN: mlir-opt %s -split-input-file | FileCheck %s

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should use --verify-roundtrip in all dialect syntax / op tests

@tagolog tagolog force-pushed the dxsa-mlir-refine-operands branch 2 times, most recently from 74a9f0e to d70f9e9 Compare June 12, 2026 22:07
Example:
  dxsa.add r<0>, r<1>, r<2>
  dxsa.add_sat r<0>, r<1>, r<2>
  dxsa.add r<0>, r<1>, l(1.0, 2.0, 3.0, 4.0)
  dxsa.add r<0>, -r<1>, |r<2>|

Signed-off-by: Vladimir Shiryaev <tagolog@users.noreply.github.com>
@tagolog tagolog force-pushed the dxsa-mlir-refine-operands branch from d70f9e9 to 6c5bf58 Compare June 12, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants