Hi, I'd like to revive the old discussion regarding the interaction of jump threading and b_c_p causing the latter to incorrectly return 1 in certain cases:
https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547236.html https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549288.html The conclusion was that this happening during threading is just a symptom of a deeper problem: SSA_NAMEs that are passed to b_c_p should not be registered for incremental updating. I performed a little experiment and added an assertion to create_new_def_for: --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -2996,6 +3014,8 @@ create_new_def_for (tree old_name, gimple *stmt, def_operand_p def) { tree new_name; + gcc_checking_assert (!used_by_bcp_p (old_name)); + timevar_push (TV_TREE_SSA_INCREMENTAL); if (!update_ssa_initialized_fn) This has of course fired when performing basic block duplication during threading, which can be fixed by avoiding duplication of basic blocks wi th b_c_p calls: --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -6224,7 +6224,8 @@ gimple_can_duplicate_bb_p (const_basic_block bb) || gimple_call_internal_p (g, IFN_GOMP_SIMT_EXIT) || gimple_call_internal_p (g, IFN_GOMP_SIMT_VOTE_ANY) || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_BFLY) - || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_IDX))) + || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_IDX) + || gimple_call_builtin_p (g, BUILT_IN_CONSTANT_P))) return false; } The second occurrence is a bit more interesting: gimple * vrp_insert::build_assert_expr_for (tree cond, tree v) { ... a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond); assertion = gimple_build_assign (NULL_TREE, a); ... tree new_def = create_new_def_for (v, assertion, NULL); The fix is also simple though: --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3101,6 +3101,9 @@ vrp_insert::process_assert_insertions_for (tree name, assert_locus *loc) if (loc->expr == loc->val) return false; + if (used_by_bcp_p (name)) + return false; + cond = build2 (loc->comp_code, boolean_type_node, loc->expr, loc- >val); assert_stmt = build_assert_expr_for (cond, name); if (loc->e) My original testcase did not trigger anything else. I'm planning to check how this affects the testsuite, but before going further I would like to ask: is this the right direction now? To me it looks a little-bit more heavy-handed than the original approach, but maybe it's worth it. Best regards, Ilya