[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