From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 62904 invoked by alias); 23 Oct 2017 17:34:53 -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 62893 invoked by uid 89); 23 Oct 2017 17:34:52 -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-f176.google.com Received: from mail-wr0-f176.google.com (HELO mail-wr0-f176.google.com) (209.85.128.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 23 Oct 2017 17:34:50 +0000 Received: by mail-wr0-f176.google.com with SMTP id w105so8880453wrc.0 for ; Mon, 23 Oct 2017 10:34:50 -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:references:date :in-reply-to:message-id:user-agent:mime-version; bh=5utaCr39DkcszSviCgpHmbgkgi/m5yVsKxpt1TOe37w=; b=b0EkLlkFg9nuGDmVJ4lh9semqnR76/+QV7vw7coBydDKjgrMsXjcyoSWuFqVezwjBH TP1jP0EvTNtxQqWK+LyiFaBr+ZmGcTYY6jILWtzzly7QAYeOcNf5SEdA445735bfrTn4 ZG9gzwEeq4PLCVJYwnZmWQ/9Z5xgPYtP3LJPp84hSoqjyiJCHZsmZ+Tns7WDNABS2dCH 0kEBNF2YQlBlEU3D58gZ6qy5qWLKFZRFI6NYF3cUnv9zHlFTgHbeaodcaW6FkNNCD6Vs hP8bvsW5rtF7vx3NnotbXSlNnYn7Q2xyL2mGmmqvgSr9VqqeIo6l/4k77EpCZD/dNf/E W88g== X-Gm-Message-State: AMCzsaUj1HV6mNF3i5ecGZZmme8j4wugUtcz7lLx3QXyi5qdnV3ItKNj dxye4W2qiQ8YMmtMYpXym7ehye0s110= X-Google-Smtp-Source: ABhQp+QwZSJgJhDzIb91zlIqOUZi+p6zXcbzXoPqPF1gNpy3Bf9l+6xZiW4yIQ1+5gQvtHdHT+5Nnw== X-Received: by 10.223.184.230 with SMTP id c35mr6164090wrg.18.1508780088225; Mon, 23 Oct 2017 10:34:48 -0700 (PDT) Received: from localhost ([2.26.27.199]) by smtp.gmail.com with ESMTPSA id w14sm5256170wmd.9.2017.10.23.10.34.47 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 10:34:47 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [086/nnn] poly_int: REGMODE_NATURAL_SIZE References: <871sltvm7r.fsf@linaro.org> Date: Mon, 23 Oct 2017 17:35:00 -0000 In-Reply-To: <871sltvm7r.fsf@linaro.org> (Richard Sandiford's message of "Mon, 23 Oct 2017 17:54:32 +0100") Message-ID: <87h8upg43t.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2017-10/txt/msg01587.txt.bz2 This patch makes target-independent code that uses REGMODE_NATURAL_SIZE treat it as a poly_int rather than a constant. 2017-10-23 Richard Sandiford Alan Hayward David Sherwood gcc/ * combine.c (can_change_dest_mode): Handle polynomial REGMODE_NATURAL_SIZE. * expmed.c (store_bit_field_1): Likewise. * expr.c (store_constructor): Likewise. * emit-rtl.c (validate_subreg): Operate on polynomial mode sizes and polynomial REGMODE_NATURAL_SIZE. (gen_lowpart_common): Likewise. * reginfo.c (record_subregs_of_mode): Likewise. * rtlanal.c (read_modify_subreg_p): Likewise. Index: gcc/combine.c =================================================================== --- gcc/combine.c 2017-10-23 17:25:26.554256722 +0100 +++ gcc/combine.c 2017-10-23 17:25:30.702136080 +0100 @@ -2474,8 +2474,8 @@ can_change_dest_mode (rtx x, int added_s /* Don't change between modes with different underlying register sizes, since this could lead to invalid subregs. */ - if (REGMODE_NATURAL_SIZE (mode) - != REGMODE_NATURAL_SIZE (GET_MODE (x))) + if (may_ne (REGMODE_NATURAL_SIZE (mode), + REGMODE_NATURAL_SIZE (GET_MODE (x)))) return false; regno = REGNO (x); Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-10-23 17:23:00.293367701 +0100 +++ gcc/expmed.c 2017-10-23 17:25:30.703136044 +0100 @@ -778,7 +778,7 @@ store_bit_field_1 (rtx str_rtx, poly_uin In the latter case, use subreg on the rhs side, not lhs. */ rtx sub; HOST_WIDE_INT regnum; - HOST_WIDE_INT regsize = REGMODE_NATURAL_SIZE (GET_MODE (op0)); + poly_uint64 regsize = REGMODE_NATURAL_SIZE (GET_MODE (op0)); if (known_zero (bitnum) && must_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))) { Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-10-23 17:23:00.293367701 +0100 +++ gcc/expr.c 2017-10-23 17:25:30.704136008 +0100 @@ -6204,8 +6204,8 @@ store_constructor (tree exp, rtx target, a constant. But if more than one register is involved, this probably loses. */ else if (REG_P (target) && TREE_STATIC (exp) - && (GET_MODE_SIZE (GET_MODE (target)) - <= REGMODE_NATURAL_SIZE (GET_MODE (target)))) + && must_le (GET_MODE_SIZE (GET_MODE (target)), + REGMODE_NATURAL_SIZE (GET_MODE (target)))) { emit_move_insn (target, CONST0_RTX (GET_MODE (target))); cleared = 1; Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-10-23 17:23:00.293367701 +0100 +++ gcc/emit-rtl.c 2017-10-23 17:25:30.703136044 +0100 @@ -924,8 +924,13 @@ gen_tmp_stack_mem (machine_mode mode, rt validate_subreg (machine_mode omode, machine_mode imode, const_rtx reg, poly_uint64 offset) { - unsigned int isize = GET_MODE_SIZE (imode); - unsigned int osize = GET_MODE_SIZE (omode); + poly_uint64 isize = GET_MODE_SIZE (imode); + poly_uint64 osize = GET_MODE_SIZE (omode); + + /* The sizes must be ordered, so that we know whether the subreg + is partial, paradoxical or complete. */ + if (!ordered_p (isize, osize)) + return false; /* All subregs must be aligned. */ if (!multiple_p (offset, osize)) @@ -935,7 +940,7 @@ validate_subreg (machine_mode omode, mac if (may_ge (offset, isize)) return false; - unsigned int regsize = REGMODE_NATURAL_SIZE (imode); + poly_uint64 regsize = REGMODE_NATURAL_SIZE (imode); /* ??? This should not be here. Temporarily continue to allow word_mode subregs of anything. The most common offender is (subreg:SI (reg:DF)). @@ -945,7 +950,7 @@ validate_subreg (machine_mode omode, mac ; /* ??? Similarly, e.g. with (subreg:DF (reg:TI)). Though store_bit_field is the culprit here, and not the backends. */ - else if (osize >= regsize && isize >= osize) + else if (must_ge (osize, regsize) && must_ge (isize, osize)) ; /* Allow component subregs of complex and vector. Though given the below extraction rules, it's not always clear what that means. */ @@ -964,7 +969,7 @@ validate_subreg (machine_mode omode, mac (subreg:SI (reg:DF) 0) isn't. */ else if (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode)) { - if (! (isize == osize + if (! (must_eq (isize, osize) /* LRA can use subreg to store a floating point value in an integer mode. Although the floating point and the integer modes need the same number of hard registers, @@ -976,7 +981,7 @@ validate_subreg (machine_mode omode, mac } /* Paradoxical subregs must have offset zero. */ - if (osize > isize) + if (may_gt (osize, isize)) return known_zero (offset); /* This is a normal subreg. Verify that the offset is representable. */ @@ -996,6 +1001,12 @@ validate_subreg (machine_mode omode, mac return subreg_offset_representable_p (regno, imode, offset, omode); } + /* The outer size must be ordered wrt the register size, otherwise + we wouldn't know at compile time how many registers the outer + mode occupies. */ + if (!ordered_p (osize, regsize)) + return false; + /* For pseudo registers, we want most of the same checks. Namely: Assume that the pseudo register will be allocated to hard registers @@ -1006,10 +1017,12 @@ validate_subreg (machine_mode omode, mac Given that we've already checked the mode and offset alignment, we only have to check subblock subregs here. */ - if (osize < regsize + if (may_lt (osize, regsize) && ! (lra_in_progress && (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode)))) { - poly_uint64 block_size = MIN (isize, regsize); + /* It is invalid for the target to pick a register size for a mode + that isn't ordered wrt to the size of that mode. */ + poly_uint64 block_size = ordered_min (isize, regsize); unsigned int start_reg; poly_uint64 offset_within_reg; if (!can_div_trunc_p (offset, block_size, &start_reg, &offset_within_reg) @@ -1548,39 +1561,43 @@ maybe_set_max_label_num (rtx_code_label rtx gen_lowpart_common (machine_mode mode, rtx x) { - int msize = GET_MODE_SIZE (mode); - int xsize; + poly_uint64 msize = GET_MODE_SIZE (mode); machine_mode innermode; /* Unfortunately, this routine doesn't take a parameter for the mode of X, so we have to make one up. Yuk. */ innermode = GET_MODE (x); if (CONST_INT_P (x) - && msize * BITS_PER_UNIT <= HOST_BITS_PER_WIDE_INT) + && must_le (msize * BITS_PER_UNIT, + (unsigned HOST_WIDE_INT) HOST_BITS_PER_WIDE_INT)) innermode = int_mode_for_size (HOST_BITS_PER_WIDE_INT, 0).require (); else if (innermode == VOIDmode) innermode = int_mode_for_size (HOST_BITS_PER_DOUBLE_INT, 0).require (); - xsize = GET_MODE_SIZE (innermode); - gcc_assert (innermode != VOIDmode && innermode != BLKmode); if (innermode == mode) return x; + /* The size of the outer and inner modes must be ordered. */ + poly_uint64 xsize = GET_MODE_SIZE (innermode); + if (!ordered_p (msize, xsize)) + return 0; + if (SCALAR_FLOAT_MODE_P (mode)) { /* Don't allow paradoxical FLOAT_MODE subregs. */ - if (msize > xsize) + if (may_gt (msize, xsize)) return 0; } else { /* MODE must occupy no more of the underlying registers than X. */ - unsigned int regsize = REGMODE_NATURAL_SIZE (innermode); - unsigned int mregs = CEIL (msize, regsize); - unsigned int xregs = CEIL (xsize, regsize); - if (mregs > xregs) + poly_uint64 regsize = REGMODE_NATURAL_SIZE (innermode); + unsigned int mregs, xregs; + if (!can_div_away_from_zero_p (msize, regsize, &mregs) + || !can_div_away_from_zero_p (xsize, regsize, &xregs) + || mregs > xregs) return 0; } Index: gcc/reginfo.c =================================================================== --- gcc/reginfo.c 2017-10-23 17:23:00.293367701 +0100 +++ gcc/reginfo.c 2017-10-23 17:25:30.704136008 +0100 @@ -1294,10 +1294,14 @@ record_subregs_of_mode (rtx subreg, bool subregs will be invalid. This relies on the fact that we've already been passed - SUBREG with PARTIAL_DEF set to false. */ - unsigned int size = MAX (REGMODE_NATURAL_SIZE (shape.inner_mode), - GET_MODE_SIZE (shape.outer_mode)); - gcc_checking_assert (size < GET_MODE_SIZE (shape.inner_mode)); + SUBREG with PARTIAL_DEF set to false. + + The size of the outer mode must ordered wrt the size of the + inner mode's registers, since otherwise we wouldn't know at + compile time how many registers the outer mode occupies. */ + poly_uint64 size = MAX (REGMODE_NATURAL_SIZE (shape.inner_mode), + GET_MODE_SIZE (shape.outer_mode)); + gcc_checking_assert (must_lt (size, GET_MODE_SIZE (shape.inner_mode))); if (must_ge (shape.offset, size)) shape.offset -= size; else Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c 2017-10-23 17:23:00.293367701 +0100 +++ gcc/rtlanal.c 2017-10-23 17:25:30.705135972 +0100 @@ -1395,13 +1395,15 @@ modified_in_p (const_rtx x, const_rtx in bool read_modify_subreg_p (const_rtx x) { - unsigned int isize, osize; if (GET_CODE (x) != SUBREG) 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))); + poly_uint64 isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))); + poly_uint64 osize = GET_MODE_SIZE (GET_MODE (x)); + poly_uint64 regsize = REGMODE_NATURAL_SIZE (GET_MODE (SUBREG_REG (x))); + /* The inner and outer modes of a subreg must be ordered, so that we + can tell whether they're paradoxical or partial. */ + gcc_checking_assert (ordered_p (isize, osize)); + return (may_gt (isize, osize) && may_gt (isize, regsize)); } /* Helper function for set_of. */