Skip to content

Proposal: Improve overflow operations #20203

Open
@Snektron

Description

@Snektron

Context

The current overflow operations (@addWithOverflow, @subWithOverflow, @mulWithOverflow, @shlWithOverflow) do currently not spark joy in my opinion: These seem initially just designed from the corresponding LLVM instruction, however, they have some problems in reality:

  • @subWithOverflow returns a bool whether overflow happened, while in my opinion a carry would be more useful. This would work cleanly with returning an i1 instead of a u1: A carry returns -1 and no carry returns 0. In this case carries can be naively added to the next word instead of with an awkward cast.
  • Why is the "overflow" bit a u1 instead of a bool if its intended as flag? If its meant to be overflow, then why are the other overflow parts not as described above?
  • @mulWithOverflow returning a u1 is even less useful. In many situations, the CPU already gives you the high words. This also ties into wide multiplication: Currently, the primary way to do that is to cast to a larger word size, but the CPU already has a native T * T -> {T, T} instruction in many cases. Trying to detect an upcast from the backend is difficult from a compiler backend perspective, and emitting a full 2T multiplication operation is often much less efficient.
  • @shlWithOverflow would be much more useful if it also returns the overflow bits in my opinion. I don't think it would be much more expensive in code either.

Proposal

My proposal is to change the overflow builtins to return the full overflow value too. The interface would largely remain the same, only the return types need to be modified:

  • @addWithOverflow remains the same
  • @subWithOverflow(a, b) would return struct{@TypeOf(a, b), i1}.
  • @mulWithOverflow(a, b) would return struct{@TypeOf(a, b), @TypeOf(a, b)}.
    • Unresolved: Which types should be used for signed multiply overflow? I think the sanes posibilities are to return either to return a pair of signed numbers, or make the low-order bits unsigned. I'm not sure.
  • @shlWithOverflow(a, b) would return struct(@TypeOf(a, b), @TypeOf(a, b)}.
    • Unresolved: Similar to the above

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedThis proposal is planned.breakingImplementing this issue could cause existing code to no longer compile or have different behavior.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions