public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, d] Fix IdentityExp comparison for complex floats
@ 2018-11-24 10:43 Johannes Pfau
  2018-11-25 10:09 ` Iain Buclaw
  0 siblings, 1 reply; 6+ messages in thread
From: Johannes Pfau @ 2018-11-24 10:43 UTC (permalink / raw)
  To: gcc-patches

Currently all identity comparisons for complex types (c1 is c2) return
true. This is caused by the rrent implementation being only correct for
real types, so this adds new code for the complex type cases.

Fixes https://bugzilla.gdcproject.org/show_bug.cgi?id=309

Tested on x86_64-linux-gnu and on the GDC CI
(https://github.com/D-Programming-GDC/GDC/pull/768)
--
Johannes


---
gcc/d/ChangeLog:

2018-11-24  Johannes Pfau  <johannespfau@gmail.com>

	* expr.cc (ExprVisitor::visit(IdentityExp)): Add support for complex types.
	(ExprVisitor::build_float_identity): New function. 

gcc/testsuite/ChangeLog:

2018-11-24  Johannes Pfau  <johannespfau@gmail.com>

	* gdc.dg/runnable.d: Test IdentityExp for complex types.


 gcc/d/expr.cc                   | 44 +++++++++++++++++++++++++--------
 gcc/testsuite/gdc.dg/runnable.d | 22 +++++++++++++++++
 2 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 9a1aad42d..7eef00ac0 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -255,6 +255,21 @@ public:
     this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
   }
 
+  /* 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);
+  }
+
   /* Build an identity comparison expression.  Operands go through the
      usual conversions to bring them to a common type before comparison.
      The result type is bool.  */
@@ -275,19 +290,28 @@ 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 e1 = d_save_expr (build_expr (e->e1));
+	tree e2 = d_save_expr (build_expr (e->e2));
+	tree re1 = real_part (e1);
+	tree im1 = imaginary_part (e1);
+	tree re2 = real_part (e2);
+	tree im2 = imaginary_part (e2);
 
-	tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
-	tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
+	tree req = build_float_identity (code, re1, re2);
+	tree ieq = build_float_identity (code, im1, im2);
 
-	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 4f1ef76e4..2d33d7d10 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -1533,6 +1533,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()
@@ -1570,6 +1591,7 @@ void main()
     test273();
     test285();
     test286();
+    test309();
 
     printf("Success!\n");
 }
-- 
2.19.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH, d] Fix IdentityExp comparison for complex floats
  2018-11-24 10:43 [PATCH, d] Fix IdentityExp comparison for complex floats Johannes Pfau
@ 2018-11-25 10:09 ` Iain Buclaw
  2018-11-28 21:32   ` [PATCH, V2, " Johannes Pfau
  0 siblings, 1 reply; 6+ messages in thread
From: Iain Buclaw @ 2018-11-25 10:09 UTC (permalink / raw)
  To: Johannes Pfau; +Cc: gcc-patches

On Sat, 24 Nov 2018 at 11:43, Johannes Pfau <johannespfau@gmail.com> wrote:
>
> Currently all identity comparisons for complex types (c1 is c2) return
> true. This is caused by the rrent implementation being only correct for
> real types, so this adds new code for the complex type cases.
>
> Fixes https://bugzilla.gdcproject.org/show_bug.cgi?id=309
>
> Tested on x86_64-linux-gnu and on the GDC CI
> (https://github.com/D-Programming-GDC/GDC/pull/768)
> --
> Johannes
>
>
> ---
> gcc/d/ChangeLog:
>
> 2018-11-24  Johannes Pfau  <johannespfau@gmail.com>
>
>         * expr.cc (ExprVisitor::visit(IdentityExp)): Add support for complex types.
>         (ExprVisitor::build_float_identity): New function.
>
> gcc/testsuite/ChangeLog:
>
> 2018-11-24  Johannes Pfau  <johannespfau@gmail.com>
>
>         * gdc.dg/runnable.d: Test IdentityExp for complex types.
>
>
>  gcc/d/expr.cc                   | 44 +++++++++++++++++++++++++--------
>  gcc/testsuite/gdc.dg/runnable.d | 22 +++++++++++++++++
>  2 files changed, 56 insertions(+), 10 deletions(-)
>
> diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
> index 9a1aad42d..7eef00ac0 100644
> --- a/gcc/d/expr.cc
> +++ b/gcc/d/expr.cc
> @@ -255,6 +255,21 @@ public:
>      this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
>    }
>
> +  /* 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)

It may be better to make this a static free function instead because...

[-- snip --]

> +       tree e1 = d_save_expr (build_expr (e->e1));
> +       tree e2 = d_save_expr (build_expr (e->e2));
> +       tree re1 = real_part (e1);
> +       tree im1 = imaginary_part (e1);
> +       tree re2 = real_part (e2);
> +       tree im2 = imaginary_part (e2);
>
> -       tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
> -       tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
> +       tree req = build_float_identity (code, re1, re2);
> +       tree ieq = build_float_identity (code, im1, im2);
>

... as I understand it, the preferred C++ coding convention requires
that static member function calls always be fully qualified.  So here,
it would be ExprVisitor::build_float_identity, as it makes it clear
where the function comes from.

Don't think its really required to put the result of real_part and
imaginary_part into a temporary, it's only used once, and there's
plenty of horizontal space to use.

Change itself looks OK and makes sense, we definitely don't want to do
memcmp() on the padding.

--
Iain.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH, V2, d] Fix IdentityExp comparison for complex floats
  2018-11-25 10:09 ` Iain Buclaw
