This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, V2, d] Fix IdentityExp comparison for complex floats
Next version, addresses the review comments.
Tested at https://github.com/D-Programming-GDC/GDC/pull/768
---
gcc/d/ChangeLog:
2018-11-28 Johannes Pfau <johannespfau@gmail.com>
* expr.cc (ExprVisitor::visit(IdentityExp)): Add support for complex types.
(build_float_identity): New function.
gcc/testsuite/ChangeLog:
2018-11-28 Johannes Pfau <johannespfau@gmail.com>
* gdc.dg/runnable.d: Test IdentityExp for complex types.
gcc/d/expr.cc | 40 ++++++++++++++++++++++++---------
gcc/testsuite/gdc.dg/runnable.d | 22 ++++++++++++++++++
2 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 9a1aad42ddc..91cb02f1e9a 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -42,6 +42,20 @@ along with GCC; see the file COPYING3. If not see
#include "d-tree.h"
+/* Helper function for floating point identity comparison. Compare
+ only well-defined bits, ignore padding (e.g. for X86 80bit real). */
+
+static tree build_float_identity (tree_code code, tree t1, tree t2)
+{
+ /* For floating-point values, identity is defined as the bits in the
+ operands being identical. */
+ tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
+ tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
+
+ tree result = build_call_expr (tmemcmp, 3, build_address (t1),
+ build_address (t2), size);
+ return build_boolop (code, result, integer_zero_node);
+}
/* Implements the visitor interface to build the GCC trees of all Expression
AST classes emitted from the D Front-end.
@@ -275,19 +289,23 @@ public:
this->result_ = d_convert (build_ctype (e->type),
build_boolop (code, t1, t2));
}
- else if (tb1->isfloating () && tb1->ty != Tvector)
+ else if (tb1->iscomplex () && tb1->ty != Tvector)
{
- /* For floating-point values, identity is defined as the bits in the
- operands being identical. */
- tree t1 = d_save_expr (build_expr (e->e1));
- tree t2 = d_save_expr (build_expr (e->e2));
-
- tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
- tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
+ tree e1 = d_save_expr (build_expr (e->e1));
+ tree e2 = d_save_expr (build_expr (e->e2));
+ tree req = build_float_identity (code, real_part (e1), real_part (e2));
+ tree ieq = build_float_identity (code, imaginary_part (e1), imaginary_part (e2));
- tree result = build_call_expr (tmemcmp, 3, build_address (t1),
- build_address (t2), size);
- this->result_ = build_boolop (code, result, integer_zero_node);
+ if (code == EQ_EXPR)
+ this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
+ else
+ this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
+ }
+ else if (tb1->isfloating () && tb1->ty != Tvector)
+ {
+ tree e1 = d_save_expr (build_expr (e->e1));
+ tree e2 = d_save_expr (build_expr (e->e2));
+ this->result_ = build_float_identity (code, e1, e2);
}
else if (tb1->ty == Tstruct)
{
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
index ec172fae810..65c71e86292 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -1534,6 +1534,27 @@ void test286()
assert(0);
}
+/******************************************/
+// https://bugzilla.gdcproject.org/show_bug.cgi?id=309
+
+void test309()
+{
+ creal f1 = +0.0 + 0.0i;
+ creal f2 = +0.0 - 0.0i;
+ creal f3 = -0.0 + 0.0i;
+ creal f4 = +0.0 + 0.0i;
+
+ assert(f1 !is f2);
+ assert(f1 !is f3);
+ assert(f2 !is f3);
+ assert(f1 is f4);
+
+ assert(!(f1 is f2));
+ assert(!(f1 is f3));
+ assert(!(f2 is f3));
+ assert(!(f1 !is f4));
+}
+
/******************************************/
void main()
@@ -1571,6 +1592,7 @@ void main()
test273();
test285();
test286();
+ test309();
printf("Success!\n");
}
--
2.19.1