Index: libclc/generic/lib/math/clc_fma.cl =================================================================== --- libclc/generic/lib/math/clc_fma.cl +++ libclc/generic/lib/math/clc_fma.cl @@ -38,15 +38,15 @@ if (isnan(a) || isnan(b) || isnan(c) || isinf(a) || isinf(b)) return mad(a, b, c); - /* If only c is inf, and both a,b are regular numbers, the result is c*/ - if (isinf(c)) + /* If only c is inf, and both a,b are regular numbers, or if a or b is 0, the result is c*/ + if (a == .0f || b == .0f || isinf(c)) return c; a = __clc_flush_denormal_if_not_supported(a); b = __clc_flush_denormal_if_not_supported(b); c = __clc_flush_denormal_if_not_supported(c); - if (c == 0) + if (c == .0f) return a * b; struct fp st_a, st_b, st_c; @@ -71,11 +71,7 @@ struct fp st_mul; st_mul.sign = st_a.sign ^ st_b.sign; st_mul.mantissa = (st_a.mantissa * st_b.mantissa) << 14ul; - st_mul.exponent = st_mul.mantissa ? st_a.exponent + st_b.exponent : 0; - - // FIXME: Detecting a == 0 || b == 0 above crashed GCN isel - if (st_mul.exponent == 0 && st_mul.mantissa == 0) - return c; + st_mul.exponent = st_a.exponent + st_b.exponent; // Mantissa is 23 fractional bits, shift it the same way as product mantissa #define C_ADJUST 37ul @@ -106,7 +102,7 @@ // underflow: st_c.sign != st_mul.sign, and magnitude switches the sign if (st_fma.mantissa > LONG_MAX) { - st_fma.mantissa = 0 - st_fma.mantissa; + st_fma.mantissa = -st_fma.mantissa; st_fma.sign = st_mul.sign ^ 0x80000000; } @@ -153,6 +149,6 @@ if (st_fma.exponent <= -127) return as_float(st_fma.sign); - return as_float(st_fma.sign | ((st_fma.exponent + 127) << 23) | ((uint)st_fma.mantissa & 0x7fffff)); + return as_float(st_fma.sign | ((st_fma.exponent + 127) << 23) | (st_fma.mantissa & 0x7fffff)); } _CLC_TERNARY_VECTORIZE(_CLC_DEF _CLC_OVERLOAD, float, __clc_sw_fma, float, float, float) Index: libclc/generic/lib/math/math.h =================================================================== --- libclc/generic/lib/math/math.h +++ libclc/generic/lib/math/math.h @@ -76,15 +76,14 @@ #define MANTLENGTH_SP32 24 #define BASEDIGITS_SP32 7 -_CLC_OVERLOAD _CLC_INLINE float __clc_flush_denormal_if_not_supported(float x) -{ - int ix = as_int(x); - if (!__clc_fp32_subnormals_supported() && - ((ix & EXPBITS_SP32) == 0) && ((ix & MANTBITS_SP32) != 0)) { - ix &= SIGNBIT_SP32; - x = as_float(ix); - } - return x; +_CLC_OVERLOAD _CLC_INLINE float __clc_flush_denormal_if_not_supported(float x) { + int ix = as_int(x); + if (!__clc_fp32_subnormals_supported() && ((ix & MANTBITS_SP32) != 0) && + ((ix & EXPBITS_SP32) == 0)) { + ix &= SIGNBIT_SP32; + x = as_float(ix); + } + return x; } #ifdef cl_khr_fp64