Hi, When a cbranch immediately follows an SH2A nott insn, the branch condition can be inverted and the nott insn can be deleted. This is what the attached patch makes the sh_treg_combine pass do. Tested with make -k check RUNTESTFLAGS="--target_board=sh-sim \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}" Committed as r218847.
Cheers, Oleg gcc/ChangeLog: PR target/51244 * config/sh/sh_treg_combine.cc (sh_treg_combine::try_optimize_cbranch): Combine ccreg inversion and cbranch into inverted cbranch.
Index: gcc/config/sh/sh_treg_combine.cc =================================================================== --- gcc/config/sh/sh_treg_combine.cc (revision 218722) +++ gcc/config/sh/sh_treg_combine.cc (working copy) @@ -1339,9 +1339,17 @@ // for now we limit the search to the current basic block. trace.setcc = find_set_of_reg_bb (m_ccreg, prev_nonnote_insn_bb (insn)); - if (!is_cmp_eq_zero (trace.setcc.set_src ())) + if (trace.setcc.set_src () == NULL_RTX) log_return_void ("could not find set of ccreg in current BB\n"); + if (!is_cmp_eq_zero (trace.setcc.set_src ()) + && !is_inverted_ccreg (trace.setcc.set_src ())) + { + log_msg ("unsupported set of ccreg in current BB: "); + log_rtx (trace.setcc.set_src ()); + log_return_void ("\n"); + } + rtx trace_reg = XEXP (trace.setcc.set_src (), 0); log_msg ("set of ccreg:\n"); @@ -1358,6 +1366,19 @@ log_return_void ("\nbecause it's volatile\n"); } + // If the ccreg is inverted before cbranch try inverting the branch + // condition. + if (is_inverted_ccreg (trace.setcc.set_src ())) + { + if (!trace.can_invert_condition ()) + log_return_void ("branch condition can't be inverted - aborting\n"); + + if (try_invert_branch_condition (trace)) + delete_insn (trace.setcc.insn); + + return; + } + // Now that we have an insn which tests some reg and sets the condition // reg before the conditional branch, try to figure out how that tested // reg was formed, i.e. find all the insns that set the tested reg in