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

[FIRRTL] Canonicalize multibit_mux with narrow index #7373

Merged
merged 2 commits into from
Aug 9, 2024

Conversation

uenoku
Copy link
Member

@uenoku uenoku commented Jul 23, 2024

This adds a canonicalization to optimize multibit_mux whose index has narrow width. Close #7361

Copy link
Member

@seldridge seldridge left a comment

Choose a reason for hiding this comment

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

LGTM

While, this looks right to me, it is worthwhile to verify (locally test) that the behavior is doing to right thing for edge cases, e.g., zero width.

// elements.
auto indexWidth = op.getIndex().getType().getBitWidthOrSentinel();
uint64_t inputSize = op.getInputs().size();
if (indexWidth < 64 && 1ull << indexWidth < inputSize) {
Copy link
Member

Choose a reason for hiding this comment

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

Is 1ull portable across windows and Linux?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's fine as there are several existing use cases in LLVM and CIRCT repo.

Copy link
Contributor

Choose a reason for hiding this comment

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

long long is at least 64bits since c++11, according to https://en.cppreference.com/w/cpp/language/types .

That said (only looking at the code added here):

indexWidth is signed (int32_t), and in particular can be negative (!). Shift by a negative amount is UB! Please add a check for that, as even without UB it's logically not what we want either.

Copy link
Contributor

@dtzSiFive dtzSiFive left a comment

Choose a reason for hiding this comment

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

Great work identifying this and putting together the canonicalizer!

On my "TODO" is to bolster our knownbits-like capabilities, and with that hat on I can't help but wonder about generalizing this beyond index being narrow directly. Future work, but since you're pushing on this just thought I'd mention it 👍 .

Anyway, generally looks good but there's an important issue that needs to be addressed before landing this, see my comment. Thanks!

// elements.
auto indexWidth = op.getIndex().getType().getBitWidthOrSentinel();
uint64_t inputSize = op.getInputs().size();
if (indexWidth < 64 && 1ull << indexWidth < inputSize) {
Copy link
Contributor

Choose a reason for hiding this comment

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

long long is at least 64bits since c++11, according to https://en.cppreference.com/w/cpp/language/types .

That said (only looking at the code added here):

indexWidth is signed (int32_t), and in particular can be negative (!). Shift by a negative amount is UB! Please add a check for that, as even without UB it's logically not what we want either.

@uenoku
Copy link
Member Author

uenoku commented Jul 23, 2024

On my "TODO" is to bolster our knownbits-like capabilities, and with that hat on I can't help but wonder about generalizing this beyond index being narrow directly. Future work, but since you're pushing on this just thought I'd mention it 👍 .

Yeah that sounds great idea. I think naively computing knownbits could be expensive (as shown in

#if 0
// If the extracted bits are all known, then return the result.
auto knownBits = computeKnownBits(op.getInput())
.extractBits(cast<IntegerType>(op.getType()).getWidth(),
op.getLowBit());
if (knownBits.isConstant()) {
replaceOpWithNewOpAndCopyName<hw::ConstantOp>(rewriter, op,
knownBits.getConstant());
return success();
}
) so I guess a dedicated pass would be needed. Though computing known bits is exactly bit-sensitive IMCP so it's worth extending the lattice in IMCP.

Copy link
Contributor

@dtzSiFive dtzSiFive left a comment

Choose a reason for hiding this comment

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

Friendly upgrade to "request changes" since this is reachable UB. I don't have the details paged in but the expected change (dropping widths, I think?) to one of the tests was all it took 👍 .

Just making sure this gets addressed, thanks!

@uenoku
Copy link
Member Author

uenoku commented Jul 31, 2024

Thanks! I added a condition and test to ensure that the width is not negative number. I checked the canonicalization on internal cores and it was ok.

Copy link
Contributor

@dtzSiFive dtzSiFive left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks!

(sorry for delay, missed the update 👍 )

@uenoku
Copy link
Member Author

uenoku commented Aug 9, 2024

Np, thank you for review!

@uenoku uenoku merged commit a2c44c1 into main Aug 9, 2024
4 checks passed
@uenoku uenoku deleted the dev/hidetou/cano-multi branch August 9, 2024 11:51
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.

[FIRRTL] Canonicalization missing for narrow dynamic subindex
3 participants