[D] Fix IdentityExp comparison for complex floats.
authorJohannes Pfau <johannespfau@gmail.com>
Sun, 20 Jan 2019 12:15:47 +0000 (12:15 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 20 Jan 2019 12:15:47 +0000 (12:15 +0000)
gcc/d/ChangeLog:

2019-01-20  Johannes Pfau  <johannespfau@gmail.com>

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

gcc/testsuite/ChangeLog:

2019-01-20  Johannes Pfau  <johannespfau@gmail.com>

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

From-SVN: r268103

gcc/d/ChangeLog
gcc/d/expr.cc
gcc/testsuite/ChangeLog
gcc/testsuite/gdc.dg/runnable.d

index fa4ba35bf6bcc1444e81c539a3e26459af5125a4..f062ff8f24fc2bafe59d1bc6242efb90a777150f 100644 (file)
@@ -1,3 +1,8 @@
+2019-01-20  Johannes Pfau  <johannespfau@gmail.com>
+
+       * expr.cc (build_float_identity): New function.
+       (ExprVisitor::visit(IdentityExp)): Add support for complex types.
+
 2019-01-16  Iain Buclaw  <ibuclaw@gdcproject.org>
 
        PR d/87824
index 15754a1dc2efce73f625e86f30d9b883e726058f..a1f7c262dc8f2a93557a9b2a30d66ebaac3606a4 100644 (file)
@@ -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)
       {
index 8c1707a53b2e68def2eaae8064643e2bc81b58b7..de3a3c428d220b4a14b9eaf6f0a80fc4388765aa 100644 (file)
@@ -1,3 +1,7 @@
+2019-01-20  Johannes Pfau  <johannespfau@gmail.com>
+
+       * gdc.dg/runnable.d: Add tests for comparing complex types.
+
 2019-01-20  Kewen Lin  <linkw@gcc.gnu.org>
 
        * gcc.target/powerpc/altivec_vld_vst_addr.c: Remove, split into 
index ec172fae8109f7b13d4dc2b2fff39ce9c7ab120f..65c71e86292cb632c9a0eb91f944c4237d7d4133 100644 (file)
@@ -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");
 }