op=[PLUS, MINUS, IOR, XOR, ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT] 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 bin_exp_ptr interface (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 | 53 +- .../gcc.target/riscv/zicond_ifcvt_opt.c | 675 +++++++++++++++++- 2 files changed, 716 insertions(+), 12 deletions(-) diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 8f6a0e7f5fe..4cc6a125ff0 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -2920,6 +2920,16 @@ noce_try_sign_mask (struct noce_if_info *if_info) 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; +} + static bool noce_cond_zero_binary_op_supported (rtx op) { @@ -2930,8 +2940,7 @@ noce_cond_zero_binary_op_supported (rtx op) opcode = GET_CODE (XEXP (op, 0)); if (opcode == PLUS || opcode == MINUS || opcode == IOR || opcode == XOR - || opcode == ASHIFT || opcode == ASHIFTRT || opcode == LSHIFTRT - || opcode == ROTATE || opcode == ROTATERT) + || noce_cond_zero_shift_op_supported (opcode)) return true; return false; @@ -2963,6 +2972,7 @@ get_base_reg (rtx exp) static bool noce_bbs_ok_for_cond_zero_arith (struct noce_if_info *if_info, rtx *common_ptr, + rtx *bin_exp_ptr, enum rtx_code *czero_code_ptr, rtx *a_ptr, rtx **to_replace) { @@ -3029,6 +3039,7 @@ noce_bbs_ok_for_cond_zero_arith (struct noce_if_info *if_info, rtx *common_ptr, return false; *common_ptr = common; + *bin_exp_ptr = bin_exp; *czero_code_ptr = czero_code; *a_ptr = a; @@ -3047,20 +3058,28 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info) machine_mode mode = GET_MODE (if_info->x); rtx common = NULL_RTX; 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; - if (!noce_bbs_ok_for_cond_zero_arith (if_info, &common, &czero_code, &a, - &to_replace)) + if (!noce_bbs_ok_for_cond_zero_arith (if_info, &common, &bin_exp, &czero_code, + &a, &to_replace)) return false; - /* Disallow CONST_INT currently for simplicity*/ - if (to_replace == NULL || !REG_P (*to_replace)) - return false; + start_sequence (); - non_zero_op = *to_replace; + bin_code = GET_CODE (bin_exp); + bin_op0 = XEXP (bin_exp, 0); - start_sequence (); + 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 */ @@ -3076,7 +3095,21 @@ 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); + if (GET_CODE (a) == ZERO_EXTEND && bin_code == LSHIFTRT) + PUT_CODE (a, SIGN_EXTEND); + } + 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; emit_insn (gen_rtx_SET (if_info->x, a)); seq = end_ifcvt_sequence (if_info); diff --git a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c index 9357f26d978..c6b0518968b 100644 --- a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c +++ b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c @@ -678,5 +678,676 @@ test_RotateR_eqz_int (unsigned int x, unsigned int y, unsigned int z, return x; } -/* { dg-final { scan-assembler-times {czero\.eqz} 39 } } */ -/* { dg-final { scan-assembler-times {czero\.nez} 28 } } */ +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; +} + +int +test_ADD_ceqz_imm_int (int x, int y, int c) +{ + if (c) + x = y + 11; + else + x = y; + return x; +} + +int +test_ShiftLeft_eqz_imm_int (int x, int y, int c) +{ + if (c) + x = y << 11; + else + x = y; + return x; +} + +int +test_ShiftR_eqz_imm_int (int x, int y, int c) +{ + if (c) + x = y >> 11; + else + x = y; + return x; +} + +unsigned int +test_ShiftR_logical_eqz_imm_int (unsigned int x, unsigned int y, unsigned int c) +{ + if (c) + x = y >> 11; + else + x = y; + return x; +} + +unsigned int +test_RotateL_eqz_imm_int (unsigned int x, unsigned int y, unsigned int c) +{ + if (c) + x = (y << 11) | (y >> (32 - 11)); + else + x = y; + return x; +} + +unsigned int +test_RotateR_eqz_imm_int (unsigned int x, unsigned int y, unsigned int c) +{ + if (c) + x = (y >> 11) | (y << (32 - 11)); + else + x = y; + return x; +} + +/* { dg-final { scan-assembler-times {czero\.eqz} 78 } } */ +/* { dg-final { scan-assembler-times {czero\.nez} 56 } } */ -- 2.17.1