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

Commit 6a30937

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

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

gcc/d/expr.cc

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,24 @@ class ExprVisitor : public Visitor
255255
this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
256256
}
257257

258+
/* Helper function for floating point identity comparison. Compare
259+
only well-defined bits, ignore padding (e.g. for X86 80bit real). */
260+
261+
static tree build_float_identity (tree_code code, tree e1, tree e2)
262+
{
263+
/* For floating-point values, identity is defined as the bits in the
264+
operands being identical. */
265+
tree t1 = d_save_expr (e1);
266+
tree t2 = d_save_expr (e2);
267+
268+
tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
269+
tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
270+
271+
tree result = build_call_expr (tmemcmp, 3, build_address (t1),
272+
build_address (t2), size);
273+
return build_boolop (code, result, integer_zero_node);
274+
}
275+
258276
/* Build an identity comparison expression. Operands go through the
259277
usual conversions to bring them to a common type before comparison.
260278
The result type is bool. */
@@ -275,19 +293,27 @@ class ExprVisitor : public Visitor
275293
this->result_ = d_convert (build_ctype (e->type),
276294
build_boolop (code, t1, t2));
277295
}
278-
else if (tb1->isfloating () && tb1->ty != Tvector)
296+
else if (tb1->iscomplex () && tb1->ty != Tvector)
279297
{
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));
298+
tree e1 = build_expr (e->e1);
299+
tree e2 = build_expr (e->e2);
300+
tree re1 = real_part (e1);
301+
tree im1 = imaginary_part (e1);
302+
tree re2 = real_part (e2);
303+
tree im2 = imaginary_part (e2);
284304

285-
tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
286-
tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
305+
tree req = build_float_identity (code, re1, re2);
306+
tree ieq = build_float_identity (code, im1, im2);
287307

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);
308+
if (code == EQ_EXPR)
309+
this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
310+
else
311+
this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
312+
}
313+
else if (tb1->isfloating () && tb1->ty != Tvector)
314+
{
315+
this->result_ = build_float_identity (code, build_expr (e->e1),
316+
build_expr (e->e2));
291317
}
292318
else if (tb1->ty == Tstruct)
293319
{

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)