[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