On Fri, Dec 26, 2025 at 7:18 PM Andrew Pinski <[email protected]> wrote: > > 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.
I just found a bug in this. cond is not the correct thing to use for noce_emit_cmove. It should have been if_info->cond. Thanks, Andrew > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/ifcvt.cc | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc > index 75d959f652c..9d62681be24 100644 > --- a/gcc/ifcvt.cc > +++ b/gcc/ifcvt.cc > @@ -3202,6 +3202,28 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) > XEXP (if_info->cond, 0), XEXP (if_info->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, GET_CODE (cond), > + 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; > > -- > 2.43.0 >
