[compiler-rt] [compiler-rt][builtins]Fix complex division for aarch64 (PR #106664)

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 29 22:28:56 PDT 2024


https://github.com/alexander-shaposhnikov created https://github.com/llvm/llvm-project/pull/106664

The correctness of __divsc3 (https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/divsc3.c#L23) relies on the behavior of __compiler_rt_fmaxX if one of the arguments is NaN.
For aarch64 __compiler_rt_fmaxf  expands to __builtin_fmaxf that doesn't provide the same gurantess / behaves differently for some pairs of (infinity, nan).
In particular, c++'s std::complex<float> would produce an incorrect result (on ARM).

1. Make  __divsc3 use __compiler_rt_fmaxX  directly.
2. Move the array "x" in divsc3_test to allow using fromRep32 & apply clang-format --style=llvm.

Test plan: ninja check-all

>From 1a5ce412732bd2b3de183b9359407192528e25fd Mon Sep 17 00:00:00 2001
From: Alexander Shaposhnikov <ashaposhnikov at google.com>
Date: Fri, 30 Aug 2024 05:16:57 +0000
Subject: [PATCH] [compiler-rt][builtins]Fix complex division on arm64

---
 compiler-rt/lib/builtins/divsc3.c            |   2 +-
 compiler-rt/test/builtins/Unit/divsc3_test.c | 302 +++++++++----------
 2 files changed, 149 insertions(+), 155 deletions(-)

diff --git a/compiler-rt/lib/builtins/divsc3.c b/compiler-rt/lib/builtins/divsc3.c
index aa4fd8e79e0cc6..6529651252c554 100644
--- a/compiler-rt/lib/builtins/divsc3.c
+++ b/compiler-rt/lib/builtins/divsc3.c
@@ -20,7 +20,7 @@
 COMPILER_RT_ABI Fcomplex __divsc3(float __a, float __b, float __c, float __d) {
   int __ilogbw = 0;
   float __logbw =
-      __compiler_rt_logbf(__compiler_rt_fmaxf(crt_fabsf(__c), crt_fabsf(__d)));
+      __compiler_rt_logbf(__compiler_rt_fmaxX(crt_fabsf(__c), crt_fabsf(__d)));
   if (crt_isfinite(__logbw)) {
     __ilogbw = (int)__logbw;
     __c = __compiler_rt_scalbnf(__c, -__ilogbw);
diff --git a/compiler-rt/test/builtins/Unit/divsc3_test.c b/compiler-rt/test/builtins/Unit/divsc3_test.c
index 870ab6e8453857..2fb0a9697e5acf 100644
--- a/compiler-rt/test/builtins/Unit/divsc3_test.c
+++ b/compiler-rt/test/builtins/Unit/divsc3_test.c
@@ -3,11 +3,11 @@
 // REQUIRES: c99-complex
 
 #include "int_lib.h"
+#include "fp_test.h"
 #include <math.h>
 #include <complex.h>
 #include <stdio.h>
 
-
 // Returns: the quotient of (a + ib) / (c + id)
 
 COMPILER_RT_ABI float _Complex
@@ -190,174 +190,168 @@ int test__divsc3(float a, float b, float c, float d)
     return 0;
 }
 
-float x[][2] =
-{
-    { 1.e-6,  1.e-6},
-    {-1.e-6,  1.e-6},
-    {-1.e-6, -1.e-6},
-    { 1.e-6, -1.e-6},
-
-    { 1.e+6,  1.e-6},
-    {-1.e+6,  1.e-6},
-    {-1.e+6, -1.e-6},
-    { 1.e+6, -1.e-6},
+int main() {
+  float x[][2] = {{1.e-6, 1.e-6},
+                  {-1.e-6, 1.e-6},
+                  {-1.e-6, -1.e-6},
+                  {1.e-6, -1.e-6},
 
-    { 1.e-6,  1.e+6},
-    {-1.e-6,  1.e+6},
-    {-1.e-6, -1.e+6},
-    { 1.e-6, -1.e+6},
+                  {1.e+6, 1.e-6},
+                  {-1.e+6, 1.e-6},
+                  {-1.e+6, -1.e-6},
+                  {1.e+6, -1.e-6},
 
-    { 1.e+6,  1.e+6},
-    {-1.e+6,  1.e+6},
-    {-1.e+6, -1.e+6},
-    { 1.e+6, -1.e+6},
+                  {1.e-6, 1.e+6},
+                  {-1.e-6, 1.e+6},
+                  {-1.e-6, -1.e+6},
+                  {1.e-6, -1.e+6},
 
-    {NAN, NAN},
-    {-INFINITY, NAN},
-    {-2, NAN},
-    {-1, NAN},
-    {-0.5, NAN},
-    {-0., NAN},
-    {+0., NAN},
-    {0.5, NAN},
-    {1, NAN},
-    {2, NAN},
-    {INFINITY, NAN},
+                  {1.e+6, 1.e+6},
+                  {-1.e+6, 1.e+6},
+                  {-1.e+6, -1.e+6},
+                  {1.e+6, -1.e+6},
 
-    {NAN, -INFINITY},
-    {-INFINITY, -INFINITY},
-    {-2, -INFINITY},
-    {-1, -INFINITY},
-    {-0.5, -INFINITY},
-    {-0., -INFINITY},
-    {+0., -INFINITY},
-    {0.5, -INFINITY},
-    {1, -INFINITY},
-    {2, -INFINITY},
-    {INFINITY, -INFINITY},
+                  {NAN, NAN},
+                  {-INFINITY, NAN},
+                  {-2, NAN},
+                  {-1, NAN},
+                  {-0.5, NAN},
+                  {-0., NAN},
+                  {+0., NAN},
+                  {0.5, NAN},
+                  {1, NAN},
+                  {2, NAN},
+                  {INFINITY, NAN},
 
-    {NAN, -2},
-    {-INFINITY, -2},
-    {-2, -2},
-    {-1, -2},
-    {-0.5, -2},
-    {-0., -2},
-    {+0., -2},
-    {0.5, -2},
-    {1, -2},
-    {2, -2},
-    {INFINITY, -2},
+                  {NAN, -INFINITY},
+                  {-INFINITY, -INFINITY},
+                  {-2, -INFINITY},
+                  {-1, -INFINITY},
+                  {-0.5, -INFINITY},
+                  {-0., -INFINITY},
+                  {+0., -INFINITY},
+                  {0.5, -INFINITY},
+                  {1, -INFINITY},
+                  {2, -INFINITY},
+                  {INFINITY, -INFINITY},
 
-    {NAN, -1},
-    {-INFINITY, -1},
-    {-2, -1},
-    {-1, -1},
-    {-0.5, -1},
-    {-0., -1},
-    {+0., -1},
-    {0.5, -1},
-    {1, -1},
-    {2, -1},
-    {INFINITY, -1},
+                  {NAN, -2},
+                  {-INFINITY, -2},
+                  {-2, -2},
+                  {-1, -2},
+                  {-0.5, -2},
+                  {-0., -2},
+                  {+0., -2},
+                  {0.5, -2},
+                  {1, -2},
+                  {2, -2},
+                  {INFINITY, -2},
 
-    {NAN, -0.5},
-    {-INFINITY, -0.5},
-    {-2, -0.5},
-    {-1, -0.5},
-    {-0.5, -0.5},
-    {-0., -0.5},
-    {+0., -0.5},
-    {0.5, -0.5},
-    {1, -0.5},
-    {2, -0.5},
-    {INFINITY, -0.5},
+                  {NAN, -1},
+                  {-INFINITY, -1},
+                  {-2, -1},
+                  {-1, -1},
+                  {-0.5, -1},
+                  {-0., -1},
+                  {+0., -1},
+                  {0.5, -1},
+                  {1, -1},
+                  {2, -1},
+                  {INFINITY, -1},
 
-    {NAN, -0.},
-    {-INFINITY, -0.},
-    {-2, -0.},
-    {-1, -0.},
-    {-0.5, -0.},
-    {-0., -0.},
-    {+0., -0.},
-    {0.5, -0.},
-    {1, -0.},
-    {2, -0.},
-    {INFINITY, -0.},
+                  {NAN, -0.5},
+                  {-INFINITY, -0.5},
+                  {-2, -0.5},
+                  {-1, -0.5},
+                  {-0.5, -0.5},
+                  {-0., -0.5},
+                  {+0., -0.5},
+                  {0.5, -0.5},
+                  {1, -0.5},
+                  {2, -0.5},
+                  {INFINITY, -0.5},
 
-    {NAN, 0.},
-    {-INFINITY, 0.},
-    {-2, 0.},
-    {-1, 0.},
-    {-0.5, 0.},
-    {-0., 0.},
-    {+0., 0.},
-    {0.5, 0.},
-    {1, 0.},
-    {2, 0.},
-    {INFINITY, 0.},
+                  {NAN, -0.},
+                  {-INFINITY, -0.},
+                  {-2, -0.},
+                  {-1, -0.},
+                  {-0.5, -0.},
+                  {-0., -0.},
+                  {+0., -0.},
+                  {0.5, -0.},
+                  {1, -0.},
+                  {2, -0.},
+                  {INFINITY, -0.},
 
-    {NAN, 0.5},
-    {-INFINITY, 0.5},
-    {-2, 0.5},
-    {-1, 0.5},
-    {-0.5, 0.5},
-    {-0., 0.5},
-    {+0., 0.5},
-    {0.5, 0.5},
-    {1, 0.5},
-    {2, 0.5},
-    {INFINITY, 0.5},
+                  {NAN, 0.},
+                  {-INFINITY, 0.},
+                  {-2, 0.},
+                  {-1, 0.},
+                  {-0.5, 0.},
+                  {-0., 0.},
+                  {+0., 0.},
+                  {0.5, 0.},
+                  {1, 0.},
+                  {2, 0.},
+                  {INFINITY, 0.},
 
-    {NAN, 1},
-    {-INFINITY, 1},
-    {-2, 1},
-    {-1, 1},
-    {-0.5, 1},
-    {-0., 1},
-    {+0., 1},
-    {0.5, 1},
-    {1, 1},
-    {2, 1},
-    {INFINITY, 1},
+                  {NAN, 0.5},
+                  {-INFINITY, 0.5},
+                  {-2, 0.5},
+                  {-1, 0.5},
+                  {-0.5, 0.5},
+                  {-0., 0.5},
+                  {+0., 0.5},
+                  {0.5, 0.5},
+                  {1, 0.5},
+                  {2, 0.5},
+                  {INFINITY, 0.5},
 
-    {NAN, 2},
-    {-INFINITY, 2},
-    {-2, 2},
-    {-1, 2},
-    {-0.5, 2},
-    {-0., 2},
-    {+0., 2},
-    {0.5, 2},
-    {1, 2},
-    {2, 2},
-    {INFINITY, 2},
+                  {NAN, 1},
+                  {-INFINITY, 1},
+                  {-2, 1},
+                  {-1, 1},
+                  {-0.5, 1},
+                  {-0., 1},
+                  {+0., 1},
+                  {0.5, 1},
+                  {1, 1},
+                  {2, 1},
+                  {INFINITY, 1},
 
-    {NAN, INFINITY},
-    {-INFINITY, INFINITY},
-    {-2, INFINITY},
-    {-1, INFINITY},
-    {-0.5, INFINITY},
-    {-0., INFINITY},
-    {+0., INFINITY},
-    {0.5, INFINITY},
-    {1, INFINITY},
-    {2, INFINITY},
-    {INFINITY, INFINITY}
+                  {NAN, 2},
+                  {-INFINITY, 2},
+                  {-2, 2},
+                  {-1, 2},
+                  {-0.5, 2},
+                  {-0., 2},
+                  {+0., 2},
+                  {0.5, 2},
+                  {1, 2},
+                  {2, 2},
+                  {INFINITY, 2},
 
-};
+                  {NAN, INFINITY},
+                  {-INFINITY, INFINITY},
+                  {-2, INFINITY},
+                  {-1, INFINITY},
+                  {-0.5, INFINITY},
+                  {-0., INFINITY},
+                  {+0., INFINITY},
+                  {0.5, INFINITY},
+                  {1, INFINITY},
+                  {2, INFINITY},
+                  {INFINITY, INFINITY},
+                  {INFINITY, fromRep32(0x7f800001) /* NaN */}};
 
-int main()
-{
-    const unsigned N = sizeof(x) / sizeof(x[0]);
-    unsigned i, j;
-    for (i = 0; i < N; ++i)
-    {
-        for (j = 0; j < N; ++j)
-        {
-            if (test__divsc3(x[i][0], x[i][1], x[j][0], x[j][1]))
-                return 1;
-        }
+  const unsigned N = sizeof(x) / sizeof(x[0]);
+  unsigned i, j;
+  for (i = 0; i < N; ++i) {
+    for (j = 0; j < N; ++j) {
+      if (test__divsc3(x[i][0], x[i][1], x[j][0], x[j][1]))
+        return 1;
     }
+  }
 
-    return 0;
+  return 0;
 }



More information about the llvm-commits mailing list