From patchwork Thu Jul 13 08:51:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 107622 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp1934453qge; Thu, 13 Jul 2017 01:52:46 -0700 (PDT) X-Received: by 10.98.15.220 with SMTP id 89mr60839740pfp.203.1499935965937; Thu, 13 Jul 2017 01:52:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499935965; cv=none; d=google.com; s=arc-20160816; b=ndF/JFYAImDRF7qNO15Typf2siZ0miBfhWxfwQvbtOE/ATD4EoRjsCdzRqSRapIVs8 V+pieYlv/4FeI1OqqHtl57P+b4lbSAe/cLdhSLoWdxjmjSc79TPW4dQ6XmsKdVHJ1twk ZooBkrt01t/uAHaGRxruLgMQlGV0mak2Kgtc/TlqW3xwB/BVlttTIcZSByel0SfpSCSP PIAOYXI+wpZmqaUUzma9SZWCMlwINuTS68ZEb6YOwdwC6TkhyGbQlOcP0XV8Rd0cGTDJ 83z6nFQ98jO3MWlczI+0pu/Kl/FAjoxamdRJz9PsGbJOXR2EmP6GtyOGqMH7MDm5GUvV 0v1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:in-reply-to:date:references :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=cUC2q/pdGBOL8EBn4u2ccjyIaAXdcgC3yp2UcwuajAE=; b=tDV3DsEaGkZpG4DiCHvgjOxVJ7KU3xtJt4RhnE83NpsCWfCdhpCAH6e0773IATaj8t 4mn2lif5h8tmcdtZMOWUEsm0/dwZ6d2DviQsnZjbI2fsrGGZFelpWujdm0Be+OuZ5riG ywsUyFWs1cgnGmJG/kJAC1WmImMpHBx/QYDtpZcArDg2X4kYItPAxaa9UGWjuLkKc32I Wq7pFq20N36vY42dt31Cs4k0DOQUd/0isoynn+PSjfFwVjtZ2cp+ng+GpSyMaLXLgNtm cmkmT1y1d/IYXKo8pMnHrZQy0TxUeZj3xcA3NO1GSfTgZ6xrQt83ZFZlbDngyw5UehdT iJlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.b=iu11lZ4t; spf=pass (google.com: domain of gcc-patches-return-458027-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-458027-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 v66si3816956pfv.303.2017.07.13.01.52.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Jul 2017 01:52:45 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-458027-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.b=iu11lZ4t; spf=pass (google.com: domain of gcc-patches-return-458027-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-458027-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:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=x1MGWz2SckEODSdegW0dZvlrzsoKQ fsTu2jw7hjT83O2KbhFqkj/kYKnJcxK+UrGX1JiipIfwIyoFGI0NkRghXcKHb3W3 iCTj7mr4Ifj4NxpUYqOccdsUfG4aya8wzhoVZ4rsyeDCRy4tWq/wnVLCjmvU35LF s2+fKdBsCJ87Ps= 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:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=yxBT4kmINXf7sZEKM5EGKkSveM8=; b=iu1 1lZ4toAGkBG8pgv4gEps1OEdcCjt1TfmB7LeCIn4XidXg2TiDcLc+0dquUULMYy7 aa4SC7A9HfpEfIrHjbZqnnihAZkTjWB5Mk9L1xSWyfd77j0pKeW5eHRoQDGpFKxb gCtlb+6IopDNoVpGkr7paC5Moi+wc2nkME2d1cqo= Received: (qmail 18006 invoked by alias); 13 Jul 2017 08:51:41 -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 17509 invoked by uid 89); 13 Jul 2017 08:51:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=biv X-HELO: mail-wm0-f52.google.com Received: from mail-wm0-f52.google.com (HELO mail-wm0-f52.google.com) (74.125.82.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 13 Jul 2017 08:51:31 +0000 Received: by mail-wm0-f52.google.com with SMTP id 62so16667353wmw.1 for ; Thu, 13 Jul 2017 01:51:31 -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=cUC2q/pdGBOL8EBn4u2ccjyIaAXdcgC3yp2UcwuajAE=; b=QpPZY04ReXkKcNOMz48Fwe0WjwJbt9GylIhS2OVAaNvvAKLu819OaW2vZGqk/I/jKz YMHMzb7hWAy7WBYg4v3IuxgMoQAb6/LLQ7/bpqU0a84TxFGsUTMlbCDpCAClr+CRFiRl l7VEFGkkcXmdwbj6doWDrSNSp4BLVoEQ3cuwSPNOSEdMVMrRgBDU+4S9rOYAjyYFoU4y q7L9tknvfHXcLCZXj79C8Ii2LEc9mjJwi2uiCMKil7ltsgMVd17ONDh4eUDmBnSZN69v XGftKXWEbTNDDs3/1HexSbgrrGDUKmEIkFxa9L4pG7zEfmk9HJmlSnkpx/tORO+93ly6 mspA== X-Gm-Message-State: AIVw1134kqdlm0T5Th5SloxhuryMMTeN7T9T9zwAYh1JnC5rbxwGqfSP mf3m/nHw4ENFtaXRAchq+w== X-Received: by 10.28.146.208 with SMTP id u199mr1147699wmd.6.1499935889093; Thu, 13 Jul 2017 01:51:29 -0700 (PDT) Received: from localhost (92.40.249.184.threembb.co.uk. [92.40.249.184]) by smtp.gmail.com with ESMTPSA id y5sm3932953wrd.52.2017.07.13.01.51.27 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 13 Jul 2017 01:51:28 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [36/77] Use scalar_int_mode in the RTL iv routines References: <8760ewohsv.fsf@linaro.org> Date: Thu, 13 Jul 2017 09:51:27 +0100 In-Reply-To: <8760ewohsv.fsf@linaro.org> (Richard Sandiford's message of "Thu, 13 Jul 2017 09:35:44 +0100") Message-ID: <87tw2ghg8g.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch changes the iv modes in rtx_iv from machine_mode to scalar_int_mode. It also passes the mode of the iv down to subroutines; this avoids the previous situation in which the mode information was sometimes lost and had to be added by the caller on return. Some routines already took a mode argument, but the patch tries to standardise on passing it immediately before the argument it describes. gcc/ 2017-07-13 Richard Sandiford Alan Hayward David Sherwood * cfgloop.h (rtx_iv): Change type of extend_mode and mode to scalar_int_mode. (niter_desc): Likewise mode. (iv_analyze): Add a mode parameter. (biv_p): Likewise. (iv_analyze_expr): Pass the mode paraeter before the rtx it describes and change its type to scalar_int_mode. * loop-iv.c: Update commentary at head of file. (iv_constant): Pass the mode paraeter before the rtx it describes and change its type to scalar_int_mode. Remove VOIDmode handling. (iv_subreg): Change the type of the mode parameter to scalar_int_mode. (iv_extend): Likewise. (shorten_into_mode): Likewise. (iv_add): Use scalar_int_mode. (iv_mult): Likewise. (iv_shift): Likewise. (canonicalize_iv_subregs): Likewise. (get_biv_step_1): Pass the outer_mode parameter before the rtx it describes and change its mode to scalar_int_mode. Also change the type of the returned inner_mode to scalar_int_mode. (get_biv_step): Likewise, turning outer_mode from a pointer into a direct parameter. Update call to get_biv_step_1. (iv_analyze_biv): Add an outer_mode parameter. Update calls to iv_constant and get_biv_step. (iv_analyze_expr): Pass the mode parameter before the rtx it describes and change its type to scalar_int_mode. Don't initialise iv->mode to VOIDmode and remove later checks for its still being VOIDmode. Update calls to iv_analyze_op and iv_analyze_expr. Check is_a when changing the mode under consideration. (iv_analyze_def): Ignore registers that don't have a scalar_int_mode. Update call to iv_analyze_expr. (iv_analyze_op): Add a mode parameter. Reject subregs whose inner register is not also a scalar_int_mode. Update call to iv_analyze_biv. (iv_analyze): Add a mode parameter. Update call to iv_analyze_op. (biv_p): Add a mode parameter. Update call to iv_analyze_biv. (iv_number_of_iterations): Use is_a instead of separate mode class checks. Update calls to iv_analyze. Remove fix-up of VOIDmodes after iv_analyze_biv. * loop-unroll.c (analyze_iv_to_split_insn): Reject registers that don't have a scalar_int_mode. Update call to biv_p. Index: gcc/cfgloop.h =================================================================== --- gcc/cfgloop.h 2017-07-05 16:25:08.605609122 +0100 +++ gcc/cfgloop.h 2017-07-13 09:18:40.317672476 +0100 @@ -421,10 +421,10 @@ struct rtx_iv rtx delta, mult; /* The mode it is extended to. */ - machine_mode extend_mode; + scalar_int_mode extend_mode; /* The mode the variable iterates in. */ - machine_mode mode; + scalar_int_mode mode; /* Whether the first iteration needs to be handled specially. */ unsigned first_special : 1; @@ -465,19 +465,19 @@ struct GTY(()) niter_desc bool signed_p; /* The mode in that niter_expr should be computed. */ - machine_mode mode; + scalar_int_mode mode; /* The number of iterations of the loop. */ rtx niter_expr; }; extern void iv_analysis_loop_init (struct loop *); -extern bool iv_analyze (rtx_insn *, rtx, struct rtx_iv *); +extern bool iv_analyze (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *); extern bool iv_analyze_result (rtx_insn *, rtx, struct rtx_iv *); -extern bool iv_analyze_expr (rtx_insn *, rtx, machine_mode, +extern bool iv_analyze_expr (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *); extern rtx get_iv_value (struct rtx_iv *, rtx); -extern bool biv_p (rtx_insn *, rtx); +extern bool biv_p (rtx_insn *, scalar_int_mode, rtx); extern void find_simple_exit (struct loop *, struct niter_desc *); extern void iv_analysis_done (void); Index: gcc/loop-iv.c =================================================================== --- gcc/loop-iv.c 2017-07-13 09:18:35.049126549 +0100 +++ gcc/loop-iv.c 2017-07-13 09:18:40.317672476 +0100 @@ -35,16 +35,17 @@ Free Software Foundation; either version The available functions are: - iv_analyze (insn, reg, iv): Stores the description of the induction variable - corresponding to the use of register REG in INSN to IV. Returns true if - REG is an induction variable in INSN. false otherwise. - If use of REG is not found in INSN, following insns are scanned (so that - we may call this function on insn returned by get_condition). + iv_analyze (insn, mode, reg, iv): Stores the description of the induction + variable corresponding to the use of register REG in INSN to IV, given + that REG has mode MODE. Returns true if REG is an induction variable + in INSN. false otherwise. If a use of REG is not found in INSN, + the following insns are scanned (so that we may call this function + on insns returned by get_condition). iv_analyze_result (insn, def, iv): Stores to IV the description of the iv corresponding to DEF, which is a register defined in INSN. - iv_analyze_expr (insn, rhs, mode, iv): Stores to IV the description of iv + iv_analyze_expr (insn, mode, expr, iv): Stores to IV the description of iv corresponding to expression EXPR evaluated at INSN. All registers used bu - EXPR must also be used in INSN. + EXPR must also be used in INSN. MODE is the mode of EXPR. */ #include "config.h" @@ -133,7 +134,7 @@ biv_entry_hasher::equal (const biv_entry static hash_table *bivs; -static bool iv_analyze_op (rtx_insn *, rtx, struct rtx_iv *); +static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *); /* Return the RTX code corresponding to the IV extend code EXTEND. */ static inline enum rtx_code @@ -383,11 +384,8 @@ iv_get_reaching_def (rtx_insn *insn, rtx consistency with other iv manipulation functions that may fail). */ static bool -iv_constant (struct rtx_iv *iv, rtx cst, machine_mode mode) +iv_constant (struct rtx_iv *iv, scalar_int_mode mode, rtx cst) { - if (mode == VOIDmode) - mode = GET_MODE (cst); - iv->mode = mode; iv->base = cst; iv->step = const0_rtx; @@ -403,7 +401,7 @@ iv_constant (struct rtx_iv *iv, rtx cst, /* Evaluates application of subreg to MODE on IV. */ static bool -iv_subreg (struct rtx_iv *iv, machine_mode mode) +iv_subreg (struct rtx_iv *iv, scalar_int_mode mode) { /* If iv is invariant, just calculate the new value. */ if (iv->step == const0_rtx @@ -445,7 +443,7 @@ iv_subreg (struct rtx_iv *iv, machine_mo /* Evaluates application of EXTEND to MODE on IV. */ static bool -iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, machine_mode mode) +iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode) { /* If iv is invariant, just calculate the new value. */ if (iv->step == const0_rtx @@ -508,7 +506,7 @@ iv_neg (struct rtx_iv *iv) static bool iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op) { - machine_mode mode; + scalar_int_mode mode; rtx arg; /* Extend the constant to extend_mode of the other operand if necessary. */ @@ -578,7 +576,7 @@ iv_add (struct rtx_iv *iv0, struct rtx_i static bool iv_mult (struct rtx_iv *iv, rtx mby) { - machine_mode mode = iv->extend_mode; + scalar_int_mode mode = iv->extend_mode; if (GET_MODE (mby) != VOIDmode && GET_MODE (mby) != mode) @@ -603,7 +601,7 @@ iv_mult (struct rtx_iv *iv, rtx mby) static bool iv_shift (struct rtx_iv *iv, rtx mby) { - machine_mode mode = iv->extend_mode; + scalar_int_mode mode = iv->extend_mode; if (GET_MODE (mby) != VOIDmode && GET_MODE (mby) != mode) @@ -628,9 +626,9 @@ iv_shift (struct rtx_iv *iv, rtx mby) at get_biv_step. */ static bool -get_biv_step_1 (df_ref def, rtx reg, - rtx *inner_step, machine_mode *inner_mode, - enum iv_extend_code *extend, machine_mode outer_mode, +get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg, + rtx *inner_step, scalar_int_mode *inner_mode, + enum iv_extend_code *extend, rtx *outer_step) { rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX; @@ -732,8 +730,8 @@ get_biv_step_1 (df_ref def, rtx reg, *inner_mode = outer_mode; *outer_step = const0_rtx; } - else if (!get_biv_step_1 (next_def, reg, - inner_step, inner_mode, extend, outer_mode, + else if (!get_biv_step_1 (next_def, outer_mode, reg, + inner_step, inner_mode, extend, outer_step)) return false; @@ -793,19 +791,17 @@ get_biv_step_1 (df_ref def, rtx reg, LAST_DEF is the definition of REG that dominates loop latch. */ static bool -get_biv_step (df_ref last_def, rtx reg, rtx *inner_step, - machine_mode *inner_mode, enum iv_extend_code *extend, - machine_mode *outer_mode, rtx *outer_step) +get_biv_step (df_ref last_def, scalar_int_mode outer_mode, rtx reg, + rtx *inner_step, scalar_int_mode *inner_mode, + enum iv_extend_code *extend, rtx *outer_step) { - *outer_mode = GET_MODE (reg); - - if (!get_biv_step_1 (last_def, reg, - inner_step, inner_mode, extend, *outer_mode, + if (!get_biv_step_1 (last_def, outer_mode, reg, + inner_step, inner_mode, extend, outer_step)) return false; - gcc_assert ((*inner_mode == *outer_mode) != (*extend != IV_UNKNOWN_EXTEND)); - gcc_assert (*inner_mode != *outer_mode || *outer_step == const0_rtx); + gcc_assert ((*inner_mode == outer_mode) != (*extend != IV_UNKNOWN_EXTEND)); + gcc_assert (*inner_mode != outer_mode || *outer_step == const0_rtx); return true; } @@ -850,13 +846,13 @@ record_biv (rtx def, struct rtx_iv *iv) } /* Determines whether DEF is a biv and if so, stores its description - to *IV. */ + to *IV. OUTER_MODE is the mode of DEF. */ static bool -iv_analyze_biv (rtx def, struct rtx_iv *iv) +iv_analyze_biv (scalar_int_mode outer_mode, rtx def, struct rtx_iv *iv) { rtx inner_step, outer_step; - machine_mode inner_mode, outer_mode; + scalar_int_mode inner_mode; enum iv_extend_code extend; df_ref last_def; @@ -872,7 +868,7 @@ iv_analyze_biv (rtx def, struct rtx_iv * if (!CONSTANT_P (def)) return false; - return iv_constant (iv, def, VOIDmode); + return iv_constant (iv, outer_mode, def); } if (!latch_dominating_def (def, &last_def)) @@ -883,7 +879,7 @@ iv_analyze_biv (rtx def, struct rtx_iv * } if (!last_def) - return iv_constant (iv, def, VOIDmode); + return iv_constant (iv, outer_mode, def); if (analyzed_for_bivness_p (def, iv)) { @@ -892,8 +888,8 @@ iv_analyze_biv (rtx def, struct rtx_iv * return iv->base != NULL_RTX; } - if (!get_biv_step (last_def, def, &inner_step, &inner_mode, &extend, - &outer_mode, &outer_step)) + if (!get_biv_step (last_def, outer_mode, def, &inner_step, &inner_mode, + &extend, &outer_step)) { iv->base = NULL_RTX; goto end; @@ -930,16 +926,15 @@ iv_analyze_biv (rtx def, struct rtx_iv * The mode of the induction variable is MODE. */ bool -iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode, +iv_analyze_expr (rtx_insn *insn, scalar_int_mode mode, rtx rhs, struct rtx_iv *iv) { rtx mby = NULL_RTX; rtx op0 = NULL_RTX, op1 = NULL_RTX; struct rtx_iv iv0, iv1; enum rtx_code code = GET_CODE (rhs); - machine_mode omode = mode; + scalar_int_mode omode = mode; - iv->mode = VOIDmode; iv->base = NULL_RTX; iv->step = NULL_RTX; @@ -948,18 +943,7 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs if (CONSTANT_P (rhs) || REG_P (rhs) || code == SUBREG) - { - if (!iv_analyze_op (insn, rhs, iv)) - return false; - - if (iv->mode == VOIDmode) - { - iv->mode = mode; - iv->extend_mode = mode; - } - - return true; - } + return iv_analyze_op (insn, mode, rhs, iv); switch (code) { @@ -971,7 +955,9 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs case ZERO_EXTEND: case NEG: op0 = XEXP (rhs, 0); - omode = GET_MODE (op0); + /* We don't know how many bits there are in a sign-extended constant. */ + if (!is_a (GET_MODE (op0), &omode)) + return false; break; case PLUS: @@ -1001,11 +987,11 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs } if (op0 - && !iv_analyze_expr (insn, op0, omode, &iv0)) + && !iv_analyze_expr (insn, omode, op0, &iv0)) return false; if (op1 - && !iv_analyze_expr (insn, op1, omode, &iv1)) + && !iv_analyze_expr (insn, omode, op1, &iv1)) return false; switch (code) @@ -1075,11 +1061,11 @@ iv_analyze_def (df_ref def, struct rtx_i return iv->base != NULL_RTX; } - iv->mode = VOIDmode; iv->base = NULL_RTX; iv->step = NULL_RTX; - if (!REG_P (reg)) + scalar_int_mode mode; + if (!REG_P (reg) || !is_a (GET_MODE (reg), &mode)) return false; set = single_set (insn); @@ -1096,7 +1082,7 @@ iv_analyze_def (df_ref def, struct rtx_i else rhs = SET_SRC (set); - iv_analyze_expr (insn, rhs, GET_MODE (reg), iv); + iv_analyze_expr (insn, mode, rhs, iv); record_iv (def, iv); if (dump_file) @@ -1112,10 +1098,11 @@ iv_analyze_def (df_ref def, struct rtx_i return iv->base != NULL_RTX; } -/* Analyzes operand OP of INSN and stores the result to *IV. */ +/* Analyzes operand OP of INSN and stores the result to *IV. MODE is the + mode of OP. */ static bool -iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv) +iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, struct rtx_iv *iv) { df_ref def = NULL; enum iv_grd_result res; @@ -1132,13 +1119,15 @@ iv_analyze_op (rtx_insn *insn, rtx op, s res = GRD_INVARIANT; else if (GET_CODE (op) == SUBREG) { - if (!subreg_lowpart_p (op)) + scalar_int_mode inner_mode; + if (!subreg_lowpart_p (op) + || !is_a (GET_MODE (SUBREG_REG (op)), &inner_mode)) return false; - if (!iv_analyze_op (insn, SUBREG_REG (op), iv)) + if (!iv_analyze_op (insn, inner_mode, SUBREG_REG (op), iv)) return false; - return iv_subreg (iv, GET_MODE (op)); + return iv_subreg (iv, mode); } else { @@ -1153,7 +1142,7 @@ iv_analyze_op (rtx_insn *insn, rtx op, s if (res == GRD_INVARIANT) { - iv_constant (iv, op, VOIDmode); + iv_constant (iv, mode, op); if (dump_file) { @@ -1165,15 +1154,16 @@ iv_analyze_op (rtx_insn *insn, rtx op, s } if (res == GRD_MAYBE_BIV) - return iv_analyze_biv (op, iv); + return iv_analyze_biv (mode, op, iv); return iv_analyze_def (def, iv); } -/* Analyzes value VAL at INSN and stores the result to *IV. */ +/* Analyzes value VAL at INSN and stores the result to *IV. MODE is the + mode of VAL. */ bool -iv_analyze (rtx_insn *insn, rtx val, struct rtx_iv *iv) +iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, struct rtx_iv *iv) { rtx reg; @@ -1192,7 +1182,7 @@ iv_analyze (rtx_insn *insn, rtx val, str insn = NEXT_INSN (insn); } - return iv_analyze_op (insn, val, iv); + return iv_analyze_op (insn, mode, val, iv); } /* Analyzes definition of DEF in INSN and stores the result to IV. */ @@ -1210,11 +1200,13 @@ iv_analyze_result (rtx_insn *insn, rtx d } /* Checks whether definition of register REG in INSN is a basic induction - variable. IV analysis must have been initialized (via a call to + variable. MODE is the mode of REG. + + IV analysis must have been initialized (via a call to iv_analysis_loop_init) for this function to produce a result. */ bool -biv_p (rtx_insn *insn, rtx reg) +biv_p (rtx_insn *insn, scalar_int_mode mode, rtx reg) { struct rtx_iv iv; df_ref def, last_def; @@ -1229,7 +1221,7 @@ biv_p (rtx_insn *insn, rtx reg) if (last_def != def) return false; - if (!iv_analyze_biv (reg, &iv)) + if (!iv_analyze_biv (mode, reg, &iv)) return false; return iv.step != const0_rtx; @@ -2078,7 +2070,7 @@ simplify_using_initial_values (struct lo is SIGNED_P to DESC. */ static void -shorten_into_mode (struct rtx_iv *iv, machine_mode mode, +shorten_into_mode (struct rtx_iv *iv, scalar_int_mode mode, enum rtx_code cond, bool signed_p, struct niter_desc *desc) { rtx mmin, mmax, cond_over, cond_under; @@ -2140,7 +2132,7 @@ shorten_into_mode (struct rtx_iv *iv, ma canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code cond, struct niter_desc *desc) { - machine_mode comp_mode; + scalar_int_mode comp_mode; bool signed_p; /* If the ivs behave specially in the first iteration, or are @@ -2318,7 +2310,8 @@ iv_number_of_iterations (struct loop *lo struct rtx_iv iv0, iv1; rtx assumption, may_not_xform; enum rtx_code cond; - machine_mode mode, comp_mode; + machine_mode nonvoid_mode; + scalar_int_mode comp_mode; rtx mmin, mmax, mode_mmin, mode_mmax; uint64_t s, size, d, inv, max, up, down; int64_t inc, step_val; @@ -2343,28 +2336,24 @@ iv_number_of_iterations (struct loop *lo cond = GET_CODE (condition); gcc_assert (COMPARISON_P (condition)); - mode = GET_MODE (XEXP (condition, 0)); - if (mode == VOIDmode) - mode = GET_MODE (XEXP (condition, 1)); + nonvoid_mode = GET_MODE (XEXP (condition, 0)); + if (nonvoid_mode == VOIDmode) + nonvoid_mode = GET_MODE (XEXP (condition, 1)); /* The constant comparisons should be folded. */ - gcc_assert (mode != VOIDmode); + gcc_assert (nonvoid_mode != VOIDmode); /* We only handle integers or pointers. */ - if (GET_MODE_CLASS (mode) != MODE_INT - && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT) + scalar_int_mode mode; + if (!is_a (nonvoid_mode, &mode)) goto fail; op0 = XEXP (condition, 0); - if (!iv_analyze (insn, op0, &iv0)) + if (!iv_analyze (insn, mode, op0, &iv0)) goto fail; - if (iv0.extend_mode == VOIDmode) - iv0.mode = iv0.extend_mode = mode; op1 = XEXP (condition, 1); - if (!iv_analyze (insn, op1, &iv1)) + if (!iv_analyze (insn, mode, op1, &iv1)) goto fail; - if (iv1.extend_mode == VOIDmode) - iv1.mode = iv1.extend_mode = mode; if (GET_MODE_BITSIZE (iv0.extend_mode) > HOST_BITS_PER_WIDE_INT || GET_MODE_BITSIZE (iv1.extend_mode) > HOST_BITS_PER_WIDE_INT) Index: gcc/loop-unroll.c =================================================================== --- gcc/loop-unroll.c 2017-06-30 12:50:38.433653920 +0100 +++ gcc/loop-unroll.c 2017-07-13 09:18:40.318672392 +0100 @@ -1509,6 +1509,7 @@ analyze_iv_to_split_insn (rtx_insn *insn rtx set, dest; struct rtx_iv iv; struct iv_to_split *ivts; + scalar_int_mode mode; bool ok; /* For now we just split the basic induction variables. Later this may be @@ -1518,10 +1519,10 @@ analyze_iv_to_split_insn (rtx_insn *insn return NULL; dest = SET_DEST (set); - if (!REG_P (dest)) + if (!REG_P (dest) || !is_a (GET_MODE (dest), &mode)) return NULL; - if (!biv_p (insn, dest)) + if (!biv_p (insn, mode, dest)) return NULL; ok = iv_analyze_result (insn, dest, &iv);