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

f32/64.neg/abs may be wrong #70

Closed
CryZe opened this issue Mar 6, 2018 · 6 comments
Closed

f32/64.neg/abs may be wrong #70

CryZe opened this issue Mar 6, 2018 · 6 comments

Comments

@CryZe
Copy link

CryZe commented Mar 6, 2018

It seems like it delegates the implementations to Rust's f32/64::neg/abs which might to be wrong as according to https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-negate
those instructions are supposed to be bitwise instructions that preserve the bits, so they can't be implemented as subtractions. However f32/64::neg generate the following LLVM IR:

define float @example::foo(float %x) unnamed_addr #0 {
  %0 = fsub float -0.000000e+00, %x
  ret float %0
}
@pepyakin
Copy link
Collaborator

pepyakin commented Mar 6, 2018

It well might be! We didn't spent much time on float stuff and, I think, we even not passing testsuite for float.

@pepyakin
Copy link
Collaborator

It seems that there is no separate instruction in LLVM that acts as fneg: fsub 0, x is used to represent it. I guess we fine since both LLVM and wasm strives to be IEEE 754 compatible.

@pepyakin
Copy link
Collaborator

Also, just in case you interested, in #72 I've enabled fp tests and they should pass now.

@CryZe
Copy link
Author

CryZe commented Mar 11, 2018

While there is no separate instruction for it in LLVM, the reference manual specifically calls out that subtracting from 0 is not correct:

This differs from subtracting the operand value from negative zero

I don't know enough about floating point to be able to judge whether there's any actual difference, but is there anything stopping you from just implementing it as:

f32::from_bits(val.to_bits() ^ 0x8000_0000)

@pepyakin
Copy link
Collaborator

Yeah, that's because the IEEE 754 tells the same!
I'm actually pretty not sure that fsub 0, x does something other than flipping the sign bit.

Personally, I'd perfer using f32::neg rather than bit-twiddling since it's cleaner (and maybe there is a chance that llvm might generate a better code?)

So before doing that change, I would like to be sure that this is actually a problem.

I think running the testsuite on a some exotic (fp-wise) arch such as MIPS would be enough to discover problems if they are actually present!

@pepyakin
Copy link
Collaborator

After all we ended up with raw bit manipulation, see #87 !

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

No branches or pull requests

2 participants