[PATCH] D28862: [compiler-rt] [test] Use approximate comparison on float types

2017-01-18 Thread Michał Górny via Phabricator via cfe-commits
mgorny created this revision.
Herald added a subscriber: dberris.

Use approximate comparison between the result of __divsc3()
and the canonical value calculated, to allow the possible difference of
1 representable value resulting from optimization.

For example, the value of (0.01+j0.01) / (-0.50-j2.00))
computed the canonical way without specific machine flags is:

  z = -0x1.3bce70p-21 + j0x1.7af7bcp-22

However, if -march=i386 -mfpmath=387 is used, it becomes:

  z = -0x1.3bce72p-21 + j0x1.7af7bcp-22

While this difference is insignificant, it may cause the exact
comparison used in tests to fail. Allowing the difference of one
representable value seems to be a reasonable compromise.


Repository:
  rL LLVM

https://reviews.llvm.org/D28862

Files:
  test/builtins/Unit/divsc3_test.c


Index: test/builtins/Unit/divsc3_test.c
===
--- test/builtins/Unit/divsc3_test.c
+++ test/builtins/Unit/divsc3_test.c
@@ -14,6 +14,7 @@
 #include "int_lib.h"
 #include 
 #include 
+#include 
 #include 
 
 // Returns: the quotient of (a + ib) / (c + id)
@@ -47,6 +48,25 @@
 return non_zero;
 }
 
+// check for equality assuming that both real and imaginary parts
+// can differ by exactly 1 representable value, in order to handle
+// different levels of accuracy on 32-bit x86
+static bool approx_equal(float _Complex a, float _Complex b) {
+if (a != b) {
+float ra = __real__ a;
+float ia = __imag__ a;
+float rb = __real__ b;
+float ib = __imag__ b;
+
+if (ra != rb && nextafterf(ra, rb) != rb)
+return false;
+if (ia != ib && nextafterf(ia, ib) != ib)
+return false;
+}
+
+return true;
+}
+
 int test__divsc3(float a, float b, float c, float d)
 {
 float _Complex r = __divsc3(a, b, c, d);
@@ -100,7 +120,7 @@
 {
 float _Complex z = (a * c + b * d) / (c * c + d * d)
  + (b * c - a * d) / (c * c + d * d) * _Complex_I;
-if (r != z)
+if (!approx_equal(r, z))
 return 1;
 }
 break;


Index: test/builtins/Unit/divsc3_test.c
===
--- test/builtins/Unit/divsc3_test.c
+++ test/builtins/Unit/divsc3_test.c
@@ -14,6 +14,7 @@
 #include "int_lib.h"
 #include 
 #include 
+#include 
 #include 
 
 // Returns: the quotient of (a + ib) / (c + id)
@@ -47,6 +48,25 @@
 return non_zero;
 }
 
+// check for equality assuming that both real and imaginary parts
+// can differ by exactly 1 representable value, in order to handle
+// different levels of accuracy on 32-bit x86
+static bool approx_equal(float _Complex a, float _Complex b) {
+if (a != b) {
+float ra = __real__ a;
+float ia = __imag__ a;
+float rb = __real__ b;
+float ib = __imag__ b;
+
+if (ra != rb && nextafterf(ra, rb) != rb)
+return false;
+if (ia != ib && nextafterf(ia, ib) != ib)
+return false;
+}
+
+return true;
+}
+
 int test__divsc3(float a, float b, float c, float d)
 {
 float _Complex r = __divsc3(a, b, c, d);
@@ -100,7 +120,7 @@
 {
 float _Complex z = (a * c + b * d) / (c * c + d * d)
  + (b * c - a * d) / (c * c + d * d) * _Complex_I;
-if (r != z)
+if (!approx_equal(r, z))
 return 1;
 }
 break;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28862: [compiler-rt] [test] Use approximate comparison on float types

2017-01-18 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added a comment.

I think that the checks should be exact.  Instead, we should check the 
compilation mode and change the exact value (i.e. if we are using i387 mode, we 
would use the adjusted value).


Repository:
  rL LLVM

https://reviews.llvm.org/D28862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28862: [compiler-rt] [test] Use approximate comparison on float types

2017-01-19 Thread Michał Górny via Phabricator via cfe-commits
mgorny added a comment.

Just to be clear, the values also differ per -O0 vs -O2. I'm not sure if we can 
even reliably figure that out.

I've tried to work around the issue by building everything in 387 mode. 
However, in that case muldc3_test has even larger mismatches and didn't really 
want to go figuring that out.


Repository:
  rL LLVM

https://reviews.llvm.org/D28862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28862: [compiler-rt] [test] Use approximate comparison on float types

2017-01-19 Thread Steve Canon via Phabricator via cfe-commits
scanon added a comment.

These tests should either be exact, or should have a tolerance that's 
mathematically sound. +/-1ulp is not sound; the allowed error should be 
proportional to the magnitude of the larger of the real and imaginary 
components of the result -- e.g. if one component is very small compared to the 
other, the smaller one may have *no* "correct" bits and still be acceptable.


Repository:
  rL LLVM

https://reviews.llvm.org/D28862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28862: [compiler-rt] [test] Use approximate comparison on float types

2017-02-15 Thread Michał Górny via Phabricator via cfe-commits
mgorny abandoned this revision.
mgorny added a comment.

I've opened http://bugs.llvm.org/show_bug.cgi?id=31964 to track this further. I 
don't really have time to look into it in more detail at the moment.


Repository:
  rL LLVM

https://reviews.llvm.org/D28862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits