From 70d87497e760dca94ef78e4e936f6d461f36e80d Mon Sep 17 00:00:00 2001 From: Johannes Pfau Date: Sun, 20 Jan 2019 12:15:47 +0000 Subject: [PATCH] [D] Fix IdentityExp comparison for complex floats. gcc/d/ChangeLog: 2019-01-20 Johannes Pfau * expr.cc (build_float_identity): New function. (ExprVisitor::visit(IdentityExp)): Add support for complex types. gcc/testsuite/ChangeLog: 2019-01-20 Johannes Pfau * gdc.dg/runnable.d: Add tests for comparing complex types. From-SVN: r268103 --- gcc/d/ChangeLog | 5 +++++ gcc/d/expr.cc | 33 ++++++++++++++++++++++++++++----- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gdc.dg/runnable.d | 22 ++++++++++++++++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index fa4ba35bf6b..f062ff8f24f 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,8 @@ +2019-01-20 Johannes Pfau + + * expr.cc (build_float_identity): New function. + (ExprVisitor::visit(IdentityExp)): Add support for complex types. + 2019-01-16 Iain Buclaw PR d/87824 diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 15754a1dc2e..a1f7c262dc8 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -43,6 +43,20 @@ along with GCC; see the file COPYING3. If not see #include "d-tree.h" +/* Build a floating-point identity comparison between T1 and T2, ignoring any + excessive padding in the type. CODE is EQ_EXPR or NE_EXPR comparison. */ + +static tree +build_float_identity (tree_code code, tree t1, tree t2) +{ + 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. All visit methods accept one parameter E, which holds the frontend AST @@ -282,12 +296,21 @@ public: 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); + if (!tb1->iscomplex ()) + this->result_ = build_float_identity (code, t1, t2); + else + { + /* Compare the real and imaginary parts separately. */ + tree req = build_float_identity (code, real_part (t1), + real_part (t2)); + tree ieq = build_float_identity (code, imaginary_part (t1), + imaginary_part (t2)); - 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->ty == Tstruct) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8c1707a53b2..de3a3c428d2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-01-20 Johannes Pfau + + * gdc.dg/runnable.d: Add tests for comparing complex types. + 2019-01-20 Kewen Lin * gcc.target/powerpc/altivec_vld_vst_addr.c: Remove, split into 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"); }