-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Remove sqrt from the volatile list #43786
Conversation
Nice to get this fixed! |
my guess is that the common way this could fail is if a libm uses |
If anyone fails this, it would probably be windows. Their libm isn't great in general. |
Random test passed locally on win64: for I in 1:10000000
r = reinterpret(Float64,rand(UInt))
@test sqrt(abs(r)) === Base.sqrt_llvm(abs(r))
end Edit: glibc test also passed. |
|
IIUC, julia> fma(-1.9369631f13, 2.1513551f-7, -1.7354427f-24)
-4.1670958f6
julia> Base.fma_float(-1.9369631f13, 2.1513551f-7, -1.7354427f-24)
-4.1670955f6 |
7922ce9
to
b7a9051
Compare
Alright, I have added a test to detect if there's any platform with the fp80 double rounding problem. Otherwise, I think we should try this and see what happens. |
Sigh, sqrt test failed on builtkite i686 Linux, so looks like whatever we're using there is buggy. |
This might be our fault because it looks like openlibm has the double rounding bug on 32bit: https://github.com/JuliaMath/openlibm/blob/master/i387/e_sqrt.S#L12. @oscardssmith wanna have a go at fixing this in openlibm? That said, we assume a minimum of SSE2, so our minimum supported ISA has sqrtsd - we should probably just use that. |
There's three cases that all need to be consistent:
Depending on how things are built, these can all pick up different version of the intrinsics. |
I'd honestly rather us move away from openlibm. can we just make llvm use the intrinsic? |
Actually, looks like in this case LLVM doesn't actually constant fold |
That makes sense. (I am, however unlikely to touch the openlibm version). |
Alright, do you want to change the runtime intrinsics here and I'll make the patch to openlibm (but we won't block on an openlibm upgrade)? |
As discussed in JuliaLang/julia#43786, openlibm's sqrt function is incorrectly rounded for i387. IEEE requires correct rounding for these functions and LLVM relies on it. Fix that by setting the precision in the FPU control word (see e.g. e_ceil.S for similar FPU modifications).
As discussed in JuliaLang/julia#43786, openlibm's sqrt function is incorrectly rounded for i387. IEEE requires correct rounding for these functions and LLVM relies on it. Fix that by setting the precision in the FPU control word (see e.g. e_ceil.S for similar FPU modifications).
Openlibm fix is JuliaMath/openlibm#256. |
As discussed in JuliaLang/julia#43786, openlibm's sqrt function is incorrectly rounded for i387. IEEE requires correct rounding for these functions and LLVM relies on it. Fix that by setting the precision in the FPU control word (see e.g. e_ceil.S for similar FPU modifications).
This is more of a "Do we want to move in this direction RFC". As mentioned in #43786, we currently have three implementations of these intrinsics: 1. The code generated by LLVM for the intrinsic 2. The code LLVM uses for constant folding the intrinsic 3. Our own runtime intrinsic used by the interpreter This basically removes the third one, which will be required if we want to do something about #26434 because we just forward these to libm. Of course we'll still have to do something to teach LLVM how to constant fold these in a manner compatible with what will actually end up running, but that's a separate issue.
As discussed, for now we won't touch runtime_intrinsic and just pull in the openlibm update to enable this. #43869 tracks just getting rid of the intrinsic entirely to reduce the complexity. |
This is more of a "Do we want to move in this direction RFC". As mentioned in #43786, we currently have three implementations of these intrinsics: 1. The code generated by LLVM for the intrinsic 2. The code LLVM uses for constant folding the intrinsic 3. Our own runtime intrinsic used by the interpreter This basically removes the third one, which will be required if we want to do something about #26434 because we just forward these to libm. Of course we'll still have to do something to teach LLVM how to constant fold these in a manner compatible with what will actually end up running, but that's a separate issue.
The LLVM IR spec now explicitly says that this intrinsic is required to be rounded correctly. That means that without fasthmath flag (which we do not set here), this intrinsic must have the bitwise correctly rounded answer and should thus not differ between compile and runtime. If there is still a case where it does differ, that is likely some other underlying bug that we should fix instead. Before: ``` julia> f() = sqrt(2) f (generic function with 1 method) julia> @code_typed f() CodeInfo( 1 ─ %1 = Base.Math.sqrt_llvm(2.0)::Float64 └── return %1 ) => Float64 ``` After: ``` julia> @code_typed f() CodeInfo( 1 ─ return 1.4142135623730951 ) => Float64 ```
b7a9051
to
bb2e1fb
Compare
This reverts commit cc96240.
This reverts commit cc96240.
This reverts commit cc96240.
The LLVM IR spec now explicitly says that this intrinsic is required to be rounded correctly. That means that without fasthmath flag (which we do not set here), this intrinsic must have the bitwise correctly rounded answer and should thus not differ between compile and runtime. If there is still a case where it does differ, that is likely some other underlying bug that we should fix instead. Before: ``` julia> f() = sqrt(2) f (generic function with 1 method) julia> @code_typed f() CodeInfo( 1 ─ %1 = Base.Math.sqrt_llvm(2.0)::Float64 └── return %1 ) => Float64 ``` After: ``` julia> @code_typed f() CodeInfo( 1 ─ return 1.4142135623730951 ) => Float64 ```
The LLVM IR spec now explicitly says that this intrinsic is required to be rounded correctly. That means that without fasthmath flag (which we do not set here), this intrinsic must have the bitwise correctly rounded answer and should thus not differ between compile and runtime. If there is still a case where it does differ, that is likely some other underlying bug that we should fix instead. Before: ``` julia> f() = sqrt(2) f (generic function with 1 method) julia> @code_typed f() CodeInfo( 1 ─ %1 = Base.Math.sqrt_llvm(2.0)::Float64 └── return %1 ) => Float64 ``` After: ``` julia> @code_typed f() CodeInfo( 1 ─ return 1.4142135623730951 ) => Float64 ```
The LLVM IR spec now explicitly says that this intrinsic is required
to be rounded correctly. That means that without fasthmath flag
(which we do not set here), this intrinsic must have the bitwise
correctly rounded answer and should thus not differ between compile
and runtime. If there is still a case where it does differ, that is
likely some other underlying bug that we should fix instead.
Before:
After: