My colleague Will Schmidt recently discovered (http://llvm.org/bugs/show_bug.cgi?id=21048) that the LLVM optimizers are converting sqrt(n), where n is negative, into 0.0. Now, as Sanjay pointed out, the value of sqrt(n) for negative n other than -0.0 is undefined according to the C99 standard, so this is allowable behavior. But I think that it's not necessarily good behavior, nonetheless. The problem is that an unoptimized call to sqrt(n) in libm will produce a NaN, at least in the implementations I have access to. So this particular choice changes the behavior of optimized versus unoptimized code, which of course is allowable, but probably to be avoided when possible. However, there's a de facto standard of producing NaN for these cases. The gcc and xlc compilers will optimize the call into a constant NaN, given the right options (-O2 -ffast-math for gcc, -O2 -qignerrno for xlc). All of gcc, icc, and xlc produce NaN via the library call with unoptimized code. Choosing 0.0 for Clang/LLVM introduces an unnecessary incompatibility. This is important in practice because of the xalanc benchmark in SPEC CPU2006. This code initializes a variable to a NaN value by assigning it the value sqrt(-2.01) -- don't ask me why. This variable is used to terminate a loop, and when Clang/LLVM produces 0.0 instead of NaN, the loop spins forever. Are there any objections to changing the LLVM optimization behavior to produce a constant NaN instead of 0.0 in this case? Thanks, Bill
----- Original Message -----> From: "Bill Schmidt" <wschmidt at linux.vnet.ibm.com> > To: llvmdev at cs.uiuc.edu > Cc: "Will Schmidt" <will_schmidt at vnet.ibm.com>, "Hal Finkel" <hfinkel at anl.gov>, spatel+llvm at rotateright.com > Sent: Thursday, September 25, 2014 2:50:48 PM > Subject: Optimization of sqrt() with invalid argument > > My colleague Will Schmidt recently discovered > (http://llvm.org/bugs/show_bug.cgi?id=21048) that the LLVM optimizers > are converting sqrt(n), where n is negative, into 0.0. Now, as > Sanjay > pointed out, the value of sqrt(n) for negative n other than -0.0 is > undefined according to the C99 standard, so this is allowable > behavior. > But I think that it's not necessarily good behavior, nonetheless. > > The problem is that an unoptimized call to sqrt(n) in libm will > produce > a NaN, at least in the implementations I have access to. So this > particular choice changes the behavior of optimized versus > unoptimized > code, which of course is allowable, but probably to be avoided when > possible. > > However, there's a de facto standard of producing NaN for these > cases. > The gcc and xlc compilers will optimize the call into a constant NaN, > given the right options (-O2 -ffast-math for gcc, -O2 -qignerrno for > xlc). All of gcc, icc, and xlc produce NaN via the library call with > unoptimized code. Choosing 0.0 for Clang/LLVM introduces an > unnecessary > incompatibility. > > This is important in practice because of the xalanc benchmark in SPEC > CPU2006. This code initializes a variable to a NaN value by > assigning > it the value sqrt(-2.01) -- don't ask me why. This variable is used > to > terminate a loop, and when Clang/LLVM produces 0.0 instead of NaN, > the > loop spins forever. > > Are there any objections to changing the LLVM optimization behavior > to > produce a constant NaN instead of 0.0 in this case?I think that changing this makes sense. Returning NaN is constant with the POSIX sqrt() specification (http://pubs.opengroup.org/onlinepubs/009695399/functions/sqrt.html). -Hal> > Thanks, > Bill > >-- Hal Finkel Assistant Computational Scientist Leadership Computing Facility Argonne National Laboratory
Tim Northover
2014-Sep-25 22:41 UTC
[LLVMdev] Optimization of sqrt() with invalid argument
> This is important in practice because of the xalanc benchmark in SPEC > CPU2006.No, it would be important in practice for really used legacy (i.e. unfixable) code relying on this undefined behaviour. It's important for gaming the system if it occurs in SPEC. Cheers. Tim.
Stephen Canon
2014-Sep-25 23:05 UTC
[LLVMdev] Optimization of sqrt() with invalid argument
> On Sep 25, 2014, at 6:41 PM, Tim Northover <t.p.northover at gmail.com> wrote: > >> This is important in practice because of the xalanc benchmark in SPEC >> CPU2006. > > No, it would be important in practice for really used legacy (i.e. > unfixable) code relying on this undefined behaviour. It's important > for gaming the system if it occurs in SPEC.We should fix it because it costs us nothing to do and conforms to IEEE-754, and there’s no good reason to maintain the current behavior. – Steve
Maybe Matching Threads
- [LLVMdev] Optimization of sqrt() with invalid argument
- [LLVMdev] Optimization of sqrt() with invalid argument
- [LLVMdev] Optimization of sqrt() with invalid argument
- [LLVMdev] Optimization of sqrt() with invalid argument
- [LLVMdev] Optimization of sqrt() with invalid argument