-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
muladd
may unexpectedly optimize multiplications with LLVM 8 and 9
#34988
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
Comments
Note that this is documented. It’s done since this kind of optimization is much easier for llvm to do than us. |
Why do you think that’s the case.
No you couldn’t possibly check this at compile time in julia |
Yes, the notes that I don't want to use the
It is generally dangerous that the result of conditional branches differs between precompilation and runtime compilation.
In this case, I don't want a perfect solution because the numerical errors are not fatal. |
What's the inconsistency? From the code you wrote, one of them allowed fma to be used whereas the other didn't and the code generated reflects that. Are you just confused by what the llvm IR means?
That, on it's own, you can pretty much always expect to happen whenever architecture dependent optimizaions is allowed. This includes
My question was is that what you identified as the cause of the crash in the first place? If you didn't write any unsafe code there should not be a crash and I don't see why this behavior can lead to one. |
That part is not more wrong on LLVM 8 or 9 than it was on older LLVM versions. It has been wrong after function multiversioning is enabled and I think the only way to do it correctly is to intercept the LLVM lowering of |
In the example using
I didn't mean there was an identified problem. I just picked it up as the worst case. I’m sorry if I misled you. |
Thank you for the information. This is just my impression, but it is strange that the i686 is handled specially. |
For anyone familiar with the LLVM, if this is not worth explaining or documenting, close this issue. |
OK, so
is not the inconsistency. There's nothing wrong with this one NOT being optimized. The question seems to be instead why did it contract the operations into a multiplication rather than a multiplication and a fma. That seems to be because LLVM got smarter and contracted
No that's not really how it works. It's only the worst case in the sense that anything can lead to a crash. It's not more likely to lead to a crash than anything else. |
I see. Does this mean that there is no way to control it from a Julia script? In general, |
Quoting the C standard (page 56 of the archived final draft of C18, page 75 of the PDF), which should be what LLVM is following,
so LLVM should be allowed to transform However, that does not seems to be what's happening. Doing a single rounding is actually OK in this case.
But the transformation to |
No, this contraction only happen when you ask for it with The only question is that whether this is a valid contraction when you enables it with |
If we do not need to use I intuitively think that the effects of |
This may be an issue with LLVM rather than Julia, and for many Julia users, no additional documentation is needed, so I close this issue. Thanks! |
Uh oh!
There was an error while loading. Please reload this page.
Since I'm not familiar with the Julia's compiler or LLVM, I don't know whether this is a bug. There are three main parts to this issue.
background
I wrote a fast version of the method for division by
60
in JuliaGraphics/Colors.jl#407, as follows:It works fine on Julia v1.0.5 and v1.3.1 (on Windows, Linux and macOS with the x86_64 processor).
However, it may not work as expected on Julia v1.4.0-rc2 and nightly build. (All the examples below are on v1.4.0-rc2.)
part 1
The purpose of the
muladd
function is to use the FMA instruction, but I do not want to use thefma
function for the following reasons:fma_libm
instead offma_llvm
, even if the system supports the FMA instructionsThe first part is a pure question: is this conditional branch also appropriate on LLVM 8 or 9?
julia/base/floatfuncs.jl
Lines 327 to 329 in 3b53f54
part 2
The second part may be related to the LLVM backend.
By abandoning the use of the FMA instruction, we can use the following workaround:
However, it is inconsistent that
div60_mul
is not optimized into one multiplication. The difference is thecontract
:Although I don't know the details of
contract
, it is counterintuitive that thecontract
edfmul
fuses "un"-contract
edfmul
by adding thecontract
s.Does this have anything to do with the issue #34093?
part 3
The third part concerns the context dependency of compilation, and this is not a bug. The following workaround does not work.
Perhaps when
_div60(90.0f0) == 1.5f0
is evaluated, what_div60
will be compiled to by the LLVM backend is not definitive.I think that is inevitable due to the mechanism of the compiler. Is there any workaround?
Edit:
Of course, in the case of
div60
, the difference is acceptable, so this is not a fatal problem. However, I am concerned that such contextual dependencies can cause segfaults (cf. #34121).Edit2:
I'm going to use an ad-hoc measure
if reduce(max, _div60.((90.0f0,))) == 1.5f0
, but it is not a drastic measure.The text was updated successfully, but these errors were encountered: