@@ -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 {
0 commit comments