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.