heterogeneous bitwidths for transfer.integer - #88
Draft
dominicmkennedy wants to merge 14 commits into
Draft
Conversation
dominicmkennedy
marked this pull request as ready for review
February 11, 2026 16:54
dominicmkennedy
marked this pull request as draft
February 11, 2026 16:54
…'t used by filecheck)
…1> -> smt.bv<1>`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a WIP at the moment, but I want to share progress in case anyone has comments/concerns on this implementation.
As of now I allow for three types of transfer integers:
!transfer.integerwhich is a legacy type so that all existing code can remain unchanged!transfer.integer<8>which has a concrete width and!transfer.integer<@X>which has a symbolic width.The caveat is that you may have legacy types, and concrete types in a module, or you may have symbolic types and concrete types in a module, but you may not mix symbolic and legacy types.
I've also added a pass called
ResolveTransferWidthswhich in the legacy case takes a global width, to lower all transfer.integers to. This matches the existing behavior, and the pass can be run like this:-p=resolve-transfer-widths{width=8}. Alternatively, if you have a module with symbolic transfer integers, then you run the pass like this:-p=resolve-transfer-widths{width-map=\"@X=8,@Y=16\"}. The width-map defines which widths each symbolic integer should be lowered to.The
ResolveTransferWidthspass should run first, since you need all concrete widths to lower to smt or llvm ir. But if all transfer integers already have a concrete width then you don't need to run this pass.I've also added
trunc,zext, andsextoperations which have a new typeCastOpsuch that they take in a symbolic width@Xand return a symbolic width@Y. Once the transfer widths are resolved to concrete values, we assert that the old with is more than the new one in thetruncop, and vice versa forzextandsext.One other happy consequence of this change is that
CmpOpandSelectOppreviously used a hack which was that consumed mlir's built ini1, which meant that they had to be lowered tosmt.pair<smt.bv<1>, smt.bool>for poison semantics, even though no other transfer ops had such semantics. But now they expecttransfer.integer<1>and producesmt.bv<1>which is more in line with how all of the other transfer ops are treatedMost of the files changed are just tests, just to add the new pass.