From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100250 invoked by alias); 9 Dec 2016 13:33:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 100229 invoked by uid 89); 9 Dec 2016 13:32:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=ease, roundabout, SGN X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Dec 2016 13:32:49 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4BD69707; Fri, 9 Dec 2016 05:32:48 -0800 (PST) Received: from localhost (e105548-lin.manchester.arm.com [10.45.32.67]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EB62C3F477 for ; Fri, 9 Dec 2016 05:32:47 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [55/67] Use scalar_int_mode in simplify_const_unary_operation References: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> Date: Fri, 09 Dec 2016 13:33:00 -0000 In-Reply-To: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Fri, 09 Dec 2016 12:48:01 +0000") Message-ID: <87vautfcsh.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2016-12/txt/msg00831.txt.bz2 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. These changes require the rtl wi:: routines to take machine_mode_enums, to avoid an ambiguity when using scalar_int_modes instead of machine_modes. The problem is that machine_mode_enum (like all enums) can be implicitly converted to an integer, and so the mode classes can indirectly be converted to an integer too. (And this is useful when modes are used as array indices, for example.) So when scalar_int_mode was used, the non-rtl wi:: candidates that take integer precisions instead of modes had the same rank as the machine_mode ones. gcc/ 2016-11-24 Richard Sandiford Alan Hayward David Sherwood * rtl.h (wi::shwi): Take a machine_mode_enum rather than a machine_mode. (wi::min_value): Likewise. (wi::max_value): Likewise, * 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. diff --git a/gcc/rtl.h b/gcc/rtl.h index e65020a..a5ca103 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2139,13 +2139,13 @@ wi::int_traits ::decompose (HOST_WIDE_INT *, namespace wi { - hwi_with_prec shwi (HOST_WIDE_INT, machine_mode mode); - wide_int min_value (machine_mode, signop); - wide_int max_value (machine_mode, signop); + hwi_with_prec shwi (HOST_WIDE_INT, machine_mode_enum); + wide_int min_value (machine_mode_enum, signop); + wide_int max_value (machine_mode_enum, signop); } inline wi::hwi_with_prec -wi::shwi (HOST_WIDE_INT val, machine_mode mode) +wi::shwi (HOST_WIDE_INT val, machine_mode_enum mode) { return shwi (val, GET_MODE_PRECISION (mode)); } @@ -2153,7 +2153,7 @@ wi::shwi (HOST_WIDE_INT val, machine_mode mode) /* Produce the smallest number that is represented in MODE. The precision is taken from MODE and the sign from SGN. */ inline wide_int -wi::min_value (machine_mode mode, signop sgn) +wi::min_value (machine_mode_enum mode, signop sgn) { return min_value (GET_MODE_PRECISION (mode), sgn); } @@ -2161,7 +2161,7 @@ wi::min_value (machine_mode mode, signop sgn) /* Produce the largest number that is represented in MODE. The precision is taken from MODE and the sign from SGN. */ inline wide_int -wi::max_value (machine_mode mode, signop sgn) +wi::max_value (machine_mode_enum mode, signop sgn) { return max_value (GET_MODE_PRECISION (mode), sgn); } diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index f4997bf..465e02a 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1683,7 +1683,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) { @@ -1798,10 +1798,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; @@ -1830,35 +1833,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: @@ -1879,7 +1882,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) @@ -1936,9 +1939,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