@ 2018-11-28 21:32   ` Johannes Pfau
  2018-11-28 22:46     ` Iain Buclaw
  0 siblings, 1 reply; 6+ messages in thread
From: Johannes Pfau @ 2018-11-28 21:32 UTC (permalink / raw)
  To: gcc-patches

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH, V2, d] Fix IdentityExp comparison for complex floats
  2018-11-28 21:32   ` [PATCH, V2, " Johannes Pfau
@ 2018-11-28 22:46     ` Iain Buclaw
  2018-12-17 22:05       ` Iain Buclaw
  0 siblings, 1 reply; 6+ messages in thread
From: Iain Buclaw @ 2018-11-28 22:46 UTC (permalink / raw)
  To: Johannes Pfau; +Cc: gcc-patches

On Wed, 28 Nov 2018 at 22:32, Johannes Pfau <johannespfau@gmail.com> wrote:
>
> 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(-)
>

As I've said before, looks reasonable to me.  Thanks.

-- 
Iain

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH, V2, d] Fix IdentityExp comparison for complex floats
  2018-11-28 22:46     ` Iain Buclaw
@ 2018-12-17 22:05       ` Iain Buclaw
  2019-01-20 12:56         ` Iain Buclaw
  0 siblings, 1 reply; 6+ messages in thread
From: Iain Buclaw @ 2018-12-17 22:05 UTC (permalink / raw)
  To: Johannes Pfau; +Cc: gcc-patches

On Wed, 28 Nov 2018 at 23:46, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
>
> On Wed, 28 Nov 2018 at 22:32, Johannes Pfau <johannespfau@gmail.com> wrote:
> >
> > 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(-)
> >
>
> As I've said before, looks reasonable to me.  Thanks.
>

I noticed that this hasn't been pushed in yet, I was about to go ahead
and commit it, however... there's another case to consider, structs
with creal fields.

This test - modified from your patch - is another that should pass but
currently doesn't.
---
struct CReal
{
    creal value;
}

CReal s1 = CReal(+0.0 + 0.0i);
CReal s2 = CReal(+0.0 - 0.0i);
CReal s3 = CReal(-0.0 + 0.0i);
CReal s4 = CReal(+0.0 + 0.0i);

