Hi, before noce_find_if_block processes a block it sets up an if_info structure that holds the original costs. At that point the costs of the then/else blocks have not been added so we only care about the "if" cost.
The code originally used BRANCH_COST for that but was then changed to COST_N_INSNS (2) - a compare and a jump. This patch computes the jump costs via insn_cost (if_info.jump, ...) which is supposed to incorporate the branch costs and, in case of a CC comparison, pattern_cost (if_info.cond, ...) which is supposed to account for the CC creation. For compare_and_jump patterns insn_cost should have already computed the right cost. Does this "split" make sense, generally? Bootstrapped and regtested on x86, aarch64 and power10. Regtested on riscv. Regards Robin gcc/ChangeLog: * ifcvt.cc (noce_process_if_block): Subtract condition pattern cost if applicable. (noce_find_if_block): Use insn_cost and pattern_cost for original cost. --- gcc/ifcvt.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 58ed42673e5..305b9faed38 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -3940,7 +3940,9 @@ noce_process_if_block (struct noce_if_info *if_info) ??? Actually, instead of the branch instruction costs we might want to use COSTS_N_INSNS (BRANCH_COST ()) as in other places. */ - unsigned potential_cost = if_info->original_cost - COSTS_N_INSNS (1); + unsigned potential_cost = if_info->original_cost; + if (cc_in_cond (if_info->cond)) + potential_cost -= pattern_cost (if_info->cond, if_info->speed_p); unsigned old_cost = if_info->original_cost; if (!else_bb && HAVE_conditional_move @@ -4703,11 +4705,13 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, = targetm.max_noce_ifcvt_seq_cost (then_edge); /* We'll add in the cost of THEN_BB and ELSE_BB later, when we check that they are valid to transform. We can't easily get back to the insn - for COND (and it may not exist if we had to canonicalize to get COND), - and jump_insns are always given a cost of 1 by seq_cost, so treat - both instructions as having cost COSTS_N_INSNS (1). */ - if_info.original_cost = COSTS_N_INSNS (2); - + for COND (and it may not exist if we had to canonicalize to get COND). + Here we assume one CC compare insn (if the target uses CC) and one + jump insn that is costed via insn_cost. It is assumed that the + costs of a jump insn are dependent on the branch costs. */ + if (cc_in_cond (if_info.cond)) + if_info.original_cost = pattern_cost (if_info.cond, if_info.speed_p); + if_info.original_cost += insn_cost (if_info.jump, if_info.speed_p); /* Do the real work. */ -- 2.45.1