[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] ifcvt: Handle lowpart subregs if noce_emit_cmove fails in noce_try_cond_zero_arith [PR123308]
Jeff Law
law@gcc.gnu.org
Fri Jan 30 07:15:22 GMT 2026
https://gcc.gnu.org/g:89ed8490301616eafdd2abe4ef759060cbc8bf59
commit 89ed8490301616eafdd2abe4ef759060cbc8bf59
Author: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
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 <andrew.pinski@oss.qualcomm.com>
(cherry picked from commit 92f2a86794ad88d773b102c753e13be1b6f05ff9)
Diff:
---
gcc/ifcvt.cc | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 1f6538beb791..e2f98fbd5fbc 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -3210,6 +3210,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;
More information about the Gcc-cvs
mailing list