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
>

Reply via email to