assert(s1 !is s2);
assert(s1 !is s3);
assert(s2 !is s3);
assert(s1 is s4);

assert(!(s1 is s2));
assert(!(s1 is s3));
assert(!(s2 is s3));
assert(!(s1 !is s4));
---

I'll send a supplementary patch, and commit both together.

-- 
Iain

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH, V2, d] Fix IdentityExp comparison for complex floats
  2018-12-17 22:05       ` Iain Buclaw
@ 2019-01-20 12:56         ` Iain Buclaw
  0 siblings, 0 replies; 6+ messages in thread
From: Iain Buclaw @ 2019-01-20 12:56 UTC (permalink / raw)
  To: Johannes Pfau; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1805 bytes --]

On Mon, 17 Dec 2018 at 23:05, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
>
> On Wed, 28 Nov 2018 at 23:46, Iain Buclaw <ibuclaw@gdcproject.org> wrote:
> >
> > On Wed, 28 Nov 2018 at 22:32, Johannes Pfau <johannespfau@gmail.com> wrote:
> > >
> > > 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(-)
> > >
> >
> > As I've said before, looks reasonable to me.  Thanks.
> >
>
> I'll send a supplementary patch, and commit both together.
>

Committed to trunk along with patch that handles creal fields.

Bootstrapped and regression tested on x86_64-linux-gnu.

-- 
Iain
---
gcc/d/ChangeLog:

2019-01-20  Iain Buclaw  <ibuclaw@gdcproject.org>

    * d-codegen.cc (identity_compare_p): Return false if seen built-in
    type with padding.
    (build_float_identity): Moved here from expr.cc.
    (lower_struct_comparison): Handle real and complex types.
    * d-tree.h (build_float_identity): New.
    * expr.cc (build_float_identity): Move to d-codegen.cc.

gcc/testsuite/ChangeLog:

2019-01-20  Iain Buclaw  <ibuclaw@gdcproject.org>

    * gdc.dg/runnable.d: Add more tests for comparing complex types.

---

[-- Attachment #2: crealcmp.patch --]
[-- Type: text/x-patch, Size: 5749 bytes --]

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 7ca0acffcc4..58c8257c63c 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -798,15 +798,21 @@ identity_compare_p (StructDeclaration *sd)
   for (size_t i = 0; i < sd->fields.dim; i++)
     {
       VarDeclaration *vd = sd->fields[i];
+      Type *tb = vd->type->toBasetype ();
 
       /* Check inner data structures.  */
-      if (vd->type->ty == Tstruct)
+      if (tb->ty == Tstruct)
 	{
-	  TypeStruct *ts = (TypeStruct *) vd->type;
+	  TypeStruct *ts = (TypeStruct *) tb;
 	  if (!identity_compare_p (ts->sym))
 	    return false;
 	}
 
+      /* Check for types that may have padding.  */
+      if ((tb->ty == Tcomplex80 || tb->ty == Tfloat80 || tb->ty == Timaginary80)
+	  && Target::realpad != 0)
+	return false;
+
       if (offset <= vd->offset)
 	{
 	  /* There's a hole in the struct.  */
@@ -824,6 +830,20 @@ identity_compare_p (StructDeclaration *sd)
   return true;
 }
 
+/* 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.  */
+
+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);
+}
+
 /* Lower a field-by-field equality expression between T1 and T2 of type SD.
    CODE is the EQ_EXPR or NE_EXPR comparison.  */
 
