https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79981

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-03-10
     Ever confirmed|0                           |1

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
No, the reason is really the FE implements (_Bool) int as int != 0 while
fold_builtin_atomic_compare_exchange emits (_Bool) int in the IL which
isn't forwarded the same way:

  if (oldlhs)
    {
      g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
                               build1 (IMAGPART_EXPR, itype, lhs));
      if (throws)
        {
          gsi_insert_on_edge_immediate (e, g);
          *gsi = gsi_for_stmt (g);
        }
      else
        gsi_insert_after (gsi, g, GSI_NEW_STMT);
      g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
      gsi_insert_after (gsi, g, GSI_NEW_STMT);

(gdb) p debug_tree (oldlhs)
 <ssa_name 0x7ffff68ad990
    type <boolean_type 0x7ffff68bab28 _Bool public unsigned QI
        size <integer_cst 0x7ffff68a2dc8 constant 8>
        unit size <integer_cst 0x7ffff68a2de0 constant 1>
        align 8 symtab 0 alias set -1 canonical type 0x7ffff68bab28 precision 1
min <integer_cst 0x7ffff68bf030 0> max <integer_cst 0x7ffff68bf060 1>>
    visited
    def_stmt _1 = (_Bool) _13;
    version 1>


Note we do not have any folding/match.pd to transform (_Bool) whatever to
!= 0 (or the other way around) so we're clearly missing some canonicalization
here.  Note that the above code also misses to fold the stmts it generates
(it should use gimple_build (...) which would do this).

Sth like

(simplify
 (convert @1)
 (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
      && INTEGRAL_TYPE_P (type)
      && (TREE_CODE (type) == BOOLEAN_TYPE
          || TYPE_PRECISION (type) == 1))
  (ne @1 { build_zero_cst (TREE_TYPE (@1)); })))

might do this (but I'm somewhat leaning towards making the canonicalization
the other way around which would mean fixing the forwarding of the comparison
instead).

Thus, for a "quick" fix simply change what we emit from
fold_builtin_atomic_compare_exchange ...

Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   (revision 245976)
+++ gcc/gimple-fold.c   (working copy)
@@ -3581,7 +3581,8 @@ fold_builtin_atomic_compare_exchange (gi
        }
       else
        gsi_insert_after (gsi, g, GSI_NEW_STMT);
-      g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
+      g = gimple_build_assign (oldlhs, NE_EXPR, gimple_assign_lhs (g),
+                              build_zero_cst (TREE_TYPE (gimple_assign_lhs
(g))));
       gsi_insert_after (gsi, g, GSI_NEW_STMT);
     }
   g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,

of course needs to be conditional on oldlhs being bool and lhs being
integral.

Reply via email to