[libre-riscv-dev] FP unit testing (was Re: [isa-dev] FP reciprocal sqrt extension proposal)

Jacob Lifshay programmerjake at gmail.com
Thu Jul 25 10:17:43 BST 2019

On Thu, Jul 25, 2019 at 1:54 AM lkcl <luke.leighton at gmail.com> wrote:
> On Thursday, July 25, 2019 at 9:45:08 AM UTC+1, Jacob Lifshay wrote:
>> The special case values should be (for reciprocal sqrt):
>> NaN -> NaN (ignoring signaling/quiet)
>> -Inf -> NaN
>> -finite -> NaN
>> -0 -> -Inf (div-by-zero; weird, but this is how ieee 754 defines it)
>> +0 -> +Inf (div-by-zero)
>> +finite -> rsqrt
>> +Inf -> +0
> do you happen to know if that's the exact order in which those tests have to be actioned?  the reason i ask is because i got caught out when doing fpsqrt special cases: i'd placed zero-testing later in the list, tested -ve numbers (all -ve numbers) first to return canonical-NaN, and of course sqrt(-ve zero) is -ve zero.

Those cases are more like a switch statement in C with breaks in that
each case is independent:

Float frsqrt(Float input)
    case NAN:
    case NEG_INF:
    case NEG_FINITE:
    case NEG_DENORMAL:
        return NaN;
    case NEG_ZERO:
        return -Inf;
    case POS_ZERO:
        return +Inf;
    case POS_FINITE:
    case POS_DENORMAL:
        return calculate_frsqrt(input);
    case POS_INF:
        return +0.0;

So, the order you test them in is whatever order the classify() algorithm uses.

> this one "-0 -> -Inf" kiiinda makes sense if the 1/ is considered to take precedence over sqrt() part.
yeah, but it makes it more annoying since otherwise the sign of the
result (ignoring NaNs) is always positive, like you would expect from
the mathematical limits at 0 and infinity.

If I recall correctly the actual definition of reciprocal sqrt in IEEE
754 is (expanded):
fn frsqrt(v) {
    let temp = sqrt(v); // IEEE 754 sqrt except it returns the exact
mathematical result without rounding
    return 1.0 / temp; // IEEE 754 division; rounds the result

the reason frsqrt(-0) returns -Inf is that IEEE 754 sqrt(-0) returns
-0 which then gets converted to -Infinity.

Jacob Lifshay

More information about the libre-riscv-dev mailing list