@@ -859,29 +879,45 @@ lower_struct_comparison (tree_code code, StructDeclaration *sd,
   for (size_t i = 0; i < sd->fields.dim; i++)
     {
       VarDeclaration *vd = sd->fields[i];
+      Type *type = vd->type->toBasetype ();
       tree sfield = get_symbol_decl (vd);
 
       tree t1ref = component_ref (t1, sfield);
       tree t2ref = component_ref (t2, sfield);
       tree tcmp;
 
-      if (vd->type->ty == Tstruct)
+      if (type->ty == Tstruct)
 	{
 	  /* Compare inner data structures.  */
-	  StructDeclaration *decl = ((TypeStruct *) vd->type)->sym;
+	  StructDeclaration *decl = ((TypeStruct *) type)->sym;
 	  tcmp = lower_struct_comparison (code, decl, t1ref, t2ref);
 	}
+      else if (type->ty != Tvector && type->isintegral ())
+	{
+	  /* Integer comparison, no special handling required.  */
+	  tcmp = build_boolop (code, t1ref, t2ref);
+	}
+      else if (type->ty != Tvector && type->isfloating ())
+	{
+	  /* Floating-point comparison, don't compare padding in type.  */
+	  if (!type->iscomplex ())
+	    tcmp = build_float_identity (code, t1ref, t2ref);
+	  else
+	    {
+	      tree req = build_float_identity (code, real_part (t1ref),
+					       real_part (t2ref));
+	      tree ieq = build_float_identity (code, imaginary_part (t1ref),
+					       imaginary_part (t2ref));
+
+	      tcmp = build_boolop (tcode, req, ieq);
+	    }
+	}
       else
 	{
-	  tree stype = build_ctype (vd->type);
+	  tree stype = build_ctype (type);
 	  opt_scalar_int_mode mode = int_mode_for_mode (TYPE_MODE (stype));
 
-	  if (vd->type->ty != Tvector && vd->type->isintegral ())
-	    {
-	      /* Integer comparison, no special handling required.  */
-	      tcmp = build_boolop (code, t1ref, t2ref);
-	    }
-	  else if (mode.exists ())
+	  if (mode.exists ())
 	    {
 	      /* Compare field bits as their corresponding integer type.
 		    *((T*) &t1) == *((T*) &t2)  */
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 6ffb0f32a1f..0b3c5eddedd 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -522,6 +522,7 @@ extern tree d_mark_addressable (tree);
 extern tree d_mark_used (tree);
 extern tree d_mark_read (tree);
 extern bool identity_compare_p (StructDeclaration *);
+extern tree build_float_identity (tree_code, tree, tree);
 extern tree build_struct_comparison (tree_code, StructDeclaration *,
 				     tree, tree);
 extern tree build_array_struct_comparison (tree_code, StructDeclaration *,
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index a1f7c262dc8..4bfdde5a29a 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -43,20 +43,6 @@ 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
diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d
index 65c71e86292..e36a2585027 100644
--- a/gcc/testsuite/gdc.dg/runnable.d
+++ b/gcc/testsuite/gdc.dg/runnable.d
@@ -1553,6 +1553,26 @@ void test309()
     assert(!(f1 is f3));
     assert(!(f2 is f3));
     assert(!(f1 !is f4));
+
+    struct CReal
+    {
+        creal value;
+    }
+
+    CReal s1 = CReal(+0.0 + 0.0i);
+    CReal s2 = CReal(+0.0 - 0.0i);
+    CReal s3 = CReal(-0.0 + 0.0i);
+    CReal s4 = CReal(+0.0 + 0.0i);
+
+    assert(s1 !is s2);
+    assert(s1 !is s3);
+    assert(s2 !is s3);
+    assert(s1 is s4);
+
+    assert(!(s1 is s2));
+    assert(!(s1 is s3));
+    assert(!(s2 is s3));
+    assert(!(s1 !is s4));
 }
 
 /******************************************/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-01-20 12:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-24 10:43 [PATCH, d] Fix IdentityExp comparison for complex floats Johannes Pfau
2018-11-25 10:09 ` Iain Buclaw
2018-11-28 21:32   ` [PATCH, V2, " Johannes Pfau
2018-11-28 22:46     ` Iain Buclaw
2018-12-17 22:05       ` Iain Buclaw
2019-01-20 12:56         ` Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).