Skip to content

Fix return types of SInt::Unsigned and SInt::*Divide - #156

Open
alastairreid wants to merge 6 commits into
masterfrom
areid-fix-types
Open

Fix return types of SInt::Unsigned and SInt::*Divide#156
alastairreid wants to merge 6 commits into
masterfrom
areid-fix-types

Conversation

@alastairreid

Copy link
Copy Markdown
  • The return types of Std::SInt::Unsigned and Std::SInt::*Divide need one more bit to represent the result than the size of the input.

    More specifically:

    Std::SInt::Unsigned(x : Bits(n)) -> __sint(n+1)
    // For n == 8, consider "Unsigned(0xFF) = 255": representing 255 as a signed integer requires 9 bits
    
    Std::SInt::Floor_Divide(x : __sint(n), y : __sint(n)) -> __sint(n+1)
    // For n == 8, consider "-128 / -1 == 128": representing 128 as a signed integer requires 9 bits
    // ditto for Std::SInt::Ceiling_Divide and Std::SInt::Truncated_Divide
    
  • Also adds support for compiling Std::SInt::Ceiling_Divide.
    This has been supported in the runtime_*.ml files for a while but we had not added support in the C backend.

  • To be able to write tests that use -O0 for these operations, I had to tweak the typechecker so that it does not infer types like "__sint(8+1)" (which the backend will not accept) and, instead infers the type "__sint(9)".

This utility function is useful for things like applying
constant folding to types like 'Bits(4+1)'
Apply constant folding to types like 'Bits(4+1)'.
Apart from being simpler, this is essential when using the -O0
compilation flag because it requires that bitwidths are literal constants.

In particular, this is needed in tests of functions whose return type
is of the form 'Bits(x * y)', 'Bits(x + 1)', etc.
This was incorrectly calculating bounds such as {3..3}
when calculating the bounds of an expression like 'Log2(x) + 3'
This was wrong because the result of Log2 has type {0..}
so the most accurate bounds we could calculate should be {3..} (with no upper bound)
This was incorrectly saying that Bits(N) can be stored in an N-bit signed value.
Obviously, we need an (N+1)-bit signed value to represent an unsigned N-bit number.
This had been added to the runtime but, for some reason,
it had not been added to the standard library.
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