From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 40584 invoked by alias); 9 Dec 2016 13:28:51 -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 40514 invoked by uid 89); 9 Dec 2016 13:28:45 -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= 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:28:35 +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 1DECA707; Fri, 9 Dec 2016 05:28:33 -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 ABB6D3F477 for ; Fri, 9 Dec 2016 05:28:32 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [50/67] Add helper routines for SUBREG_PROMOTED_VAR_P subregs References: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> Date: Fri, 09 Dec 2016 13:28: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: <87h96dgrk0.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/msg00826.txt.bz2 When subregs contain promoted values, as indicated by SUBREG_PROMOTED_VAR_P, both the unpromoted (outer) and promoted (inner) values are known to be scalar integers. This patch adds helper routines that get the modes as scalar_int_modes. gcc/ 2016-11-24 Richard Sandiford Alan Hayward David Sherwood * rtl.h (subreg_unpromoted_mode, subreg_promoted_mode): New functions. * expr.c (convert_move): Use them. (convert_modes): Likewise. (store_expr_with_bounds): Likewise. diff --git a/gcc/expr.c b/gcc/expr.c index 408a8bd..f682925 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -241,7 +241,7 @@ convert_move (rtx to, rtx from, int unsignedp) if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from) && is_a (to_mode, &to_int_mode) - && (GET_MODE_PRECISION (GET_MODE (SUBREG_REG (from))) + && (GET_MODE_PRECISION (subreg_promoted_mode (from)) >= GET_MODE_PRECISION (to_int_mode)) && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp)) from = gen_lowpart (to_int_mode, from), from_mode = to_int_mode; @@ -639,7 +639,8 @@ convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp) if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x) && is_a (mode, &int_mode) - && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (int_mode) + && (GET_MODE_PRECISION (subreg_promoted_mode (x)) + >= GET_MODE_PRECISION (int_mode)) && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp)) x = gen_lowpart (int_mode, SUBREG_REG (x)); @@ -5414,6 +5415,8 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p, expression. */ { rtx inner_target = 0; + scalar_int_mode outer_mode = subreg_unpromoted_mode (target); + scalar_int_mode inner_mode = subreg_promoted_mode (target); /* We can do the conversion inside EXP, which will often result in some optimizations. Do the conversion in two steps: first @@ -5423,7 +5426,7 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p, converting modes. */ if (INTEGRAL_TYPE_P (TREE_TYPE (exp)) && TREE_TYPE (TREE_TYPE (exp)) == 0 - && GET_MODE_PRECISION (GET_MODE (target)) + && GET_MODE_PRECISION (outer_mode) == TYPE_PRECISION (TREE_TYPE (exp))) { if (!SUBREG_CHECK_PROMOTED_SIGN (target, @@ -5443,8 +5446,7 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p, } exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode - (GET_MODE (SUBREG_REG (target)), - SUBREG_PROMOTED_SIGN (target)), + (inner_mode, SUBREG_PROMOTED_SIGN (target)), exp); inner_target = SUBREG_REG (target); @@ -5470,10 +5472,9 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p, sure that we properly convert it. */ if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode) { - temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)), + temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)), temp, SUBREG_PROMOTED_SIGN (target)); - temp = convert_modes (GET_MODE (SUBREG_REG (target)), - GET_MODE (target), temp, + temp = convert_modes (inner_mode, outer_mode, temp, SUBREG_PROMOTED_SIGN (target)); } diff --git a/gcc/rtl.h b/gcc/rtl.h index 35f61c8..e65020a 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2766,6 +2766,24 @@ unwrap_const_vec_duplicate (T x) return x; } +/* Return the unpromoted (outer) mode of SUBREG_PROMOTED_VAR_P subreg X. */ + +inline scalar_int_mode +subreg_unpromoted_mode (rtx x) +{ + gcc_checking_assert (SUBREG_PROMOTED_VAR_P (x)); + return as_a (GET_MODE (x)); +} + +/* Return the promoted (inner) mode of SUBREG_PROMOTED_VAR_P subreg X. */ + +inline scalar_int_mode +subreg_promoted_mode (rtx x) +{ + gcc_checking_assert (SUBREG_PROMOTED_VAR_P (x)); + return as_a (GET_MODE (SUBREG_REG (x))); +} + /* In emit-rtl.c */ extern rtvec gen_rtvec_v (int, rtx *); extern rtvec gen_rtvec_v (int, rtx_insn **);