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 >
Actually scratch my original remark about the hardware. I'm not actually sure what the hardware does. All I really want is a way to properly negate a floating point number. On Thu, Aug 7, 2014 at 1:45 AM, 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 >>
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 >>
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 >>> >