From patchwork Fri May 22 06:34:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 475309 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D240C1402B9 for ; Fri, 22 May 2015 16:34:38 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=UirmZvj6; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=hbvYN8yZXWP2ymLYAqx2FC5gAM+S051P7xYBtcPoRU3d6fCaB+o0z M0PbnM72tILHNcgIUa7miWWwCVgSyTXOOSDFkx1rOo/iunADoMzyftM0b0wjLcbL wSRYXWbP2u/Rk1v12jfh4p2zOsb0GaH49Frcigfz6rL4u2wPTzySU4= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=KdLzpJXprLbu6waXMhvARXYqWT4=; b=UirmZvj6nvKXO4mjBgAh VPIuJEfAdy2rrkcZAxjFUEO8Pc83wLZIXd/JhQqVG9enYsYEqZ2/uxU6nmawcj3e q84wUuZokNHXUJPkSY66NrjmiegDU42iySuhz5nk5+y6MdFDDb333EOrDmfK8vgr BIebrak/ihOY0OWHu9fNQ0w= Received: (qmail 99300 invoked by alias); 22 May 2015 06:34:30 -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 99286 invoked by uid 89); 22 May 2015 06:34:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-pa0-f44.google.com Received: from mail-pa0-f44.google.com (HELO mail-pa0-f44.google.com) (209.85.220.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 22 May 2015 06:34:27 +0000 Received: by padbw4 with SMTP id bw4so11806791pad.0 for ; Thu, 21 May 2015 23:34:25 -0700 (PDT) X-Received: by 10.66.159.68 with SMTP id xa4mr12863926pab.105.1432276465720; Thu, 21 May 2015 23:34:25 -0700 (PDT) Received: from bubble.grove.modra.org (CPE-58-160-155-134.oycza5.sa.bigpond.net.au. [58.160.155.134]) by mx.google.com with ESMTPSA id im6sm971395pbc.72.2015.05.21.23.34.24 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 21 May 2015 23:34:24 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id CA7F9EA0074; Fri, 22 May 2015 16:04:19 +0930 (ACST) Date: Fri, 22 May 2015 16:04:19 +0930 From: Alan Modra To: gcc-patches@gcc.gnu.org Subject: [PATCH] Combine related fail of gcc.target/powerpc/ti_math1.c Message-ID: <20150522063419.GO6140@bubble.grove.modra.org> Mail-Followup-To: gcc-patches@gcc.gnu.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes This patch fixes FAIL: gcc.target/powerpc/ti_math1.c scan-assembler-times adde 1 a failure caused by combine simplifying this i2src (plus:DI (plus:DI (reg:DI 165 [ val+8 ]) (reg:DI 169 [+8 ])) (reg:DI 76 ca)) to this (plus:DI (plus:DI (reg:DI 76 ca) (reg:DI 165 [ val+8 ])) (reg:DI 169 [+8 ])) which no longer matches rs6000.md adddi3_carry_in_internal. See https://gcc.gnu.org/ml/gcc/2015-05/msg00206.html for related discussion. Bootstrapped and regression tested powerpc64le-linux, powerpc64-linux and x86_64-linux. OK to apply mainline? * rtlanal.c (commutative_operand_precedence): Correct comments. * simplify-rtx.c (simplify_plus_minus_op_data_cmp): Delete forward declaration. Return an int. Distinguish REG,REG return from others. (struct simplify_plus_minus_op_data): Make local to function. (simplify_plus_minus): Rename canonicalized to not_canonical. Don't set not_canonical if merely sorting registers. Avoid packing ops if nothing changes. White space fixes. Some notes: Renaming canonicalized to not_canonical better reflects its usage. At the time the var is set, the expression hasn't been canonicalized. diff -w shown to exclude the whitespace fixes. Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c (revision 223463) +++ gcc/rtlanal.c (working copy) @@ -3140,10 +3140,9 @@ regno_use_in (unsigned int regno, rtx x) } /* Return a value indicating whether OP, an operand of a commutative - operation, is preferred as the first or second operand. The higher - the value, the stronger the preference for being the first operand. - We use negative values to indicate a preference for the first operand - and positive values for the second operand. */ + operation, is preferred as the first or second operand. The more + positive the value, the stronger the preference for being the first + operand. */ int commutative_operand_precedence (rtx op) @@ -3150,7 +3149,7 @@ commutative_operand_precedence (rtx op) { enum rtx_code code = GET_CODE (op); - /* Constants always come the second operand. Prefer "nice" constants. */ + /* Constants always become the second operand. Prefer "nice" constants. */ if (code == CONST_INT) return -8; if (code == CONST_WIDE_INT) Index: gcc/simplify-rtx.c =================================================================== --- gcc/simplify-rtx.c (revision 223463) +++ gcc/simplify-rtx.c (working copy) @@ -71,7 +71,6 @@ along with GCC; see the file COPYING3. If not see static rtx neg_const_int (machine_mode, const_rtx); static bool plus_minus_operand_p (const_rtx); -static bool simplify_plus_minus_op_data_cmp (rtx, rtx); static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx); static rtx simplify_immed_subreg (machine_mode, rtx, machine_mode, unsigned int); @@ -4064,20 +4063,10 @@ simplify_const_binary_operation (enum rtx_code cod -/* Simplify a PLUS or MINUS, at least one of whose operands may be another - PLUS or MINUS. +/* Return a positive integer if X should sort after Y. The value + returned is 1 if and only if X and Y are both regs. */ - Rather than test for specific case, we do this by a brute-force method - and do all possible simplifications until no more changes occur. Then - we rebuild the operation. */ - -struct simplify_plus_minus_op_data -{ - rtx op; - short neg; -}; - -static bool +static int simplify_plus_minus_op_data_cmp (rtx x, rtx y) { int result; @@ -4085,23 +4074,36 @@ simplify_plus_minus_op_data_cmp (rtx x, rtx y) result = (commutative_operand_precedence (y) - commutative_operand_precedence (x)); if (result) - return result > 0; + return result + result; /* Group together equal REGs to do more simplification. */ if (REG_P (x) && REG_P (y)) return REGNO (x) > REGNO (y); - else - return false; + + return 0; } +/* Simplify and canonicalize a PLUS or MINUS, at least one of whose + operands may be another PLUS or MINUS. + + Rather than test for specific case, we do this by a brute-force method + and do all possible simplifications until no more changes occur. Then + we rebuild the operation. + + May return NULL_RTX when no changes were made. */ + static rtx simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, rtx op1) { - struct simplify_plus_minus_op_data ops[16]; + struct simplify_plus_minus_op_data + { + rtx op; + short neg; + } ops[16]; rtx result, tem; int n_ops = 2; - int changed, n_constants, canonicalized = 0; + int changed, n_constants, not_canonical = 0; int i, j; memset (ops, 0, sizeof ops); @@ -4139,7 +4141,18 @@ simplify_plus_minus (enum rtx_code code, machine_m ops[i].op = XEXP (this_op, 0); changed = 1; - canonicalized |= this_neg || i != n_ops - 2; + /* If this operand was negated then we will potentially + canonicalize the expression. Similarly if we don't + place the operands adjacent we're re-ordering the + expression and thus might be performing a + canonicalization. Ignore register re-ordering. + ??? It might be better to shuffle the ops array here, + but then (plus (plus (A, B), plus (C, D))) wouldn't + be seen as non-canonical. */ + if (this_neg + || (i != n_ops - 2 + && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op)))) + not_canonical = 1; break; case NEG: @@ -4146,7 +4159,7 @@ simplify_plus_minus (enum rtx_code code, machine_m ops[i].op = XEXP (this_op, 0); ops[i].neg = ! this_neg; changed = 1; - canonicalized = 1; + not_canonical = 1; break; case CONST: @@ -4160,7 +4173,7 @@ simplify_plus_minus (enum rtx_code code, machine_m ops[n_ops].neg = this_neg; n_ops++; changed = 1; - canonicalized = 1; + not_canonical = 1; } break; @@ -4173,7 +4186,7 @@ simplify_plus_minus (enum rtx_code code, machine_m ops[i].op = XEXP (this_op, 0); ops[i].neg = !this_neg; changed = 1; - canonicalized = 1; + not_canonical = 1; } break; @@ -4184,7 +4197,7 @@ simplify_plus_minus (enum rtx_code code, machine_m ops[i].op = neg_const_int (mode, this_op); ops[i].neg = 0; changed = 1; - canonicalized = 1; + not_canonical = 1; } break; @@ -4196,7 +4209,7 @@ simplify_plus_minus (enum rtx_code code, machine_m while (changed); if (n_constants > 1) - canonicalized = 1; + not_canonical = 1; gcc_assert (n_ops >= 2); @@ -4228,21 +4241,27 @@ simplify_plus_minus (enum rtx_code code, machine_m } /* Now simplify each pair of operands until nothing changes. */ - do + while (1) { /* Insertion sort is good enough for a small array. */ for (i = 1; i < n_ops; i++) { struct simplify_plus_minus_op_data save; + int cmp; + j = i - 1; - if (!simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op)) + cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op); + if (cmp <= 0) continue; + /* Just swapping registers doesn't count as canonicalization. */ + if (cmp != 1) + not_canonical = 1; - canonicalized = 1; save = ops[i]; do ops[j + 1] = ops[j]; - while (j-- && simplify_plus_minus_op_data_cmp (ops[j].op, save.op)); + while (j-- + && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0); ops[j + 1] = save; } @@ -4306,14 +4325,13 @@ simplify_plus_minus (enum rtx_code code, machine_m ops[i].neg = lneg; ops[j].op = NULL_RTX; changed = 1; - canonicalized = 1; + not_canonical = 1; } } } - /* If nothing changed, fail. */ - if (!canonicalized) - return NULL_RTX; + if (!changed) + break; /* Pack all the operands to the lower-numbered entries. */ for (i = 0, j = 0; j < n_ops; j++) @@ -4324,8 +4342,11 @@ simplify_plus_minus (enum rtx_code code, machine_m } n_ops = i; } - while (changed); + /* If nothing changed, fail. */ + if (!not_canonical) + return NULL_RTX; + /* Create (minus -C X) instead of (neg (const (plus X C))). */ if (n_ops == 2 && CONST_INT_P (ops[1].op)