[libclc] [libclc] Replace float remquo with Intel IMF version (PR #162643)
Wenju He via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 9 17:46:01 PDT 2025
================
@@ -6,71 +6,257 @@
//
//===----------------------------------------------------------------------===//
+#define _sHighMask 0xfffff000u
+#define _iMaxQExp 0xbu
+// To prevent YLow to be denormal it should be checked
+// that Exp(Y) <= -127+23 (worst case when only last bit is non zero)
+// Exp(Y) < -103 -> Y < 0x0C000000
+// That value is used to construct _iYSub by setting up first bit to 1.
+// _iYCmp is get from max acceptable value 0x797fffff:
+// 0x797fffff - 0x8C000000 = 0x(1)ED7FFFFF
+#define _iYSub 0x8C000000u
+#define _iYCmp 0xED7FFFFFu
+#define _iOne 0x00000001u
+
+static _CLC_INLINE _CLC_OVERLOAD int
+internal_remquo(float x, float y, float *r, __CLC_ADDRESS_SPACE uint *q) {
+ uint signif_x, signif_y, rem_bit, quo_bit, tmp_x, tmp_y;
+ int exp_x, exp_y, i, j;
+ uint expabs_diff, special_op = 0, signbit_x, signbit_y, sign = 1;
+ float result, abs_x, abs_y;
+ float zero = 0.0f;
+ int nRet = 0;
+ // Remove sign bits
+ tmp_x = ((*(int *)&x)) & EXSIGNBIT_SP32;
+ tmp_y = ((*(int *)&y)) & EXSIGNBIT_SP32;
+ signbit_x = (uint)((*(int *)&x) >> 31);
+ signbit_y = (uint)((*(int *)&y) >> 31);
+ if (signbit_x ^ signbit_y)
+ sign = (-sign);
+ // Get float absolute values
+ abs_x = *(float *)&tmp_x;
+ abs_y = *(float *)&tmp_y;
+ // Remove exponent bias
+ exp_x = (int)((tmp_x & (0x7FF00000L)) >> 23) - 127;
+ exp_y = (int)((tmp_y & (0x7FF00000L)) >> 23) - 127;
+ // Test for NaNs, Infs, and Zeros
+ if ((exp_x == (0x00000080L)) || (exp_y == (0x00000080L)) ||
+ (tmp_x == (0x00000000L)) || (tmp_y == (0x00000000L)))
+ special_op++;
+ // Get significands
+ signif_x = (tmp_x & (0x007FFFFFL));
+ signif_y = (tmp_y & (0x007FFFFFL));
+ // Process NaNs, Infs, and Zeros
+ if (special_op) {
+ (*q) = 0;
+ // x is NaN
+ if ((signif_x != (0x00000000L)) && (exp_x == (0x00000080L)))
+ result = x * 1.7f;
+ // y is NaN
+ else if ((signif_y != (0x00000000L)) && (exp_y == (0x00000080L)))
+ result = y * 1.7f;
+ // y is zero
+ else if (abs_y == zero) {
+ result = zero / zero;
+ nRet = 1;
+ }
+ // x is zero
+ else if (abs_x == zero)
+ result = x;
+ // x is Inf
+ else if ((signif_x == (0x00000000L)) && (exp_x == (0x00000080L)))
+ result = zero / zero;
+ // y is Inf
+ else
+ result = x;
+ (*r) = (result);
+ return nRet;
+ }
+ // If x < y, fast return
+ if (abs_x <= abs_y) {
+ (*q) = 1 * sign;
+ if (abs_x == abs_y) {
+ (*r) = (zero * x);
+ return nRet;
+ }
+ // Is x too big to scale up by 2.0f?
+ if (exp_x != 127) {
+ if ((2.0f * abs_x) <= abs_y) {
+ (*q) = 0;
+ (*r) = x;
+ return nRet;
+ }
+ }
+ result = abs_x - abs_y;
+ if (signbit_x) {
+ result = -result;
+ }
+ (*r) = (result);
+ return nRet;
+ }
+ // Check for denormal x and y, adjust and normalize
+ if ((exp_x == -127) && (signif_x != (0x00000000L))) {
+ exp_x = -126;
+ while (signif_x <= (0x007FFFFFL)) {
----------------
wenju-he wrote:
done
https://github.com/llvm/llvm-project/pull/162643
More information about the cfe-commits
mailing list