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

[MooreToCore] Support pow op #7626

Open
fabianschuiki opened this issue Sep 25, 2024 · 2 comments
Open

[MooreToCore] Support pow op #7626

fabianschuiki opened this issue Sep 25, 2024 · 2 comments
Labels
good first issue Good for newcomers Moore

Comments

@fabianschuiki
Copy link
Contributor

Add support for the moore.pow* ops in MooreToCore: https://chipsalliance.github.io/sv-tests-results/?v=circt_verilog+11.4.3+binary_op_pow

@maerhart
Copy link
Member

We already have canonicalizers and folders that cover the simple cases here:

//===----------------------------------------------------------------------===//
// PowSOp
//===----------------------------------------------------------------------===//
static OpFoldResult powCommonFolding(MLIRContext *ctxt, Attribute lhs,
Attribute rhs) {
auto lhsValue = dyn_cast_or_null<FVIntegerAttr>(lhs);
if (lhsValue && lhsValue.getValue() == 1)
return lhs;
auto rhsValue = dyn_cast_or_null<FVIntegerAttr>(rhs);
if (rhsValue && rhsValue.getValue().isZero())
return FVIntegerAttr::get(ctxt,
FVInt(rhsValue.getValue().getBitWidth(), 1));
return {};
}
OpFoldResult PowSOp::fold(FoldAdaptor adaptor) {
return powCommonFolding(getContext(), adaptor.getLhs(), adaptor.getRhs());
}
LogicalResult PowSOp::canonicalize(PowSOp op, PatternRewriter &rewriter) {
Location loc = op.getLoc();
auto intType = cast<IntType>(op.getRhs().getType());
if (auto baseOp = op.getLhs().getDefiningOp<ConstantOp>()) {
if (baseOp.getValue() == 2) {
Value constOne = rewriter.create<ConstantOp>(loc, intType, 1);
Value constZero = rewriter.create<ConstantOp>(loc, intType, 0);
Value shift = rewriter.create<ShlOp>(loc, constOne, op.getRhs());
Value isNegative = rewriter.create<SltOp>(loc, op.getRhs(), constZero);
auto condOp = rewriter.replaceOpWithNewOp<ConditionalOp>(
op, op.getLhs().getType(), isNegative);
Block *thenBlock = rewriter.createBlock(&condOp.getTrueRegion());
rewriter.setInsertionPointToStart(thenBlock);
rewriter.create<YieldOp>(loc, constZero);
Block *elseBlock = rewriter.createBlock(&condOp.getFalseRegion());
rewriter.setInsertionPointToStart(elseBlock);
rewriter.create<YieldOp>(loc, shift);
return success();
}
}
return failure();
}
//===----------------------------------------------------------------------===//
// PowUOp
//===----------------------------------------------------------------------===//
OpFoldResult PowUOp::fold(FoldAdaptor adaptor) {
return powCommonFolding(getContext(), adaptor.getLhs(), adaptor.getRhs());
}
LogicalResult PowUOp::canonicalize(PowUOp op, PatternRewriter &rewriter) {
Location loc = op.getLoc();
auto intType = cast<IntType>(op.getRhs().getType());
if (auto baseOp = op.getLhs().getDefiningOp<ConstantOp>()) {
if (baseOp.getValue() == 2) {
Value constOne = rewriter.create<ConstantOp>(loc, intType, 1);
rewriter.replaceOpWithNewOp<ShlOp>(op, constOne, op.getRhs());
return success();
}
}
return failure();
}

The folders are automatically called during Dialect Conversion, the canonicalization aren't.

@fabianschuiki How should the a ** b case in the table be handled here? Since there's no pow op in Comb.

@fabianschuiki
Copy link
Contributor Author

👍 We could start out with a pretty dumb iterative approach? Maybe an scf.for that just goes from 0 to b and keeps multiplying a result by a? Pretty sure this almost never comes up in practice, and that would make it more of a performance issue than a correctness issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers Moore
Projects
None yet
Development

No branches or pull requests

2 participants