Skip to content

heterogeneous bitwidths for transfer.integer - #88

Draft
dominicmkennedy wants to merge 14 commits into
opencompl:mainfrom
dominicmkennedy:heterogeneous-bw
Draft

heterogeneous bitwidths for transfer.integer#88
dominicmkennedy wants to merge 14 commits into
opencompl:mainfrom
dominicmkennedy:heterogeneous-bw

Conversation

@dominicmkennedy

@dominicmkennedy dominicmkennedy commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

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.integer which 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 ResolveTransferWidths which 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 ResolveTransferWidths pass 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, and sext operations which have a new type CastOp such that they take in a symbolic width @X and 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 the trunc op, and vice versa for zext and sext.

One other happy consequence of this change is that CmpOp and SelectOp previously used a hack which was that consumed mlir's built in i1, which meant that they had to be lowered to smt.pair<smt.bv<1>, smt.bool> for poison semantics, even though no other transfer ops had such semantics. But now they expect transfer.integer<1> and produce smt.bv<1> which is more in line with how all of the other transfer ops are treated

Most of the files changed are just tests, just to add the new pass.

@dominicmkennedy
dominicmkennedy marked this pull request as ready for review February 11, 2026 16:54
@dominicmkennedy
dominicmkennedy marked this pull request as draft February 11, 2026 16:54
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.

1 participant