Ok. That you for clarifying the point for me. I was primed for a regression because this behavior changed over llvm versions and was causing my tests to fail ;). I'm now doing bitcasting to int, xoring with the signbit and bitcasting back. On Thu, Aug 7, 2014 at 2:59 AM, Owen Anderson <resistor at mac.com> wrote:> Subtraction is also not a correct implementation of negation, for exactly the same reason. LLVM is simply wrong in this context. > Generally speaking, correct implementations of fabs, fneg, and copysign are built out of logical operations rather than arithmetic ones. > > I don’t know offhand why the behavior of multiplication of multiplication in APFloat was changed. > > —Owen > > On Aug 6, 2014, at 10:45 PM, Keno Fischer <kfischer at college.harvard.edu> wrote: > >> Ok, I had forgotten about sNaNs. Doesn't the same caveat apply to >> 0-sNaN then though or does that not signal? Does that mean we need a >> separate way to handle negate in the IR? Funnily enough, historically >> I believe we were using the multiplication by -1.0 because it was a >> more reliable negation that 0-x (from 3.0 until 3.3 at least). Is >> there a good reason why multiplication by NaN should kill the sign >> bit? >> >> On Thu, Aug 7, 2014 at 1:22 AM, Owen Anderson <resistor at mac.com> wrote: >>> Hi Keno, >>> >>> From IEEE 754-2008, §5.5.1: >>> Implementations shall provide the following homogeneous quiet-computational sign bit operations for all >>> supported arithmetic formats; they only affect the sign bit. The operations treat floating-point numbers and >>> NaNs alike, and signal no exception. These operations may propagate non-canonical encodings. >>> >>> sourceFormat copy(source) >>> sourceFormat negate(source) >>> sourceFormat abs(source) >>> >>> Multiplying by -1.0 has the potential to raise a floating point exception on sNaN inputs, and hence is not a valid implementation of negation per IEEE 754. >>> >>> —Owen >>> >>> On Aug 6, 2014, at 9:51 PM, Keno Fischer <kfischer at college.harvard.edu> wrote: >>> >>>> In r187314, APFloat multiplication by with NaNs was made to always >>>> yield a positive NaN. I am wondering whether that was the correct >>>> decision. It is of course true that the result of a multiplication is >>>> undefined in IEEE, however, we were using multiplication by -1.0 to >>>> implement IEEE negate, which is defined to preserve the sign bit. >>>> r210428 made 0-NaN have IEEE negate behavior, which is good because it >>>> seems to me from r187314 to r210428 there was no compliant way to >>>> implement it in LLVM. Does somebody remember what the arguments for >>>> the behavior change in r187314 were? It seems more sane to me to >>>> preserve the sign bit than to unconditionally overwrite it, especially >>>> considering that the hardware doesn't do it this way. >>>> >>>> Thanks, >>>> Keno >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >
One more update: Since the code generated by the bitcast wasn't ideal and we were afraid to loose vectorization, etc., we ended up going with fsub -0.0, x, which for some reason unlike fsub 0.0, x, seems to be have appropriately at all optimization levels. On Thu, Aug 7, 2014 at 3:04 AM, Keno Fischer <kfischer at college.harvard.edu> wrote:> Ok. That you for clarifying the point for me. I was primed for a > regression because this behavior changed over llvm versions and was > causing my tests to fail ;). I'm now doing bitcasting to int, xoring > with the signbit and bitcasting back. > > On Thu, Aug 7, 2014 at 2:59 AM, Owen Anderson <resistor at mac.com> wrote: >> Subtraction is also not a correct implementation of negation, for exactly the same reason. LLVM is simply wrong in this context. >> Generally speaking, correct implementations of fabs, fneg, and copysign are built out of logical operations rather than arithmetic ones. >> >> I don’t know offhand why the behavior of multiplication of multiplication in APFloat was changed. >> >> —Owen >> >> On Aug 6, 2014, at 10:45 PM, Keno Fischer <kfischer at college.harvard.edu> wrote: >> >>> Ok, I had forgotten about sNaNs. Doesn't the same caveat apply to >>> 0-sNaN then though or does that not signal? Does that mean we need a >>> separate way to handle negate in the IR? Funnily enough, historically >>> I believe we were using the multiplication by -1.0 because it was a >>> more reliable negation that 0-x (from 3.0 until 3.3 at least). Is >>> there a good reason why multiplication by NaN should kill the sign >>> bit? >>> >>> On Thu, Aug 7, 2014 at 1:22 AM, Owen Anderson <resistor at mac.com> wrote: >>>> Hi Keno, >>>> >>>> From IEEE 754-2008, §5.5.1: >>>> Implementations shall provide the following homogeneous quiet-computational sign bit operations for all >>>> supported arithmetic formats; they only affect the sign bit. The operations treat floating-point numbers and >>>> NaNs alike, and signal no exception. These operations may propagate non-canonical encodings. >>>> >>>> sourceFormat copy(source) >>>> sourceFormat negate(source) >>>> sourceFormat abs(source) >>>> >>>> Multiplying by -1.0 has the potential to raise a floating point exception on sNaN inputs, and hence is not a valid implementation of negation per IEEE 754. >>>> >>>> —Owen >>>> >>>> On Aug 6, 2014, at 9:51 PM, Keno Fischer <kfischer at college.harvard.edu> wrote: >>>> >>>>> In r187314, APFloat multiplication by with NaNs was made to always >>>>> yield a positive NaN. I am wondering whether that was the correct >>>>> decision. It is of course true that the result of a multiplication is >>>>> undefined in IEEE, however, we were using multiplication by -1.0 to >>>>> implement IEEE negate, which is defined to preserve the sign bit. >>>>> r210428 made 0-NaN have IEEE negate behavior, which is good because it >>>>> seems to me from r187314 to r210428 there was no compliant way to >>>>> implement it in LLVM. Does somebody remember what the arguments for >>>>> the behavior change in r187314 were? It seems more sane to me to >>>>> preserve the sign bit than to unconditionally overwrite it, especially >>>>> considering that the hardware doesn't do it this way. >>>>> >>>>> Thanks, >>>>> Keno >>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>
On 7 August 2014 20:52, Keno Fischer <kfischer at college.harvard.edu> wrote:> One more update: Since the code generated by the bitcast wasn't ideal > and we were afraid to loose vectorization, etc., we ended up going > with fsub -0.0, x, which for some reason unlike fsub 0.0, x, seems to > be have appropriately at all optimization levels.That's because "fsub 0.0, x" is incorrect for x=+0.0. Took me a while to work out why the "obvious" choice didn't work the first time I encountered it too. Cheers. Tim.