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.