Skip to content
This repository was archived by the owner on Jun 20, 2019. It is now read-only.

Commit b15af9e

Browse files
committed
Fix IdentityExp comparison for complex floats
https://bugzilla.gdcproject.org/show_bug.cgi?id=309
1 parent 8e9a539 commit b15af9e

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

gcc/d/expr.cc

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ along with GCC; see the file COPYING3. If not see
4242

4343
#include "d-tree.h"
4444

45+
/* Helper function for floating point identity comparison. Compare
46+
only well-defined bits, ignore padding (e.g. for X86 80bit real). */
47+
48+
static tree build_float_identity (tree_code code, tree t1, tree t2)
49+
{
50+
/* For floating-point values, identity is defined as the bits in the
51+
operands being identical. */
52+
tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
53+
tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
54+
55+
tree result = build_call_expr (tmemcmp, 3, build_address (t1),
56+
build_address (t2), size);
57+
return build_boolop (code, result, integer_zero_node);
58+
}
4559

4660
/* Implements the visitor interface to build the GCC trees of all Expression
4761
AST classes emitted from the D Front-end.
@@ -275,19 +289,23 @@ class ExprVisitor : public Visitor
275289
this->result_ = d_convert (build_ctype (e->type),
276290
build_boolop (code, t1, t2));
277291
}
278-
else if (tb1->isfloating () && tb1->ty != Tvector)
292+
else if (tb1->iscomplex () && tb1->ty != Tvector)
279293
{
280-
/* For floating-point values, identity is defined as the bits in the
281-
operands being identical. */
282-
tree t1 = d_save_expr (build_expr (e->e1));
283-
tree t2 = d_save_expr (build_expr (e->e2));
284-
285-
tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
286-
tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
294+
tree e1 = d_save_expr (build_expr (e->e1));
295+
tree e2 = d_save_expr (build_expr (e->e2));
296+
tree req = build_float_identity (code, real_part (e1), real_part (e2));
297+
tree ieq = build_float_identity (code, imaginary_part (e1), imaginary_part (e2));
287298

288-
tree result = build_call_expr (tmemcmp, 3, build_address (t1),
289-
build_address (t2), size);
290-
this->result_ = build_boolop (code, result, integer_zero_node);
299+
if (code == EQ_EXPR)
300+
this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
301+
else
302+
this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
303+
}
304+
else if (tb1->isfloating () && tb1->ty != Tvector)
305+
{
306+
tree e1 = d_save_expr (build_expr (e->e1));
307+
tree e2 = d_save_expr (build_expr (e->e2));
308+
this->result_ = build_float_identity (code, e1, e2);
291309
}
292310
else if (tb1->ty == Tstruct)
293311
{

gcc/testsuite/gdc.dg/runnable.d

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,27 @@ void test286()
15331533
assert(0);
15341534
}
15351535

1536+
/******************************************/
1537+
// https://bugzilla.gdcproject.org/show_bug.cgi?id=309
1538+
1539+
void test309()
1540+
{
1541+
creal f1 = +0.0 + 0.0i;
1542+
creal f2 = +0.0 - 0.0i;
1543+
creal f3 = -0.0 + 0.0i;
1544+
creal f4 = +0.0 + 0.0i;
1545+
1546+
assert(f1 !is f2);
1547+
assert(f1 !is f3);
1548+
assert(f2 !is f3);
1549+
assert(f1 is f4);
1550+
1551+
assert(!(f1 is f2));
1552+
assert(!(f1 is f3));
1553+
assert(!(f2 is f3));
1554+
assert(!(f1 !is f4));
1555+
}
1556+
15361557
/******************************************/
15371558

15381559
void main()
@@ -1570,6 +1591,7 @@ void main()
15701591
test273();
15711592
test285();
15721593
test286();
1594+
test309();
15731595

15741596
printf("Success!\n");
15751597
}

0 commit comments

Comments
 (0)