https://gcc.gnu.org/g:92f2a86794ad88d773b102c753e13be1b6f05ff9
commit r16-6436-g92f2a86794ad88d773b102c753e13be1b6f05ff9 Author: Andrew Pinski <[email protected]> Date: Fri Dec 26 12:07:26 2025 -0800 ifcvt: Handle lowpart subregs if noce_emit_cmove fails in noce_try_cond_zero_arith [PR123308] This fixes up a missed optimization regression for riscv in ifcvt after r16-6350-g9e61a171244110. The problem is noce_emit_cmove will fail for QImode. This can show up when dealing with shifts and the right hand side is `(subreg:QI (reg:DI) lowpart)`. Trying first for the subreg mode fails so the need to try to unwrap the subreg and try for the full mode. This fixes test_ShiftLeft_eqz in gcc.target/riscv/zicond_ifcvt_opt.c. Bootstrapped and tested on x86_64-linux-gnu. PR rtl-optimization/123308 gcc/ChangeLog: * ifcvt.cc (noce_try_cond_zero_arith): If noce_emit_cmove fails for a lowpart subreg case, then try the full reg cmove and take the lowpart subreg afterwards. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/ifcvt.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 562775165a2f..2b8f68a9b415 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -3207,6 +3207,28 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) XEXP (cond, 0), XEXP (cond, 1), op != AND ? XEXP (a, 1) : const0_rtx, op != AND ? const0_rtx : XEXP (a, 0)); + if (!target) + { + end_sequence (); + rtx tmp = XEXP (a, op != AND); + /* If the cmove fails and this was a lowpart subreg, + then try the reg part and then putting back the lowpart + afterwards. */ + if (GET_CODE (tmp) != SUBREG || !subreg_lowpart_p (tmp)) + return false; + start_sequence (); + + tmp = SUBREG_REG (tmp); + target = gen_reg_rtx (GET_MODE (tmp)); + target = noce_emit_cmove (if_info, target, code, + XEXP (cond, 0), XEXP (cond, 1), + op != AND ? tmp : const0_rtx, + op != AND ? const0_rtx : tmp); + if (!target) + goto end_seq_n_fail; + target = rtl_hooks.gen_lowpart_no_emit (GET_MODE (XEXP (a, op != AND)), target); + gcc_assert (target); + } if (!target) goto end_seq_n_fail;
