Commit 40c4ef22 by Richard Sandiford Committed by Richard Sandiford

[55/77] Use scalar_int_mode in simplify_const_unary_operation

The main scalar integer block in simplify_const_unary_operation
had the condition:

  if (CONST_SCALAR_INT_P (op) && width > 0)

where "width > 0" was a roundabout way of testing != VOIDmode.
This patch replaces it with a check for a scalar_int_mode instead.
It also uses the number of bits in the input rather than the output
mode to determine the result of a "count ... bits in zero" operation.
(At the momemnt these modes have to be the same, but it still seems
conceptually wrong to use the number of bits in the output mode.)

The handling of float->integer ops also checked "width > 0",
but this was redundant with the earlier check for MODE_INT.

2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* simplify-rtx.c (simplify_const_unary_operation): Use
	is_a <scalar_int_mode> instead of checking for a nonzero
	precision.  Forcibly convert op_mode to a scalar_int_mode
	in that case.  More clearly differentiate the operand and
	result modes and use the former when deciding what the value
	of a count-bits operation should be.  Use is_int_mode instead
	of checking for a MODE_INT.  Remove redundant check for whether
	this mode has a zero precision.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r251507
parent 3c84109e
...@@ -2,6 +2,19 @@ ...@@ -2,6 +2,19 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* simplify-rtx.c (simplify_const_unary_operation): Use
is_a <scalar_int_mode> instead of checking for a nonzero
precision. Forcibly convert op_mode to a scalar_int_mode
in that case. More clearly differentiate the operand and
result modes and use the former when deciding what the value
of a count-bits operation should be. Use is_int_mode instead
of checking for a MODE_INT. Remove redundant check for whether
this mode has a zero precision.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* optabs.c (widen_leading): Change the type of the mode argument * optabs.c (widen_leading): Change the type of the mode argument
to scalar_int_mode. Use opt_scalar_int_mode for the mode iterator. to scalar_int_mode. Use opt_scalar_int_mode for the mode iterator.
(widen_bswap): Likewise. (widen_bswap): Likewise.
......
...@@ -1694,7 +1694,7 @@ rtx ...@@ -1694,7 +1694,7 @@ rtx
simplify_const_unary_operation (enum rtx_code code, machine_mode mode, simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
rtx op, machine_mode op_mode) rtx op, machine_mode op_mode)
{ {
unsigned int width = GET_MODE_PRECISION (mode); scalar_int_mode result_mode;
if (code == VEC_DUPLICATE) if (code == VEC_DUPLICATE)
{ {
...@@ -1809,10 +1809,13 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, ...@@ -1809,10 +1809,13 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
return const_double_from_real_value (d, mode); return const_double_from_real_value (d, mode);
} }
if (CONST_SCALAR_INT_P (op) && width > 0) if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
{ {
unsigned int width = GET_MODE_PRECISION (result_mode);
wide_int result; wide_int result;
machine_mode imode = op_mode == VOIDmode ? mode : op_mode; scalar_int_mode imode = (op_mode == VOIDmode
? result_mode
: as_a <scalar_int_mode> (op_mode));
rtx_mode_t op0 = rtx_mode_t (op, imode); rtx_mode_t op0 = rtx_mode_t (op, imode);
int int_value; int int_value;
...@@ -1841,35 +1844,35 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, ...@@ -1841,35 +1844,35 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
break; break;
case FFS: case FFS:
result = wi::shwi (wi::ffs (op0), mode); result = wi::shwi (wi::ffs (op0), result_mode);
break; break;
case CLZ: case CLZ:
if (wi::ne_p (op0, 0)) if (wi::ne_p (op0, 0))
int_value = wi::clz (op0); int_value = wi::clz (op0);
else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, int_value)) else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
int_value = GET_MODE_PRECISION (mode); int_value = GET_MODE_PRECISION (imode);
result = wi::shwi (int_value, mode); result = wi::shwi (int_value, result_mode);
break; break;
case CLRSB: case CLRSB:
result = wi::shwi (wi::clrsb (op0), mode); result = wi::shwi (wi::clrsb (op0), result_mode);
break; break;
case CTZ: case CTZ:
if (wi::ne_p (op0, 0)) if (wi::ne_p (op0, 0))
int_value = wi::ctz (op0); int_value = wi::ctz (op0);
else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, int_value)) else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
int_value = GET_MODE_PRECISION (mode); int_value = GET_MODE_PRECISION (imode);
result = wi::shwi (int_value, mode); result = wi::shwi (int_value, result_mode);
break; break;
case POPCOUNT: case POPCOUNT:
result = wi::shwi (wi::popcount (op0), mode); result = wi::shwi (wi::popcount (op0), result_mode);
break; break;
case PARITY: case PARITY:
result = wi::shwi (wi::parity (op0), mode); result = wi::shwi (wi::parity (op0), result_mode);
break; break;
case BSWAP: case BSWAP:
...@@ -1890,7 +1893,7 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, ...@@ -1890,7 +1893,7 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
return 0; return 0;
} }
return immed_wide_int_const (result, mode); return immed_wide_int_const (result, result_mode);
} }
else if (CONST_DOUBLE_AS_FLOAT_P (op) else if (CONST_DOUBLE_AS_FLOAT_P (op)
...@@ -1950,9 +1953,9 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, ...@@ -1950,9 +1953,9 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
} }
else if (CONST_DOUBLE_AS_FLOAT_P (op) else if (CONST_DOUBLE_AS_FLOAT_P (op)
&& SCALAR_FLOAT_MODE_P (GET_MODE (op)) && SCALAR_FLOAT_MODE_P (GET_MODE (op))
&& GET_MODE_CLASS (mode) == MODE_INT && is_int_mode (mode, &result_mode))
&& width > 0)
{ {
unsigned int width = GET_MODE_PRECISION (result_mode);
/* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
operators are intentionally left unspecified (to ease implementation operators are intentionally left unspecified (to ease implementation
by target backends), for consistency, this routine implements the by target backends), for consistency, this routine implements the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment