op=[PLUS, MINUS, IOR, XOR, ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT, AND]
Co-authored-by: Xiao Zeng<zengx...@eswincomputing.com> gcc/ChangeLog: * ifcvt.cc (noce_cond_zero_shift_op_supported): check if OP is shift like operation (noce_cond_zero_binary_op_supported): restructure & call noce_cond_zero_shift_op_supported (noce_bbs_ok_for_cond_zero_arith): add support for const_int (noce_try_cond_zero_arith): add support for x=c ? (y op const_int) gcc/testsuite/ChangeLog: * gcc.target/riscv/zicond_ifcvt_opt.c: add TCs for x=c ? (y op const_int) : y --- gcc/ifcvt.cc | 45 +- .../gcc.target/riscv/zicond_ifcvt_opt.c | 774 +++++++++++++++++- 2 files changed, 811 insertions(+), 8 deletions(-) diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 29f33f956eb..b84be53ec5c 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -2910,6 +2910,20 @@ noce_try_sign_mask (struct noce_if_info *if_info) return true; } +/* Check if OP is shift-like operation supported by conditional zero + based if conversion, returning TRUE if satisfied otherwise FALSE. + + OP is the operation to check. */ +static bool +noce_cond_zero_shift_op_supported (enum rtx_code op) +{ + if (op == ASHIFT || op == ASHIFTRT || op == LSHIFTRT || op == ROTATE + || op == ROTATERT) + return true; + + return false; +} + /* Check if OP is supported by conditional zero based if conversion, returning TRUE if satisfied otherwise FALSE. @@ -2921,8 +2935,7 @@ noce_cond_zero_binary_op_supported (rtx op) enum rtx_code opcode = GET_CODE (op); if (opcode == PLUS || opcode == MINUS || opcode == IOR || opcode == XOR - || opcode == ASHIFT || opcode == ASHIFTRT || opcode == LSHIFTRT - || opcode == ROTATE || opcode == ROTATERT || opcode == AND) + || opcode == AND || noce_cond_zero_shift_op_supported (opcode)) return true; return false; @@ -3009,7 +3022,7 @@ noce_bbs_ok_for_cond_zero_arith (struct noce_if_info *if_info, rtx *common_ptr, if (czero_code == UNKNOWN) return false; - if (REG_P (bin_op1)) + if (CONST_INT_P (bin_op1) || REG_P (bin_op1)) *to_replace = &XEXP (bin_exp, 1); else if (SUBREG_P (bin_op1)) *to_replace = &SUBREG_REG (XEXP (bin_exp, 1)); @@ -3038,6 +3051,7 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) enum rtx_code czero_code = UNKNOWN; rtx bin_exp = NULL_RTX; enum rtx_code bin_code = UNKNOWN; + rtx bin_op0 = NULL_RTX; rtx non_zero_op = NULL_RTX; rtx *to_replace = NULL; @@ -3048,6 +3062,7 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) start_sequence (); bin_code = GET_CODE (bin_exp); + bin_op0 = XEXP (bin_exp, 0); if (bin_code == AND) { @@ -3074,9 +3089,16 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) } else { - non_zero_op = *to_replace; + if (CONST_INT_P (*to_replace)) + { + non_zero_op = gen_reg_rtx (mode); + noce_emit_move_insn (non_zero_op, *to_replace); + } + else + non_zero_op = *to_replace; + /* If x is used in both input and out like x = c ? x + z : x, - use a new reg to avoid modifying x */ + use a new reg to avoid modifying x */ if (common && rtx_equal_p (common, if_info->x)) target = gen_reg_rtx (mode); else @@ -3089,7 +3111,18 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) return false; } - *to_replace = target; + if (CONST_INT_P (*to_replace)) + { + if (noce_cond_zero_shift_op_supported (bin_code)) + *to_replace = gen_rtx_SUBREG (E_QImode, target, 0); + else if (SUBREG_P (bin_op0)) + *to_replace = gen_rtx_SUBREG (GET_MODE (bin_op0), target, 0); + else + *to_replace = target; + } + else + *to_replace = target; + noce_emit_move_insn (if_info->x, a); } diff --git a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c index d5310690539..85743e1734c 100644 --- a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c +++ b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c @@ -615,6 +615,616 @@ test_RotateR_eqz (unsigned long x, unsigned long y, unsigned long z, return x; } +long +test_ADD_ceqz_imm (long x, long y, long c) +{ + if (c) + x = y + 11; + else + x = y; + return x; +} + +long +test_ADD_ceqz_x_imm (long x, long c) +{ + if (c) + x = x + 11; + + return x; +} + +long +test_ADD_nez_imm (long x, long y, long c) +{ + if (c) + x = y; + else + x = y + 11; + return x; +} + +long +test_ADD_nez_x_imm (long x, long c) +{ + if (c) + { + } + else + x = x + 11; + return x; +} + +long +test_ADD_nez_2_imm (long x, long y, long c) +{ + if (!c) + x = y + 11; + else + x = y; + return x; +} + +long +test_ADD_nez_x_2_imm (long x, long c) +{ + if (!c) + x = x + 11; + + return x; +} + +long +test_ADD_eqz_2_imm (long x, long y, long c) +{ + if (!c) + x = y; + else + x = y + 11; + return x; +} + +long +test_ADD_eqz_x_2_imm (long x, long c) +{ + if (!c) + { + } + else + x = x + 11; + return x; +} + +long +test_SUB_ceqz_imm (long x, long y, long c) +{ + if (c) + x = y - 11; + else + x = y; + return x; +} + +long +test_SUB_ceqz_x_imm (long x, long c) +{ + if (c) + x = x - 11; + + return x; +} + +long +test_SUB_nez_imm (long x, long y, long c) +{ + if (c) + x = y; + else + x = y - 11; + return x; +} + +long +test_SUB_nez_x_imm (long x, long c) +{ + if (c) + { + } + else + x = x - 11; + return x; +} + +long +test_SUB_nez_2_imm (long x, long y, long c) +{ + if (!c) + x = y - 11; + else + x = y; + return x; +} + +long +test_SUB_nez_x_2_imm (long x, long c) +{ + if (!c) + x = x - 11; + + return x; +} + +long +test_SUB_eqz_2_imm (long x, long y, long c) +{ + if (!c) + x = y; + else + x = y - 11; + return x; +} + +long +test_SUB_eqz_x_2_imm (long x, long c) +{ + if (!c) + { + } + else + x = x - 11; + return x; +} + +long +test_IOR_ceqz_imm (long x, long y, long c) +{ + if (c) + x = y | 11; + else + x = y; + return x; +} + +long +test_IOR_ceqz_x_imm (long x, long c) +{ + if (c) + x = x | 11; + + return x; +} + +long +test_IOR_nez_imm (long x, long y, long c) +{ + if (c) + x = y; + else + x = y | 11; + return x; +} + +long +test_IOR_nez_x_imm (long x, long c) +{ + if (c) + { + } + else + x = x | 11; + return x; +} + +long +test_IOR_nez_2_imm (long x, long y, long c) +{ + if (!c) + x = y | 11; + else + x = y; + return x; +} + +long +test_IOR_nez_x_2_imm (long x, long c) +{ + if (!c) + x = x | 11; + + return x; +} + +long +test_IOR_eqz_2_imm (long x, long y, long c) +{ + if (!c) + x = y; + else + x = y | 11; + return x; +} + +long +test_IOR_eqz_x_2_imm (long x, long c) +{ + if (!c) + { + } + else + x = x | 11; + return x; +} + +long +test_XOR_ceqz_imm (long x, long y, long c) +{ + if (c) + x = y ^ 11; + else + x = y; + return x; +} + +long +test_XOR_ceqz_x_imm (long x, long c) +{ + if (c) + x = x ^ 11; + + return x; +} + +long +test_XOR_nez_imm (long x, long y, long c) +{ + if (c) + x = y; + else + x = y ^ 11; + return x; +} + +long +test_XOR_nez_x_imm (long x, long c) +{ + if (c) + { + } + else + x = x ^ 11; + return x; +} + +long +test_XOR_nez_2_imm (long x, long y, long c) +{ + if (!c) + x = y ^ 11; + else + x = y; + return x; +} + +long +test_XOR_nez_x_2_imm (long x, long c) +{ + if (!c) + x = x ^ 11; + + return x; +} + +long +test_XOR_eqz_2_imm (long x, long y, long c) +{ + if (!c) + x = y; + else + x = y ^ 11; + return x; +} + +long +test_XOR_eqz_x_2_imm (long x, long c) +{ + if (!c) + { + } + else + x = x ^ 11; + return x; +} + +long +test_ADD_ceqz_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = 11 + y; + else + x = y; + return x; +} + +long +test_ADD_ceqz_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + x = 11 + x; + + return x; +} + +long +test_ADD_nez_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = y; + else + x = 11 + y; + return x; +} + +long +test_ADD_nez_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + { + } + else + x = 11 + x; + return x; +} + +long +test_ADD_nez_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = 11 + y; + else + x = y; + return x; +} + +long +test_ADD_nez_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + x = 11 + x; + + return x; +} + +long +test_ADD_eqz_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = y; + else + x = 11 + y; + return x; +} + +long +test_ADD_eqz_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + { + } + else + x = 11 + x; + return x; +} + +long +test_IOR_ceqz_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = 11 | y; + else + x = y; + return x; +} + +long +test_IOR_ceqz_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + x = 11 | x; + + return x; +} + +long +test_IOR_nez_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = y; + else + x = 11 | y; + return x; +} + +long +test_IOR_nez_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + { + } + else + x = 11 | x; + return x; +} + +long +test_IOR_nez_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = 11 | y; + else + x = y; + return x; +} + +long +test_IOR_nez_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + x = 11 | x; + + return x; +} + +long +test_IOR_eqz_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = y; + else + x = 11 | y; + return x; +} + +long +test_IOR_eqz_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + { + } + else + x = 11 | x; + return x; +} + +long +test_XOR_ceqz_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = 11 ^ y; + else + x = y; + return x; +} + +long +test_XOR_ceqz_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + x = 11 ^ x; + + return x; +} + +long +test_XOR_nez_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = y; + else + x = 11 ^ y; + return x; +} + +long +test_XOR_nez_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + { + } + else + x = 11 ^ x; + return x; +} + +long +test_XOR_nez_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = 11 ^ y; + else + x = y; + return x; +} + +long +test_XOR_nez_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + x = 11 ^ x; + + return x; +} + +long +test_XOR_eqz_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = y; + else + x = 11 ^ y; + return x; +} + +long +test_XOR_eqz_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + { + } + else + x = 11 ^ x; + return x; +} + +long +test_ShiftLeft_eqz_imm (long x, long y, long c) +{ + if (c) + x = y << 11; + else + x = y; + return x; +} + +long +test_ShiftR_eqz_imm (long x, long y, long c) +{ + if (c) + x = y >> 11; + else + x = y; + return x; +} + +unsigned long +test_ShiftR_logical_eqz_imm (unsigned long x, unsigned long y, unsigned long z, + unsigned long c) +{ + if (c) + x = y >> 11; + else + x = y; + return x; +} + +unsigned long +test_RotateL_eqz_imm (unsigned long x, unsigned long y, unsigned long c) +{ + if (c) + x = (y << 11) | (y >> (64 - 11)); + else + x = y; + return x; +} + +unsigned long +test_RotateR_eqz_imm (unsigned long x, unsigned long y, unsigned long c) +{ + if (c) + x = (y >> 11) | (y << (64 - 11)); + else + x = y; + return x; +} long test_AND_ceqz (long x, long y, long z, long c) { @@ -774,5 +1384,165 @@ test_AND_eqz_x_2_reverse_bin_oprands (long x, long z, long c) x = z & x; return x; } -/* { dg-final { scan-assembler-times {czero\.eqz} 41 } } */ -/* { dg-final { scan-assembler-times {czero\.nez} 36 } } */ + +long +test_AND_ceqz_imm (long x, long y, long c) +{ + if (c) + x = y & 11; + else + x = y; + return x; +} + +long +test_AND_ceqz_x_imm (long x, long c) +{ + if (c) + x = x & 11; + + return x; +} + +long +test_AND_nez_imm (long x, long y, long c) +{ + if (c) + x = y; + else + x = y & 11; + return x; +} + +long +test_AND_nez_x_imm (long x, long c) +{ + if (c) + { + } + else + x = x & 11; + return x; +} + +long +test_AND_nez_2_imm (long x, long y, long c) +{ + if (!c) + x = y & 11; + else + x = y; + return x; +} + +long +test_AND_nez_x_2_imm (long x, long c) +{ + if (!c) + x = x & 11; + + return x; +} + +long +test_AND_eqz_2_imm (long x, long y, long c) +{ + if (!c) + x = y; + else + x = y & 11; + return x; +} + +long +test_AND_eqz_x_2_imm (long x, long c) +{ + if (!c) + { + } + else + x = x & 11; + return x; +} + +long +test_AND_ceqz_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = 11 & y; + else + x = y; + return x; +} + +long +test_AND_ceqz_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + x = 11 & x; + + return x; +} + +long +test_AND_nez_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (c) + x = y; + else + x = 11 & y; + return x; +} + +long +test_AND_nez_x_imm_reverse_bin_oprands (long x, long c) +{ + if (c) + { + } + else + x = 11 & x; + return x; +} + +long +test_AND_nez_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = 11 & y; + else + x = y; + return x; +} + +long +test_AND_nez_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + x = 11 & x; + + return x; +} + +long +test_AND_eqz_2_imm_reverse_bin_oprands (long x, long y, long c) +{ + if (!c) + x = y; + else + x = 11 & y; + return x; +} + +long +test_AND_eqz_x_2_imm_reverse_bin_oprands (long x, long c) +{ + if (!c) + { + } + else + x = 11 & x; + return x; +} +/* { dg-final { scan-assembler-times {czero\.eqz} 82 } } */ +/* { dg-final { scan-assembler-times {czero\.nez} 72 } } */ -- 2.17.1