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

I64.min_value() / -1 returns unexpected results #2858

Open
SeanTAllen opened this issue Aug 10, 2018 · 6 comments
Open

I64.min_value() / -1 returns unexpected results #2858

SeanTAllen opened this issue Aug 10, 2018 · 6 comments
Labels
needs investigation This needs to be looked into before its "ready for work"

Comments

@SeanTAllen
Copy link
Member

When running:

actor Main
    new create(env: Env) =>
    let x = I64.min_value() / -1
    env.out.print(x.string())

I would expect the value to wrap back around to I64.min_value because

min value = -9223372036854775808
max value = 9223372036854775807

and -9223372036854775808 / -1 should be 9223372036854775808
which given the I would expect to be be -9223372036854775808 as it is when I do when I run:

actor Main
    new create(env: Env) =>
    let x = I64.max_value() + 1
    env.out.print(x.string())
@SeanTAllen
Copy link
Member Author

Apparently the first triggers undefined behavior in LLVM that I think we should discuss:

http://llvm.org/docs/LangRef.html#id109

A discussion of how Julia handled is here:

JuliaLang/julia#8188

@plietar
Copy link
Contributor

plietar commented Aug 13, 2018

Looking at the implementation:

LLVMAddIncoming(phi, &zero, &nonzero_block, 1);
we intentionally avoid UB and set the result to 0, same as the x/0 case.

GCC returns INT64_MIN, whereas Clang treats this as UB and optimizes everything out, even if-fwrapv is set. https://godbolt.org/g/tpTrZZ

Rust panics, even if overflows checks are disabled. Using the explicit "wrapping division" returns INT64_MIN. https://godbolt.org/g/Gr2mNC

The best choice I think would be to just change that line in genoperator.c to return INTXX_MIN.

@jemc
Copy link
Member

jemc commented Aug 22, 2018

It seems like @mfelsche found that this behaviour is not giving the expected zero on arm and armhf? #2865 (comment)

@mfelsche
Copy link
Contributor

... and on windows it seems.

@mfelsche
Copy link
Contributor

So the inconsistency is only valid for I128 on platforms arm, armhf and on whatever platform appveyor is running on. There is already a comment on this in genoperator.c.
The reason seems to be that the code in make_divmod for detecting overflows is not working on platforms without native 128 bit support. I hope we can get the behaviour to be consistent across platforms somehow.

@aturley
Copy link
Member

aturley commented Nov 20, 2018

This looks like something that needs to have the same behavior across all platforms. We should figure out what behavior is needed here.

@SeanTAllen SeanTAllen added needs investigation This needs to be looked into before its "ready for work" bug and removed bug: 1 - needs investigation labels May 12, 2020
@SeanTAllen SeanTAllen removed the bug label Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs investigation This needs to be looked into before its "ready for work"
Projects
None yet
Development

No branches or pull requests

5 participants