logic in Math.nextAfter for handling -0.0 input

Deneau, Tom tom.deneau at amd.com
Mon Jun 23 21:55:04 UTC 2014


In the same Math.nextAfter routine we have the following which among other things, handles
the requirement that
     nextAfter(+infinity, +infinity)  == +infinity
and
     nextAfter(-infinity, -infinity)  == -infinity

However, in my test case, it looks like the "if (start == direction)" test is being optimized out
and the above cases then don't work.

Before Math.nextAfter is called the direction parameter is set up as
    double direction = (gid & 1) == 0 ? Double.POSITIVE_INFINITY : -Double.NEGATIVE_INFINITY;
    outArray[gid] = Math.nextAfter(inArray[gid], direction);

so I don't understand why the (start == direction) test would be optimized out.

-- Tom




From: Tom Rodriguez [mailto:tom.rodriguez at oracle.com]
Sent: Monday, June 23, 2014 4:04 PM
To: Deneau, Tom
Cc: graal-dev at openjdk.java.net
Subject: Re: logic in Math.nextAfter for handling -0.0 input

I think graal does this in general so it's not an HSAIL specific problem.  >From AddFloatNode.java:

 @Override
    public Node canonical(CanonicalizerTool tool) {
        ...
        } else if (y().isConstant()) {
            Constant c = y().asConstant();
            if ((c.getKind() == Kind.Float && c.asFloat() == 0.0f) || (c.getKind() == Kind.Double && c.asDouble() == 0.0)) {
                return x();
            }
        }
        return this;
    }

FloatSubNode has similar problems.  I'll delete the relevant code.

tom


On Jun 23, 2014, at 1:33 PM, Deneau, Tom <tom.deneau at amd.com<mailto:tom.deneau at amd.com>> wrote:


The JDK method Math.nextAfter contains the logic shown below to handle an input of -0.0

When the graal compiler compiles this for the hsail backend, it makes the reasonable
assumption that "start + 0.0d" can be reduced to "start" which is a problem for this algorithm.

>From what I could tell, c2 or graal for amd64 backend do not do this optimization
and so get the right answer for -0.0 input.  How do they know not to do this optimization?


       } else {        // start > direction or start < direction
           // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
           // then bitwise convert start to integer.
           long transducer = Double.doubleToRawLongBits(start + 0.0d);         <==============

           if (direction > start) { // Calculate next greater value
               transducer = transducer + (transducer >= 0L ? 1L:-1L);
           } else  { // Calculate next lesser value
                 ....

-- Tom



More information about the graal-dev mailing list