From 40c4ef22a7b4b70c64d5ce09d9fc5fba60b49420 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 30 Aug 2017 11:18:02 +0000 Subject: [PATCH] [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 Alan Hayward David Sherwood gcc/ * simplify-rtx.c (simplify_const_unary_operation): Use is_a 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 Co-Authored-By: David Sherwood From-SVN: r251507 --- gcc/ChangeLog | 13 +++++++++++++ gcc/simplify-rtx.c | 35 +++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4805908254..7d3d304117a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2017-08-30 Richard Sandiford + Alan Hayward + David Sherwood + + * simplify-rtx.c (simplify_const_unary_operation): Use + is_a 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 Alan Hayward David Sherwood diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 3c81cb8733b..e729bd8ff89 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1694,7 +1694,7 @@ rtx simplify_const_unary_operation (enum rtx_code code, machine_mode mode, rtx op, machine_mode op_mode) { - unsigned int width = GET_MODE_PRECISION (mode); + scalar_int_mode result_mode; if (code == VEC_DUPLICATE) { @@ -1809,10 +1809,13 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode 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 (mode, &result_mode)) { + unsigned int width = GET_MODE_PRECISION (result_mode); wide_int result; - machine_mode imode = op_mode == VOIDmode ? mode : op_mode; + scalar_int_mode imode = (op_mode == VOIDmode + ? result_mode + : as_a (op_mode)); rtx_mode_t op0 = rtx_mode_t (op, imode); int int_value; @@ -1841,35 +1844,35 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, break; case FFS: - result = wi::shwi (wi::ffs (op0), mode); + result = wi::shwi (wi::ffs (op0), result_mode); break; case CLZ: if (wi::ne_p (op0, 0)) int_value = wi::clz (op0); - else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, int_value)) - int_value = GET_MODE_PRECISION (mode); - result = wi::shwi (int_value, mode); + else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value)) + int_value = GET_MODE_PRECISION (imode); + result = wi::shwi (int_value, result_mode); break; case CLRSB: - result = wi::shwi (wi::clrsb (op0), mode); + result = wi::shwi (wi::clrsb (op0), result_mode); break; case CTZ: if (wi::ne_p (op0, 0)) int_value = wi::ctz (op0); - else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, int_value)) - int_value = GET_MODE_PRECISION (mode); - result = wi::shwi (int_value, mode); + else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value)) + int_value = GET_MODE_PRECISION (imode); + result = wi::shwi (int_value, result_mode); break; case POPCOUNT: - result = wi::shwi (wi::popcount (op0), mode); + result = wi::shwi (wi::popcount (op0), result_mode); break; case PARITY: - result = wi::shwi (wi::parity (op0), mode); + result = wi::shwi (wi::parity (op0), result_mode); break; case BSWAP: @@ -1890,7 +1893,7 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, 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) @@ -1950,9 +1953,9 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode, } else if (CONST_DOUBLE_AS_FLOAT_P (op) && SCALAR_FLOAT_MODE_P (GET_MODE (op)) - && GET_MODE_CLASS (mode) == MODE_INT - && width > 0) + && is_int_mode (mode, &result_mode)) { + unsigned int width = GET_MODE_PRECISION (result_mode); /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX operators are intentionally left unspecified (to ease implementation by target backends), for consistency, this routine implements the -- 2.30.2