@@ -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);
}
@@ -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 } } */