From: Vineet Gupta Date: Mon, 22 Dec 2025 16:54:06 +0000 (-0800) Subject: ifcvt: cond zero arith: elide short forward branch for signed GE 0 comparison [PR122769] X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2a84a753afcf376a5fc0339c5ce228c130000cd7;p=thirdparty%2Fgcc.git ifcvt: cond zero arith: elide short forward branch for signed GE 0 comparison [PR122769] Before After ---------------------+---------------------- bge a0,zero,.L2 | slti a0,a0,0 | czero.eqz a0,a0,a0 xor a1,a1,a3 | xor a0,a0,a0 .L2 | mv a0,a1 | ret | ret This is what all the prev NFC patches have been preparing to get to. Currently the cond arith code only handles EQ/NE zero conditions missing ifcvt optimization for cases such as GE zero, as show in example above. This is due to the limitation of noce_emit_czero () so switch to noce_emit_cmove () which can handle conditions other than EQ/NE and if needed generate additional supporting insns such as SLT. This also allows us to remove the constraint at the entry to limit to EQ/NE conditions, improving ifcvt outcomes in general. PR target/122769 gcc/ChangeLog: * ifcvt.cc (noce_try_cond_zero_arith): Use noce_emit_cmove. Delete noce_emit_czero () no longer used. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr122769.c: New test. Co-authored-by: Philipp Tomsich Signed-off-by: Vineet Gupta --- diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index ef59a93e987..280f398cee6 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -2037,35 +2037,6 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, return NULL_RTX; } -/* Emit a conditional zero, returning TARGET or NULL_RTX upon failure. - IF_INFO describes the if-conversion scenario under consideration. - CZERO_CODE selects the condition (EQ/NE). - NON_ZERO_OP is the nonzero operand of the conditional move - TARGET is the desired output register. */ - -static rtx -noce_emit_czero (struct noce_if_info *if_info, enum rtx_code czero_code, - rtx non_zero_op, rtx target) -{ - machine_mode mode = GET_MODE (target); - rtx cond_op0 = XEXP (if_info->cond, 0); - rtx czero_cond - = gen_rtx_fmt_ee (czero_code, GET_MODE (cond_op0), cond_op0, const0_rtx); - rtx if_then_else - = gen_rtx_IF_THEN_ELSE (mode, czero_cond, const0_rtx, non_zero_op); - rtx set = gen_rtx_SET (target, if_then_else); - - rtx_insn *insn = make_insn_raw (set); - - if (recog_memoized (insn) >= 0) - { - add_insn (insn); - return target; - } - - return NULL_RTX; -} - /* Try only simple constants and registers here. More complex cases are handled in noce_try_cmove_arith after noce_try_store_flag_arith has had a go at it. */ @@ -3177,10 +3148,6 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) if (!noce_simple_bbs (if_info)) return false; - /* COND must be EQ or NE comparision of a reg and 0. */ - if (GET_CODE (cond) != NE && GET_CODE (cond) != EQ) - return false; - if (!REG_P (XEXP (cond, 0)) || !rtx_equal_p (XEXP (cond, 1), const0_rtx)) return false; @@ -3222,9 +3189,10 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) target = gen_reg_rtx (mode); /* AND requires !cond, instead we swap ops around. */ - target = noce_emit_czero (if_info, GET_CODE (if_info->cond), - op != AND ? a_op1 : a_op0, target); - + target = noce_emit_cmove (if_info, target, GET_CODE (if_info->cond), + XEXP (if_info->cond, 0), XEXP (if_info->cond, 1), + op != AND ? a_op1 : const0_rtx, + op != AND ? const0_rtx : a_op0); if (!target) goto end_seq_n_fail; diff --git a/gcc/testsuite/gcc.target/riscv/pr122769.c b/gcc/testsuite/gcc.target/riscv/pr122769.c new file mode 100644 index 00000000000..0f7e19ca504 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr122769.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv64gc_zbs_zicond -mabi=lp64d" { target rv64} } */ + +/* Elide a short forward branch and generate a czero instead. */ + +#include + +uint64_t updateLSB63 (uint64_t val, uint64_t val2, int bits, int n) +{ + if (val & (1ULL << 63)) + val2 ^= n; + return val2; +} + +/* { dg-final { scan-assembler-times {\tczero} 1 } } */ +/* { dg-final { scan-assembler-not {\tbge} } } */ +