From patchwork Mon Aug 21 13:34:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 110526 Delivered-To: patch@linaro.org Received: by 10.182.109.195 with SMTP id hu3csp4074492obb; Mon, 21 Aug 2017 06:34:38 -0700 (PDT) X-Received: by 10.84.128.106 with SMTP id 97mr19159579pla.41.1503322478299; Mon, 21 Aug 2017 06:34:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503322478; cv=none; d=google.com; s=arc-20160816; b=R4Nk0U8j8tldDd65z2BfBJOW3MgPun+6HNX5IYjZCfilFqiBdtne2uW5ZMCMgwEkU+ 4FhQ6Z9U9YPHY4bXUEHLehDCNf7KuiaCB7FXo8GVEF4RO4uuwzhAk2bwNV+Q3ngJbPkx 6npMCvS/X0G5b3prLhe12Dd7f5aIVc/Y1Lv6M0ZD10MLmp9Q+ZFuIFpeVwQMbMbvwH/f Y9fz1ZCV85q4h78RaB3TFgpH7sTfUdB/j9eAufn3B1OiPNQwpF5hLSzN1pc+6cazE/ki LGtncVY1HILtwsNe7Mu+jWqrj437MVjE++P/zEVCxG4wbCIiP3tfmO06PBkEVD0v27hE SH3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:date:subject:mail-followup-to:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=OdPj17lK5O79HYPf+g2pQixmZjG7lVDdq6hxjfrQjC0=; b=rGoKbY/3laX9KqErt1Y8RmM0CVGrrt462yArSAVnt5zPR8N4NeDF72mtOUGHmX4F8p G+qNnht0Gbsv2ev3OIagrzLYJHRvRkuRcVypd/jtwDeQ3HNVFaiHL5VyME9TDEm12vQp hBHRlbficX67H6MNrZgeq5oCMrMBD7ICwhcT2MIBcNkRGJgw4hhH6XmLEIW6f7d+Ok7f 08IlOcEvtVmmDWTJUuJ+jfUMKixTcPGItNH63b96YlM1jv/2pa3MjK/ZNxqmoW6BCCTy f7qO44xd50ORXr//vak0W+DzHbQlBX+Zg4O//K6/wojLVLrmy2jO2UznvklCqjDfkwhC +0WA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=RvoV/ja2; spf=pass (google.com: domain of gcc-patches-return-460649-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-460649-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s66si2900982pfb.661.2017.08.21.06.34.38 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 Aug 2017 06:34:38 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-460649-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=RvoV/ja2; spf=pass (google.com: domain of gcc-patches-return-460649-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-460649-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=td2g1HqTBUh3Di7VDwLo6N0gkarzfyaRB/cRvOp5keKTdS51irzVB w9ZYAvnM6Y47Uy9eG9rdRfkqcC67nsVGSiYtjbMSXOHSDlqLa/LAVO5xuDTnTvsp lqb/tjwlECbvr4yz2yMQoQVWSGu80UEPZNJnFUrghmFBThu+VhgMNc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=teQg7jghAG+0iLgL6bWjIj0dhbk=; b=RvoV/ja2yV+Kd4j3BQNv JQNwVM2PYhwNT1kaCLc3sI23CzQAE8zBx30d/xRd2kepm/noYAZSCCU/B10PDGZB vr8Deu8lggPjj6JSaNCsESpvo1t/OK4XrkSFwqTsdun7gZvliNO3aumor3ybLoaI nsuEgq2M6jSAQVFrbzF+uYk= Received: (qmail 7473 invoked by alias); 21 Aug 2017 13:34:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 7434 invoked by uid 89); 21 Aug 2017 13:34:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wr0-f173.google.com Received: from mail-wr0-f173.google.com (HELO mail-wr0-f173.google.com) (209.85.128.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 21 Aug 2017 13:34:13 +0000 Received: by mail-wr0-f173.google.com with SMTP id f8so63182585wrf.3 for ; Mon, 21 Aug 2017 06:34:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=OdPj17lK5O79HYPf+g2pQixmZjG7lVDdq6hxjfrQjC0=; b=RZng0Wk2nac9umW9w4HsXR/b2je2KjtY9cir/n0Z8dc2aJJuVdDtBBhuauEghe1ATk ktdJJJ1CGkOOl2tE11dMAgymND35roy/GQhNDeRZh5I7rgY2i/LIjbcG+GoHzeTIvm88 xW2NqFPAmdHVA18KlCGlz34zIc6oKXvEeC6yTKvyT2ejB/D/+HlwDIuHAp6xD2LJ0zBu N5E35O0wr40BIeyllCUknAF+0qKxPk3F+oxo6sAKwvHgSOr+P0j1CTIuqc3SyND1UAFA jY34EvZZJuBjnGdzK5foWr8mlaPLV+7rT5XqpUKYSXWrCMlALW1zi64uoj+0HL1D8Xal DdpQ== X-Gm-Message-State: AHYfb5iqFovVyUGMr05hwgoISKdxEJGz7vGNgHjCzzMI2h1Hi2+FAm4E v9hjNdunSu9VK1Im0qNzoQ== X-Received: by 10.28.193.10 with SMTP id r10mr7145289wmf.157.1503322450269; Mon, 21 Aug 2017 06:34:10 -0700 (PDT) Received: from localhost (92.40.248.37.threembb.co.uk. [92.40.248.37]) by smtp.gmail.com with ESMTPSA id f80sm6629524wmh.16.2017.08.21.06.34.08 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Aug 2017 06:34:09 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Add a partial_subreg_p predicate Date: Mon, 21 Aug 2017 14:34:07 +0100 Message-ID: <87tw11caeo.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch adds a partial_subreg_p predicate to go alongside paradoxical_subreg_p. The first two changes to cse_insn preserve the current behaviour, but the condition seems strange. Shouldn't we be able to continue to cse if the inner modes of the two subregs have the same size? The patch also preserves the existing condition in simplify_operand_subreg, but perhaps it should be using a df_read_modify_subreg_p-style check instead. We don't need to reload the inner value first if the inner value is no bigger than a word, for example. The use in curr_insn_transform also seemed strange. Surely the modes of the SET_DEST and SET_SRC will be the same, given that this code isn't meant for constants? Like the paradoxical_subreg_p patch, this one replaces some tests that were based on GET_MODE_SIZE rather than GET_MODE_PRECISION. In each case the change should be a no-op or an improvement. Doing this in regcprop.c prevents some replacements of the 82-bit RFmode with the 80-bit XFmode on ia64. I don't understand the target details here particularly well, but from the way the modes are described in ia64-modes.def, it isn't valid to assume that an XFmode can carry an RFmode payload. A comparison of the testsuite assembly output for one target per CPU showed no other differences. Some of the places changed here are tracking the widest access mode found for a register. The series tries to standardise on: if (partial_subreg_p (widest_seen, new_mode)) widest_seen = new_mode; rather than: if (paradoxical_subreg_p (new_mode, widest_seen)) widest_seen = new_mode; Either would have been OK. Tested on aarch64-linux-gnu and x86_64-linux-gnu in addition to the above. OK to install? Richard 2017-08-21 Richard Sandiford Alan Hayward David Sherwood gcc/ * rtl.h (partial_subreg_p): New function. * caller-save.c (save_call_clobbered_regs): Use it. * calls.c (expand_call): Likewise. * combine.c (combinable_i3pat): Likewise. (simplify_set): Likewise. (make_extraction): Likewise. (make_compound_operation_int): Likewise. (gen_lowpart_or_truncate): Likewise. (force_to_mode): Likewise. (make_field_assignment): Likewise. (reg_truncated_to_mode): Likewise. (record_truncated_value): Likewise. (move_deaths): Likewise. * cse.c (record_jump_cond): Likewise. (cse_insn): Likewise. * cselib.c (cselib_lookup_1): Likewise. * df-scan.c (df_read_modify_subreg_p): Likewise. * expmed.c (extract_bit_field_using_extv): Likewise. * function.c (assign_parm_setup_reg): Likewise. * ifcvt.c (noce_convert_multiple_sets): Likewise. * ira-build.c (create_insn_allocnos): Likewise. * lra-coalesce.c (merge_pseudos): Likewise. * lra-constraints.c (match_reload): Likewise. (simplify_operand_subreg): Likewise. (curr_insn_transform): Likewise. * lra-lives.c (process_bb_lives): Likewise. * lra.c (new_insn_reg): Likewise. (lra_substitute_pseudo): Likewise. * regcprop.c (mode_change_ok): Likewise. (maybe_mode_change): Likewise. (copyprop_hardreg_forward_1): Likewise. * reload.c (push_reload): Likewise. (find_reloads): Likewise. (find_reloads_subreg_address): Likewise. * reload1.c (alter_reg): Likewise. (eliminate_regs_1): Likewise. * simplify-rtx.c (simplify_unary_operation_1): Likewise. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2017-08-21 14:20:43.099964655 +0100 +++ gcc/rtl.h 2017-08-21 14:21:03.728890033 +0100 @@ -2787,6 +2787,30 @@ extern rtx operand_subword_force (rtx, u extern int subreg_lowpart_p (const_rtx); extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int); +/* Return true if a subreg of mode OUTERMODE would only access part of + an inner register with mode INNERMODE. The other bits of the inner + register would then be "don't care" on read. The behavior for writes + depends on REGMODE_NATURAL_SIZE; bits in the same REGMODE_NATURAL_SIZE-d + chunk would be clobbered but other bits would be preserved. */ + +inline bool +partial_subreg_p (machine_mode outermode, machine_mode innermode) +{ + return GET_MODE_PRECISION (outermode) < GET_MODE_PRECISION (innermode); +} + +/* Likewise return true if X is a subreg that is smaller than the inner + register. Use df_read_modify_subreg_p to test whether writing to such + a subreg preserves any part of the inner register. */ + +inline bool +partial_subreg_p (const_rtx x) +{ + if (GET_CODE (x) != SUBREG) + return false; + return partial_subreg_p (GET_MODE (x), GET_MODE (SUBREG_REG (x))); +} + /* Return true if a subreg with the given outer and inner modes is paradoxical. */ Index: gcc/caller-save.c =================================================================== --- gcc/caller-save.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/caller-save.c 2017-08-21 14:21:03.716860701 +0100 @@ -837,8 +837,7 @@ save_call_clobbered_regs (void) nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; mode = HARD_REGNO_CALLER_SAVE_MODE (r, nregs, PSEUDO_REGNO_MODE (regno)); - if (GET_MODE_BITSIZE (mode) - > GET_MODE_BITSIZE (save_mode[r])) + if (partial_subreg_p (save_mode[r], mode)) save_mode[r] = mode; while (nregs-- > 0) SET_HARD_REG_BIT (hard_regs_to_save, r + nregs); Index: gcc/calls.c =================================================================== --- gcc/calls.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/calls.c 2017-08-21 14:21:03.716860701 +0100 @@ -3354,8 +3354,7 @@ expand_call (tree exp, rtx target, int i || ((caller_mode != caller_promoted_mode || callee_mode != callee_promoted_mode) && (caller_unsignedp != callee_unsignedp - || GET_MODE_BITSIZE (caller_mode) - < GET_MODE_BITSIZE (callee_mode))))) + || partial_subreg_p (caller_mode, callee_mode))))) { try_tail_call = 0; maybe_complain_about_tail_call (exp, Index: gcc/combine.c =================================================================== --- gcc/combine.c 2017-08-21 14:20:43.092940547 +0100 +++ gcc/combine.c 2017-08-21 14:21:03.718865590 +0100 @@ -2220,9 +2220,7 @@ combinable_i3pat (rtx_insn *i3, rtx *loc STACK_POINTER_REGNUM, since these are always considered to be live. Similarly for ARG_POINTER_REGNUM if it is fixed. */ subdest = dest; - if (GET_CODE (subdest) == SUBREG - && (GET_MODE_SIZE (GET_MODE (subdest)) - >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (subdest))))) + if (GET_CODE (subdest) == SUBREG && !partial_subreg_p (subdest)) subdest = SUBREG_REG (subdest); if (pi3dest_killed && REG_P (subdest) @@ -6831,10 +6829,8 @@ simplify_set (rtx x) /* If we have (set (cc0) (subreg ...)), we try to remove the subreg in SRC. */ if (dest == cc0_rtx - && GET_CODE (src) == SUBREG - && subreg_lowpart_p (src) - && (GET_MODE_PRECISION (GET_MODE (src)) - < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (src))))) + && partial_subreg_p (src) + && subreg_lowpart_p (src)) { rtx inner = SUBREG_REG (src); machine_mode inner_mode = GET_MODE (inner); @@ -7603,7 +7599,7 @@ make_extraction (machine_mode mode, rtx /* Never narrow an object, since that might not be safe. */ if (mode != VOIDmode - && GET_MODE_SIZE (extraction_mode) < GET_MODE_SIZE (mode)) + && partial_subreg_p (extraction_mode, mode)) extraction_mode = mode; if (!MEM_P (inner)) @@ -7653,7 +7649,7 @@ make_extraction (machine_mode mode, rtx if (wanted_inner_mode != VOIDmode && inner_mode != wanted_inner_mode && ! pos_rtx - && GET_MODE_SIZE (wanted_inner_mode) < GET_MODE_SIZE (is_mode) + && partial_subreg_p (wanted_inner_mode, is_mode) && MEM_P (inner) && ! mode_dependent_address_p (XEXP (inner, 0), MEM_ADDR_SPACE (inner)) && ! MEM_VOLATILE_P (inner)) @@ -8167,7 +8163,7 @@ make_compound_operation_int (machine_mod to (subreg:QI (lshiftrt:SI (reg:SI) (const_int 7)) 0). */ || (GET_CODE (inner) == AND && CONST_INT_P (XEXP (inner, 1)) - && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner)) + && partial_subreg_p (x) && exact_log2 (UINTVAL (XEXP (inner, 1))) >= GET_MODE_BITSIZE (mode) - 1))) subreg_code = SET; @@ -8180,7 +8176,7 @@ make_compound_operation_int (machine_mod tem = simplified; if (GET_CODE (tem) != GET_CODE (inner) - && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner)) + && partial_subreg_p (x) && subreg_lowpart_p (x)) { rtx newer @@ -8191,8 +8187,9 @@ make_compound_operation_int (machine_mod if (GET_CODE (newer) != SUBREG) newer = make_compound_operation (newer, in_code); - /* force_to_mode can expand compounds. If it just re-expanded the - compound, use gen_lowpart to convert to the desired mode. */ + /* force_to_mode can expand compounds. If it just re-expanded + the compound, use gen_lowpart to convert to the desired + mode. */ if (rtx_equal_p (newer, x) /* Likewise if it re-expanded the compound only partially. This happens for SUBREG of ZERO_EXTRACT if they extract @@ -8433,7 +8430,7 @@ canon_reg_for_combine (rtx x, rtx reg) gen_lowpart_or_truncate (machine_mode mode, rtx x) { if (!CONST_INT_P (x) - && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)) + && partial_subreg_p (mode, GET_MODE (x)) && !TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (x)) && !(REG_P (x) && reg_truncated_to_mode (mode, x))) { @@ -8489,7 +8486,7 @@ force_to_mode (rtx x, machine_mode mode, /* It is not valid to do a right-shift in a narrower mode than the one it came in with. */ if ((code == LSHIFTRT || code == ASHIFTRT) - && GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (GET_MODE (x))) + && partial_subreg_p (mode, GET_MODE (x))) op_mode = GET_MODE (x); /* Truncate MASK to fit OP_MODE. */ @@ -8535,8 +8532,7 @@ force_to_mode (rtx x, machine_mode mode, if the constant masks to zero all the bits the mode doesn't have. */ if (GET_CODE (x) == SUBREG && subreg_lowpart_p (x) - && ((GET_MODE_SIZE (GET_MODE (x)) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) + && (partial_subreg_p (x) || (0 == (mask & GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x))))))) @@ -9485,8 +9481,7 @@ make_field_assignment (rtx x) if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG && subreg_lowpart_p (XEXP (src, 0)) - && (GET_MODE_SIZE (GET_MODE (XEXP (src, 0))) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0))))) + && partial_subreg_p (XEXP (src, 0)) && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE && CONST_INT_P (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2 @@ -13207,7 +13202,7 @@ reg_truncated_to_mode (machine_mode mode if (truncated == 0 || rsp->truncation_label < label_tick_ebb_start) return false; - if (GET_MODE_SIZE (truncated) <= GET_MODE_SIZE (mode)) + if (!partial_subreg_p (mode, truncated)) return true; if (TRULY_NOOP_TRUNCATION_MODES_P (mode, truncated)) return true; @@ -13230,9 +13225,10 @@ record_truncated_value (rtx x) machine_mode original_mode = GET_MODE (SUBREG_REG (x)); truncated_mode = GET_MODE (x); - if (GET_MODE_SIZE (original_mode) <= GET_MODE_SIZE (truncated_mode)) + if (!partial_subreg_p (truncated_mode, original_mode)) return true; + truncated_mode = GET_MODE (x); if (TRULY_NOOP_TRUNCATION_MODES_P (truncated_mode, original_mode)) return true; @@ -13248,8 +13244,7 @@ record_truncated_value (rtx x) rsp = ®_stat[REGNO (x)]; if (rsp->truncated_to_mode == 0 || rsp->truncation_label < label_tick_ebb_start - || (GET_MODE_SIZE (truncated_mode) - < GET_MODE_SIZE (rsp->truncated_to_mode))) + || partial_subreg_p (truncated_mode, rsp->truncated_to_mode)) { rsp->truncated_to_mode = truncated_mode; rsp->truncation_label = label_tick; @@ -13773,8 +13768,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, the remaining registers in place of NOTE. */ if (note != 0 && regno < FIRST_PSEUDO_REGISTER - && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) - > GET_MODE_SIZE (GET_MODE (x)))) + && partial_subreg_p (GET_MODE (x), GET_MODE (XEXP (note, 0)))) { unsigned int deadregno = REGNO (XEXP (note, 0)); unsigned int deadend = END_REGNO (XEXP (note, 0)); @@ -13793,8 +13787,8 @@ move_deaths (rtx x, rtx maybe_kill_insn, their own REG_DEAD notes lying around. */ else if ((note == 0 || (note != 0 - && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) - < GET_MODE_SIZE (GET_MODE (x))))) + && partial_subreg_p (GET_MODE (XEXP (note, 0)), + GET_MODE (x)))) && regno < FIRST_PSEUDO_REGISTER && REG_NREGS (x) > 1) { Index: gcc/cse.c =================================================================== --- gcc/cse.c 2017-08-21 14:20:43.093943991 +0100 +++ gcc/cse.c 2017-08-21 14:21:03.719868034 +0100 @@ -3952,10 +3952,9 @@ record_jump_cond (enum rtx_code code, ma if we test MODE instead, we can get an infinite recursion alternating between two modes each wider than MODE. */ - if (code == NE && GET_CODE (op0) == SUBREG - && subreg_lowpart_p (op0) - && (GET_MODE_SIZE (GET_MODE (op0)) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))) + if (code == NE + && partial_subreg_p (op0) + && subreg_lowpart_p (op0)) { machine_mode inner_mode = GET_MODE (SUBREG_REG (op0)); rtx tem = record_jump_cond_subreg (inner_mode, op1); @@ -3964,10 +3963,9 @@ record_jump_cond (enum rtx_code code, ma reversed_nonequality); } - if (code == NE && GET_CODE (op1) == SUBREG - && subreg_lowpart_p (op1) - && (GET_MODE_SIZE (GET_MODE (op1)) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))))) + if (code == NE + && partial_subreg_p (op1) + && subreg_lowpart_p (op1)) { machine_mode inner_mode = GET_MODE (SUBREG_REG (op1)); rtx tem = record_jump_cond_subreg (inner_mode, op0); @@ -5000,8 +4998,8 @@ cse_insn (rtx_insn *insn) && ! (src != 0 && GET_CODE (src) == SUBREG && GET_MODE (src) == GET_MODE (p->exp) - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp)))))) + && partial_subreg_p (GET_MODE (SUBREG_REG (src)), + GET_MODE (SUBREG_REG (p->exp))))) continue; if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp)) @@ -5111,8 +5109,8 @@ cse_insn (rtx_insn *insn) && ! (src != 0 && GET_CODE (src) == SUBREG && GET_MODE (src) == GET_MODE (elt->exp) - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp)))))) + && partial_subreg_p (GET_MODE (SUBREG_REG (src)), + GET_MODE (SUBREG_REG (elt->exp))))) { elt = elt->next_same_value; continue; @@ -5951,8 +5949,7 @@ cse_insn (rtx_insn *insn) && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - 1) / UNITS_PER_WORD) == (GET_MODE_SIZE (GET_MODE (dest)) - 1) / UNITS_PER_WORD) - && (GET_MODE_SIZE (GET_MODE (dest)) - >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))) + && !partial_subreg_p (dest) && sets[i].src_elt != 0) { machine_mode new_mode = GET_MODE (SUBREG_REG (dest)); Index: gcc/cselib.c =================================================================== --- gcc/cselib.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/cselib.c 2017-08-21 14:21:03.719868034 +0100 @@ -2033,8 +2033,8 @@ cselib_lookup_1 (rtx x, machine_mode mod && GET_MODE_SIZE (GET_MODE (l->elt->val_rtx)) > GET_MODE_SIZE (mode) && (lwider == NULL - || GET_MODE_SIZE (GET_MODE (l->elt->val_rtx)) - < GET_MODE_SIZE (GET_MODE (lwider->elt->val_rtx)))) + || partial_subreg_p (GET_MODE (l->elt->val_rtx), + GET_MODE (lwider->elt->val_rtx)))) { struct elt_loc_list *el; if (i < FIRST_PSEUDO_REGISTER Index: gcc/df-scan.c =================================================================== --- gcc/df-scan.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/df-scan.c 2017-08-21 14:21:03.719868034 +0100 @@ -2631,13 +2631,12 @@ df_ref_record (enum df_ref_class cl, bool df_read_modify_subreg_p (rtx x) { - unsigned int isize, osize; - if (GET_CODE (x) != SUBREG) + unsigned int isize; + + if (!partial_subreg_p (x)) return false; isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))); - osize = GET_MODE_SIZE (GET_MODE (x)); - return isize > osize - && isize > REGMODE_NATURAL_SIZE (GET_MODE (SUBREG_REG (x))); + return isize > REGMODE_NATURAL_SIZE (GET_MODE (SUBREG_REG (x))); } Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-08-21 14:20:43.095950879 +0100 +++ gcc/expmed.c 2017-08-21 14:21:03.720870478 +0100 @@ -1501,8 +1501,7 @@ extract_bit_field_using_extv (const extr && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode)) { target = gen_lowpart (ext_mode, target); - if (GET_MODE_PRECISION (ext_mode) - > GET_MODE_PRECISION (GET_MODE (spec_target))) + if (partial_subreg_p (GET_MODE (spec_target), ext_mode)) spec_target_subreg = target; } else Index: gcc/function.c =================================================================== --- gcc/function.c 2017-08-21 12:09:48.345623608 +0100 +++ gcc/function.c 2017-08-21 14:21:03.721872923 +0100 @@ -3262,13 +3262,11 @@ assign_parm_setup_reg (struct assign_par push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn); tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp); - if (GET_CODE (tempreg) == SUBREG + if (partial_subreg_p (tempreg) && GET_MODE (tempreg) == data->nominal_mode && REG_P (SUBREG_REG (tempreg)) && data->nominal_mode == data->passed_mode - && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (data->entry_parm) - && GET_MODE_SIZE (GET_MODE (tempreg)) - < GET_MODE_SIZE (GET_MODE (data->entry_parm))) + && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (data->entry_parm)) { /* The argument is already sign/zero extended, so note it into the subreg. */ Index: gcc/ifcvt.c =================================================================== --- gcc/ifcvt.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/ifcvt.c 2017-08-21 14:21:03.721872923 +0100 @@ -3195,7 +3195,7 @@ noce_convert_multiple_sets (struct noce_ { machine_mode src_mode = GET_MODE (new_val); machine_mode dst_mode = GET_MODE (temp); - if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode)) + if (!partial_subreg_p (dst_mode, src_mode)) { end_sequence (); return FALSE; @@ -3206,7 +3206,7 @@ noce_convert_multiple_sets (struct noce_ { machine_mode src_mode = GET_MODE (old_val); machine_mode dst_mode = GET_MODE (temp); - if (GET_MODE_SIZE (src_mode) <= GET_MODE_SIZE (dst_mode)) + if (!partial_subreg_p (dst_mode, src_mode)) { end_sequence (); return FALSE; Index: gcc/ira-build.c =================================================================== --- gcc/ira-build.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/ira-build.c 2017-08-21 14:21:03.722875367 +0100 @@ -1853,7 +1853,7 @@ create_insn_allocnos (rtx x, rtx outer, if (outer != NULL && GET_CODE (outer) == SUBREG) { machine_mode wmode = GET_MODE (outer); - if (GET_MODE_SIZE (wmode) > GET_MODE_SIZE (ALLOCNO_WMODE (a))) + if (partial_subreg_p (ALLOCNO_WMODE (a), wmode)) ALLOCNO_WMODE (a) = wmode; } } Index: gcc/lra-coalesce.c =================================================================== --- gcc/lra-coalesce.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/lra-coalesce.c 2017-08-21 14:21:03.722875367 +0100 @@ -112,8 +112,8 @@ merge_pseudos (int regno1, int regno2) = (lra_merge_live_ranges (lra_reg_info[first].live_ranges, lra_copy_live_range_list (lra_reg_info[first2].live_ranges))); - if (GET_MODE_SIZE (lra_reg_info[first].biggest_mode) - < GET_MODE_SIZE (lra_reg_info[first2].biggest_mode)) + if (partial_subreg_p (lra_reg_info[first].biggest_mode, + lra_reg_info[first2].biggest_mode)) lra_reg_info[first].biggest_mode = lra_reg_info[first2].biggest_mode; } Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2017-08-21 14:20:43.096954323 +0100 +++ gcc/lra-constraints.c 2017-08-21 14:21:03.722875367 +0100 @@ -925,7 +925,7 @@ match_reload (signed char out, signed ch push_to_sequence (*before); if (inmode != outmode) { - if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode)) + if (partial_subreg_p (outmode, inmode)) { reg = new_in_reg = lra_create_new_reg_with_unique_value (inmode, in_rtx, @@ -1576,8 +1576,7 @@ simplify_operand_subreg (int nop, machin bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); insert_before = (type != OP_OUT - || GET_MODE_SIZE (innermode) - > GET_MODE_SIZE (mode)); + || partial_subreg_p (mode, innermode)); insert_after = type != OP_IN; insert_move_for_subreg (insert_before ? &before : NULL, insert_after ? &after : NULL, @@ -3936,8 +3935,7 @@ curr_insn_transform (bool check_only_p) lra_assert (out >= 0 && in >= 0 && curr_static_id->operand[out].type == OP_OUT && curr_static_id->operand[in].type == OP_IN); - rld = (GET_MODE_SIZE (GET_MODE (dest)) <= GET_MODE_SIZE (GET_MODE (src)) - ? dest : src); + rld = partial_subreg_p (GET_MODE (src), GET_MODE (dest)) ? src : dest; rld_mode = GET_MODE (rld); #ifdef SECONDARY_MEMORY_NEEDED_MODE sec_mode = SECONDARY_MEMORY_NEEDED_MODE (rld_mode); @@ -3947,7 +3945,7 @@ curr_insn_transform (bool check_only_p) new_reg = lra_create_new_reg (sec_mode, NULL_RTX, NO_REGS, "secondary"); /* If the mode is changed, it should be wider. */ - lra_assert (GET_MODE_SIZE (sec_mode) >= GET_MODE_SIZE (rld_mode)); + lra_assert (!partial_subreg_p (sec_mode, rld_mode)); if (sec_mode != rld_mode) { /* If the target says specifically to use another mode for Index: gcc/lra-lives.c =================================================================== --- gcc/lra-lives.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/lra-lives.c 2017-08-21 14:21:03.723877811 +0100 @@ -717,9 +717,9 @@ process_bb_lives (basic_block bb, int &c for (reg = curr_id->regs; reg != NULL; reg = reg->next) { int i, regno = reg->regno; - - if (GET_MODE_SIZE (reg->biggest_mode) - > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode)) + + if (partial_subreg_p (lra_reg_info[regno].biggest_mode, + reg->biggest_mode)) lra_reg_info[regno].biggest_mode = reg->biggest_mode; if (regno < FIRST_PSEUDO_REGISTER) { @@ -729,8 +729,8 @@ process_bb_lives (basic_block bb, int &c part of multi-register group. Process this case here. */ for (i = 1; i < hard_regno_nregs[regno][reg->biggest_mode]; i++) - if (GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno + i])) - > GET_MODE_SIZE (lra_reg_info[regno + i].biggest_mode)) + if (partial_subreg_p (lra_reg_info[regno + i].biggest_mode, + GET_MODE (regno_reg_rtx[regno + i]))) lra_reg_info[regno + i].biggest_mode = GET_MODE (regno_reg_rtx[regno + i]); } Index: gcc/lra.c =================================================================== --- gcc/lra.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/lra.c 2017-08-21 14:21:03.723877811 +0100 @@ -546,8 +546,8 @@ new_insn_reg (rtx_insn *insn, int regno, lra_insn_reg *ir = lra_insn_reg_pool.allocate (); ir->type = type; ir->biggest_mode = mode; - if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode) - && NONDEBUG_INSN_P (insn)) + if (NONDEBUG_INSN_P (insn) + && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode)) lra_reg_info[regno].biggest_mode = mode; ir->subreg_p = subreg_p; ir->early_clobber = early_clobber; @@ -1913,7 +1913,7 @@ lra_substitute_pseudo (rtx *loc, int old if (mode != inner_mode && ! (CONST_INT_P (new_reg) && SCALAR_INT_MODE_P (mode))) { - if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (inner_mode) + if (!partial_subreg_p (mode, inner_mode) || ! SCALAR_INT_MODE_P (inner_mode)) new_reg = gen_rtx_SUBREG (mode, new_reg, 0); else Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2017-08-21 10:42:34.185530464 +0100 +++ gcc/regcprop.c 2017-08-21 14:21:03.726885145 +0100 @@ -372,7 +372,7 @@ copy_value (rtx dest, rtx src, struct va mode_change_ok (machine_mode orig_mode, machine_mode new_mode, unsigned int regno ATTRIBUTE_UNUSED) { - if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode)) + if (partial_subreg_p (orig_mode, new_mode)) return false; #ifdef CANNOT_CHANGE_MODE_CLASS @@ -392,8 +392,8 @@ maybe_mode_change (machine_mode orig_mod machine_mode new_mode, unsigned int regno, unsigned int copy_regno ATTRIBUTE_UNUSED) { - if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (orig_mode) - && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode)) + if (partial_subreg_p (copy_mode, orig_mode) + && partial_subreg_p (copy_mode, new_mode)) return NULL_RTX; /* Avoid creating multiple copies of the stack pointer. Some ports @@ -1076,8 +1076,8 @@ copyprop_hardreg_forward_1 (basic_block /* If a noop move is using narrower mode than we have recorded, we need to either remove the noop move, or kill_set_value. */ if (noop_p - && (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) - < GET_MODE_BITSIZE (vd->e[REGNO (SET_DEST (set))].mode))) + && partial_subreg_p (GET_MODE (SET_DEST (set)), + vd->e[REGNO (SET_DEST (set))].mode)) { if (noop_move_p (insn)) { Index: gcc/reload.c =================================================================== --- gcc/reload.c 2017-08-21 14:20:43.098961211 +0100 +++ gcc/reload.c 2017-08-21 14:21:03.727887589 +0100 @@ -1071,8 +1071,7 @@ push_reload (rtx in, rtx out, rtx *inloc && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in))) && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN) || (WORD_REGISTER_OPERATIONS - && (GET_MODE_PRECISION (inmode) - < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in)))) + && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in))) && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1) / UNITS_PER_WORD))))) @@ -1171,8 +1170,7 @@ push_reload (rtx in, rtx out, rtx *inloc || MEM_P (SUBREG_REG (out))) && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out))) || (WORD_REGISTER_OPERATIONS - && (GET_MODE_PRECISION (outmode) - < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out)))) + && partial_subreg_p (outmode, GET_MODE (SUBREG_REG (out))) && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1) / UNITS_PER_WORD))))) @@ -1417,10 +1415,10 @@ push_reload (rtx in, rtx out, rtx *inloc /* The modes can be different. If they are, we want to reload in the larger mode, so that the value is valid for both modes. */ if (inmode != VOIDmode - && GET_MODE_SIZE (inmode) > GET_MODE_SIZE (rld[i].inmode)) + && partial_subreg_p (rld[i].inmode, inmode)) rld[i].inmode = inmode; if (outmode != VOIDmode - && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (rld[i].outmode)) + && partial_subreg_p (rld[i].outmode, outmode)) rld[i].outmode = outmode; if (in != 0) { @@ -1462,26 +1460,25 @@ push_reload (rtx in, rtx out, rtx *inloc overwrite the operands only when the new mode is larger. See also PR33613. */ if (!rld[i].in - || GET_MODE_SIZE (GET_MODE (in)) - > GET_MODE_SIZE (GET_MODE (rld[i].in))) + || partial_subreg_p (GET_MODE (rld[i].in), GET_MODE (in))) rld[i].in = in; if (!rld[i].in_reg || (in_reg - && GET_MODE_SIZE (GET_MODE (in_reg)) - > GET_MODE_SIZE (GET_MODE (rld[i].in_reg)))) + && partial_subreg_p (GET_MODE (rld[i].in_reg), + GET_MODE (in_reg)))) rld[i].in_reg = in_reg; } if (out != 0) { if (!rld[i].out || (out - && GET_MODE_SIZE (GET_MODE (out)) - > GET_MODE_SIZE (GET_MODE (rld[i].out)))) + && partial_subreg_p (GET_MODE (rld[i].out), + GET_MODE (out)))) rld[i].out = out; if (outloc && (!rld[i].out_reg - || GET_MODE_SIZE (GET_MODE (*outloc)) - > GET_MODE_SIZE (GET_MODE (rld[i].out_reg)))) + || partial_subreg_p (GET_MODE (rld[i].out_reg), + GET_MODE (*outloc)))) rld[i].out_reg = *outloc; } if (reg_class_subset_p (rclass, rld[i].rclass)) @@ -1587,7 +1584,7 @@ push_reload (rtx in, rtx out, rtx *inloc int regno; machine_mode rel_mode = inmode; - if (out && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (inmode)) + if (out && partial_subreg_p (rel_mode, outmode)) rel_mode = outmode; for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1)) @@ -4549,11 +4546,10 @@ find_reloads (rtx_insn *insn, int replac /* Compute reload_mode and reload_nregs. */ for (i = 0; i < n_reloads; i++) { - rld[i].mode - = (rld[i].inmode == VOIDmode - || (GET_MODE_SIZE (rld[i].outmode) - > GET_MODE_SIZE (rld[i].inmode))) - ? rld[i].outmode : rld[i].inmode; + rld[i].mode = rld[i].inmode; + if (rld[i].mode == VOIDmode + || partial_subreg_p (rld[i].mode, rld[i].outmode)) + rld[i].mode = rld[i].outmode; rld[i].nregs = ira_reg_class_max_nregs [rld[i].rclass][rld[i].mode]; } @@ -6157,7 +6153,7 @@ find_reloads_subreg_address (rtx x, int return NULL; if (WORD_REGISTER_OPERATIONS - && GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode) + && partial_subreg_p (outer_mode, inner_mode) && ((GET_MODE_SIZE (outer_mode) - 1) / UNITS_PER_WORD == (GET_MODE_SIZE (inner_mode) - 1) / UNITS_PER_WORD)) return NULL; Index: gcc/reload1.c =================================================================== --- gcc/reload1.c 2017-08-21 14:20:43.099964655 +0100 +++ gcc/reload1.c 2017-08-21 14:21:03.728890033 +0100 @@ -2218,8 +2218,8 @@ alter_reg (int i, int from_reg, bool don if (spill_stack_slot[from_reg]) { - if (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg])) - > inherent_size) + if (partial_subreg_p (mode, + GET_MODE (spill_stack_slot[from_reg]))) mode = GET_MODE (spill_stack_slot[from_reg]); if (spill_stack_slot_width[from_reg] > total_size) total_size = spill_stack_slot_width[from_reg]; @@ -2817,7 +2817,7 @@ eliminate_regs_1 (rtx x, machine_mode me int new_size = GET_MODE_SIZE (GET_MODE (new_rtx)); if (MEM_P (new_rtx) - && ((x_size < new_size + && ((partial_subreg_p (GET_MODE (x), GET_MODE (new_rtx)) /* On RISC machines, combine can create rtl of the form (set (subreg:m1 (reg:m2 R) 0) ...) where m1 < m2, and expects something interesting to Index: gcc/simplify-rtx.c =================================================================== --- gcc/simplify-rtx.c 2017-08-21 14:20:43.102974987 +0100 +++ gcc/simplify-rtx.c 2017-08-21 14:21:03.728890033 +0100 @@ -987,10 +987,8 @@ simplify_unary_operation_1 (enum rtx_cod XEXP (op, 0), const0_rtx); - if (GET_CODE (op) == SUBREG + if (partial_subreg_p (op) && subreg_lowpart_p (op) - && (GET_MODE_SIZE (GET_MODE (op)) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))) && GET_CODE (SUBREG_REG (op)) == ASHIFT && XEXP (SUBREG_REG (op), 0) == const1_rtx) { @@ -1627,9 +1625,7 @@ simplify_unary_operation_1 (enum rtx_cod of mode N. E.g. (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is (and:SI (reg:SI) (const_int 63)). */ - if (GET_CODE (op) == SUBREG - && GET_MODE_PRECISION (GET_MODE (op)) - < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op))) + if (partial_subreg_p (op) && GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op))) <= HOST_BITS_PER_WIDE_INT && GET_MODE_PRECISION (mode)