<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">This looks reasonable to me.</div><div class=""><br class=""></div><div class="">– Steve</div><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 18, 2014, at 8:13 PM, Lang Hames <<a href="mailto:lhames@gmail.com" class="">lhames@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi All,<div class=""><br class=""></div><div class="">I've been digging in to <a href="http://llvm.org/PR20728" class="">http://llvm.org/PR20728</a> and I've discovered the root cause of the bug detailed there. The short version is that on x86 the following call should constant-fold to 4.0L:</div><div class=""><br class=""></div><div class="">fmal(1.0L, 1.0L, 3.0L) </div><div class=""><br class=""></div><div class="">However, it currently constant folds to 0.0L.</div><div class=""><br class=""></div><div class="">Here's what goes wrong: The call is constant folded using APFloat::fusedMultiplyAdd, but the real work is done by APFloat::multiplySignificand. APFloat::multiplySignificand takes an RHS for the multiplication and an optional addend. The method allocates a 2x precision intermediate significand to hold the result of both operations. This is sufficient to hold the result of the multiplication without overflowing, but if the MSB of the multiplication result and the addend are both in the top bits of their respective significands, the addition operation will overflow. For reasons too perverse to detail here (read the bug for the gory details) this overflow is not detected, and multiplySignificand happily returns bogus results. In the case of the test case above, you end up with:</div><div class=""><br class=""></div><div class=""><font face="monospace" class=""> 0100...0 (1.0)</font></div><div class=""><font face="monospace" class="">+ 1100...0 (3.0)</font></div><div class=""><font face="monospace" class="">---------------------</font></div><div class=""><font face="monospace" class="">1 | 0000...0 (0.0!)</font></div><div class=""><br class=""></div><div class="">The attached patch fixes this bug by holding the intermediate result in 2 * precision + 1 bits, and arranging for the top bit of the addend to be zero (by shifting right by 1). This means that the addition no longer overflows, but simply carries into the top bit.</div><div class=""><br class=""></div><div class="">This patch passes the regression test suite and the nightly test suite on x86-64, so that's a good start. Are there any APFloat experts out there who are able to offer comment on the approach I've taken though? It seems superficially sane, but this is floating point code - the appearance of sanity may be purely coincidental.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Lang.</div></div>
<span id="cid:95D6FEDB-8D74-47CC-B591-5FBFEB7F697C@hsd1.nh.comcast.net."><APFloat_multiplySignificand_fix.patch></span></div></blockquote></div><br class=""></body></html>