-
Notifications
You must be signed in to change notification settings - Fork 13.2k
APFloat's addOrSubtractSignificand
still throws assert in subtler FMA cases.
#63895
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Just noticed LLVM does have exhaustive testing for 8-bit floats, neat! llvm-project/llvm/unittests/ADT/APFloatTest.cpp Lines 5073 to 5080 in 83f3920
However, AFAICT that doesn't cover FMA - which is entirely understandable, as it would increase the test duration ~50x compared to all binary ops combined. Sadly, FMA is also more likely to hit weird edge cases (some of which have cc @d0k @reedwm @krzysz00 @majnemer (based on |
Something I should've checked is the non-assertion output (try on godbolt):
Which makes sense, the |
I've let a bruteforce run for I've also went ahead added parallelism to my bruteforce tool: and as such, I can now generate such examples much faster, if that's of any use. I'm attempting a run for |
results in (e.g. via godbolt):
However, that's not how the bug was found. I noticed 8-bit formats (like
Float8E5M2
andFloat8E4M3FN
) were added toAPFloat
, and decided to try brute-forcing all possible inputs for a few common operations (it only takes 8 seconds, and ~98% of that is FMA, because it uniquely has 3 inputs).So the first example I found was for
Float8E4M3FN
, namely:FMA(0.0254, 0.0781, -0.00195)
(the encoded byte values being0x0d
,0x1a
,0x81
).Then @solson helped me turn some formula sketches I made looking at the code, into Z3, which confirmed that the example I found was the only one across all possible 8-bit floats, but 16-bit and 32-bit have a lot more cases. (I'm only not including all that here because it's not really set up to generate ready to use examples, it's really finicky as-is)
My understanding is that e62555c fixed most of the previously problematic cases, but not the ones where both significands are equal before subtraction, which will only work if
lost_fraction == lfExactlyZero
.(cc @ekatz)
But if there is a lost fraction, neither direction will work to subtract equal significands - the code seems to rely on being able to assume that only equal exponents can result in equal significands, but we know that's not true w/ FMA.
(also, the lost fraction is always subtracted, regardless of the subtraction direction, but before e62555c the source of the
lost_fraction
was tied toreverse
, i.e.a.subtractSignificand(b, lost_fraction != lfExactlyZero)
was always performed withlost_fraction
coming fromlost_fraction = b.shiftSignificandRight(...);
, regardless of howa
andb
mapped to*this
andtemp_rhs
, respectively - this seems significant as well, but I'm not sure how to tell or test this)The text was updated successfully, but these errors were encountered: