soft-fp64: Relax the way NaN is propagated

Also reassociate a couple expressions to encourage some CSE.

Results on the 308 shaders extracted from the fp64 portion of the OpenGL
CTS:

Tiger Lake and Ice Lake had similar results. (Tiger Lake shown)
total instructions in shared programs: 813599 -> 797951 (-1.92%)
instructions in affected programs: 796110 -> 780462 (-1.97%)
helped: 92
HURT: 0
helped stats (abs) min: 3 max: 5198 x̄: 170.09 x̃: 83
helped stats (rel) min: 0.36% max: 5.50% x̄: 1.57% x̃: 1.40%
95% mean confidence interval for instructions value: -282.42 -57.75
95% mean confidence interval for instructions %-change: -1.71% -1.42%
Instructions are helped.

total cycles in shared programs: 6687128 -> 6601437 (-1.28%)
cycles in affected programs: 6582246 -> 6496555 (-1.30%)
helped: 92
HURT: 0
helped stats (abs) min: 36 max: 14442 x̄: 931.42 x̃: 592
helped stats (rel) min: 0.45% max: 3.16% x̄: 1.44% x̃: 1.23%
95% mean confidence interval for cycles value: -1257.58 -605.27
95% mean confidence interval for cycles %-change: -1.58% -1.30%
Cycles are helped.

total spills in shared programs: 759 -> 702 (-7.51%)
spills in affected programs: 759 -> 702 (-7.51%)
helped: 3
HURT: 0

total fills in shared programs: 2412 -> 1442 (-40.22%)
fills in affected programs: 2412 -> 1442 (-40.22%)
helped: 3
HURT: 0

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4142>
This commit is contained in:
Ian Romanick
2020-03-02 19:20:42 -08:00
committed by Marge Bot
parent 8178fa8876
commit abf28d6a70

View File

@@ -59,6 +59,11 @@
#define FLOAT_ROUND_UP 3
#define FLOAT_ROUNDING_MODE FLOAT_ROUND_NEAREST_EVEN
/* Relax propagation of NaN. Binary operations with a NaN source will still
* produce a NaN result, but it won't follow strict IEEE rules.
*/
#define RELAXED_NAN_PROPAGATION
/* Absolute value of a Float64 :
* Clear the sign bit
*/
@@ -639,6 +644,12 @@ __normalizeRoundAndPackFloat64(uint zSign,
uint64_t
__propagateFloat64NaN(uint64_t __a, uint64_t __b)
{
#if defined RELAXED_NAN_PROPAGATION
uvec2 a = unpackUint2x32(__a);
uvec2 b = unpackUint2x32(__b);
return packUint2x32(uvec2(a.x | b.x, a.y | b.y));
#else
bool aIsNaN = __is_nan(__a);
bool bIsNaN = __is_nan(__b);
uvec2 a = unpackUint2x32(__a);
@@ -647,6 +658,7 @@ __propagateFloat64NaN(uint64_t __a, uint64_t __b)
b.y |= 0x00080000u;
return packUint2x32(mix(b, mix(a, b, bvec2(bIsNaN, bIsNaN)), bvec2(aIsNaN, aIsNaN)));
#endif
}
/* Returns the result of adding the double-precision floating-point values
@@ -674,7 +686,7 @@ __fadd64(uint64_t a, uint64_t b)
if (orig_exp_diff_is_zero) {
if (aExp == 0x7FF) {
bool propagate = (aFracHi | aFracLo | bFracHi | bFracLo) != 0u;
bool propagate = ((aFracHi | bFracHi) | (aFracLo| bFracLo)) != 0u;
return mix(a, __propagateFloat64NaN(a, b), propagate);
}
__add64(aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1);
@@ -753,7 +765,7 @@ __fadd64(uint64_t a, uint64_t b)
return __normalizeRoundAndPackFloat64(aSign, zExp - 10, zFrac0, zFrac1);
}
if (aExp == 0x7FF) {
bool propagate = (aFracHi | aFracLo | bFracHi | bFracLo) != 0u;
bool propagate = ((aFracHi | bFracHi) | (aFracLo | bFracLo)) != 0u;
return mix(0xFFFFFFFFFFFFFFFFUL, __propagateFloat64NaN(a, b), propagate);
}
bExp = mix(bExp, 1, aExp == 0);
@@ -879,8 +891,13 @@ __fmul64(uint64_t a, uint64_t b)
return __packFloat64(zSign, 0x7FF, 0u, 0u);
}
if (bExp == 0x7FF) {
/* a cannot be NaN, but is b NaN? */
if ((bFracHi | bFracLo) != 0u)
#if defined RELAXED_NAN_PROPAGATION
return b;
#else
return __propagateFloat64NaN(a, b);
#endif
if ((uint(aExp) | aFracHi | aFracLo) == 0u)
return 0xFFFFFFFFFFFFFFFFUL;
return __packFloat64(zSign, 0x7FF, 0u, 0u);