Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Moore] Support four-valued integers in ConstantOp #7463

Merged
merged 1 commit into from
Aug 8, 2024

Conversation

fabianschuiki
Copy link
Contributor

Extend Moore's ConstantOp to use the new FVIntegerAttr, which now allows us to materialize four-valued integer constants in the IR. Also adjust ImportVerilog to finally properly captured integer literals with X and Z bits.

With this change, circt-verilog is now capable of fully parsing the Snitch RISC-V core used as a benchmark in the original LLHD paper at PLDI 2020, and to produce a corresponding blob of IR.

Examples of the extended op:

moore.constant 0 : i32
moore.constant 2 : i2
moore.constant -2 : i2
moore.constant h123456789ABCDEF0 : i64
moore.constant h123456789ABCDEF0XZ : l72
moore.constant b1010 : i8
moore.constant b1010XZ : l8

Copy link
Member

@maerhart maerhart left a comment

Choose a reason for hiding this comment

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

Super awesome that we can parse Snitch now! 🚀 🎉

Comment on lines 22 to 23
def FVIntAttr : Attr<CPred<"llvm::isa<FVIntegerAttr>($_self)">,
"arbitrary precision four-valued integer attribute"> {
let storageType = [{ circt::moore::FVIntegerAttr }];
let returnType = [{ circt::FVInt }];
}

Copy link
Member

Choose a reason for hiding this comment

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

Why isn't it possible to just use the FVIntegerAttr above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you use FVIntegerAttr directly in constant op as (ins FVIntegerAttr:$value), then calling constOp.getValue() will return the FVIntegerAttr. If you use FVIntAttr instead, you will get a getValue() accessor which returns FVInt, and a getValueAttr() accessor which returns the FVIntegerAttr.

I took the FVIntAttr pattern above from the builtin IntegerAttr: hw.constant has to use APIntAttr instead of Builtin_IntegerAttr for the same reason. I don't know why this is so obscure in MLIR. Ideally you'd have some way of marking attributes that wrap an underlying type like APInt or FVInt, and which you'd like to unwrap to that value by default.

Copy link
Member

Choose a reason for hiding this comment

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

It should work if you add the following two lines to FVIntegerAttr:

  let convertFromStorage = "$_self.getValue()";
  let returnType = [{ circt::FVInt }];

AttrDef overrides those two from the Attr class it inherits.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🥳 That works! Really cool, thanks 😃

lib/Conversion/MooreToCore/MooreToCore.cpp Outdated Show resolved Hide resolved
Comment on lines 390 to 393
if (value == FVInt(1, 0)) {
p << "false";
} else if (value == FVInt(1, 1)) {
p << "true";
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Not sure if this special casing is worth it since we need to specify the type anyways here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah good point. I think my initial motivation to add them is to avoid having single-bit 0 and 1 printed as 0 and -1. But instead we could also just not use negative notation for single-bit numbers. That would probably make more sense 😁

test/Conversion/ImportVerilog/errors.sv Show resolved Hide resolved
Base automatically changed from fschuiki/FVIntegerAttr to main August 8, 2024 15:57
@fabianschuiki fabianschuiki force-pushed the fschuiki/moore-fvint-constants branch from ae03cf9 to 2ef8f23 Compare August 8, 2024 16:23
Extend Moore's `ConstantOp` to use the new `FVIntegerAttr`, which now
allows us to materialize four-valued integer constants in the IR. Also
adjust ImportVerilog to finally properly captured integer literals with
X and Z bits.

With this change, `circt-verilog` is now capable of fully parsing the
Snitch RISC-V core used as a benchmark in the original LLHD paper at
PLDI 2020, and to produce a corresponding blob of IR.

Examples of the extended op:

    moore.constant 0 : i32
    moore.constant 2 : i2
    moore.constant -2 : i2
    moore.constant h123456789ABCDEF0 : i64
    moore.constant h123456789ABCDEF0XZ : l72
    moore.constant b1010 : i8
    moore.constant b1010XZ : l8
@fabianschuiki fabianschuiki force-pushed the fschuiki/moore-fvint-constants branch from 2ef8f23 to add0b6a Compare August 8, 2024 16:26
@fabianschuiki fabianschuiki merged commit d8c1f6d into main Aug 8, 2024
4 checks passed
@fabianschuiki fabianschuiki deleted the fschuiki/moore-fvint-constants branch August 8, 2024 17:38
Comment on lines +427 to 429
OpBuilder<(ins "IntType":$type, "const FVInt &":$value)>,
OpBuilder<(ins "IntType":$type, "const APInt &":$value)>,
OpBuilder<(ins "IntType":$type, "int64_t":$value)>,
Copy link
Member

Choose a reason for hiding this comment

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

From my perspective, I think FVInt can shoulder the creation of moore.constant. So should we still need APInt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I totally agree! The builder with APInt is just here for convenience now, it internally calls the builder with FVInt and converts the APInt to an FVInt without any X or Z bits.

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

Successfully merging this pull request may close these issues.

3 participants