From patchwork Sat Jun 25 02:22:05 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 101932 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]) by ozlabs.org (Postfix) with SMTP id B76AAB6FB2 for ; Sat, 25 Jun 2011 12:22:34 +1000 (EST) Received: (qmail 22985 invoked by alias); 25 Jun 2011 02:22:31 -0000 Received: (qmail 22975 invoked by uid 22791); 25 Jun 2011 02:22:30 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 25 Jun 2011 02:22:07 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5P2M6K1007688 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 24 Jun 2011 22:22:06 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5P2M6fu002792 for ; Fri, 24 Jun 2011 22:22:06 -0400 Received: from Mair.local (vpn-11-104.rdu.redhat.com [10.11.11.104]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p5P2M5k7019391 for ; Fri, 24 Jun 2011 22:22:05 -0400 Message-ID: <4E05464D.7000704@redhat.com> Date: Fri, 24 Jun 2011 22:22:05 -0400 From: Vladimir Makarov User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 To: GCC Patches Subject: [lra] patch to fix a x86 wrong code generation X-IsSubscribed: yes 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 The following patch solves a bug which results in a wrong code generation of Maeno's algorithm of matrix multiplications on x86. The patch was successfully bootstrapped on x86, ppc64, ia64. 2011-06-24 Vladimir Makarov * lra-constraints.c (extract_loc_address_regs): Add an argument. Don't process the reg as an index reg on the top address level when it is added to the symbol. (extract_address_regs): Pass new argument to extract_loc_address_regs. Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 175386) +++ lra-constraints.c (working copy) @@ -383,8 +383,8 @@ ok_for_base_p_nonstrict (rtx reg, enum m return ok_for_base_p_1 (regno, mode, outer_code, index_code); } -/* Process address part with location *LOC to extract address - characteristics. +/* Process address part (or all address if TOP_P) with location *LOC + to extract address characteristics. If CONTEXT_P is false, we are looking at the base part of an address, otherwise we are looking at the index part. @@ -393,7 +393,7 @@ ok_for_base_p_nonstrict (rtx reg, enum m give the context that the rtx appears in; MODIFY_P if *LOC is modified. */ static void -extract_loc_address_regs (enum machine_mode mode, +extract_loc_address_regs (bool top_p, enum machine_mode mode, rtx *loc, bool context_p, enum rtx_code outer_code, enum rtx_code index_code, bool modify_p, struct address *ad) @@ -447,8 +447,8 @@ extract_loc_address_regs (enum machine_m must be in the first operand. */ if (MAX_REGS_PER_ADDRESS == 1) { - extract_loc_address_regs (mode, arg0_loc, false, PLUS, code1, - modify_p, ad); + extract_loc_address_regs (false, mode, arg0_loc, false, PLUS, + code1, modify_p, ad); gcc_assert (CONSTANT_P (arg1)); /* It should be a displacement. */ ad->disp_loc = arg1_loc; } @@ -458,11 +458,11 @@ extract_loc_address_regs (enum machine_m addresses are in canonical form. */ else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH)) { - extract_loc_address_regs (mode, arg0_loc, false, PLUS, code1, - modify_p, ad); + extract_loc_address_regs (false, mode, arg0_loc, false, PLUS, + code1, modify_p, ad); if (! CONSTANT_P (arg1)) - extract_loc_address_regs (mode, arg1_loc, true, PLUS, code0, - modify_p, ad); + extract_loc_address_regs (false, mode, arg1_loc, true, PLUS, + code0, modify_p, ad); else ad->disp_loc = arg1_loc; } @@ -471,15 +471,17 @@ extract_loc_address_regs (enum machine_m change what class the first operand must be. */ else if (code1 == CONST_INT || code1 == CONST_DOUBLE) { - extract_loc_address_regs (mode, arg0_loc, context_p, PLUS, code1, - modify_p, ad); + extract_loc_address_regs (false, mode, arg0_loc, context_p, PLUS, + code1, modify_p, ad); ad->disp_loc = arg1_loc; } /* If the second operand is a symbolic constant, the first - operand must be an index register. */ + operand must be an index register but only if this part is + all the address. */ else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF) { - extract_loc_address_regs (mode, arg0_loc, true, PLUS, code1, + extract_loc_address_regs (false, mode, arg0_loc, + top_p ? true : context_p, PLUS, code1, modify_p, ad); ad->disp_loc = arg1_loc; } @@ -493,9 +495,9 @@ extract_loc_address_regs (enum machine_m || ok_for_index_p_nonstrict (arg0))) { extract_loc_address_regs - (mode, arg0_loc, ! base_ok_p, PLUS, REG, modify_p, ad); + (false, mode, arg0_loc, ! base_ok_p, PLUS, REG, modify_p, ad); extract_loc_address_regs - (mode, arg1_loc, base_ok_p, PLUS, REG, modify_p, ad); + (false, mode, arg1_loc, base_ok_p, PLUS, REG, modify_p, ad); } else if (code0 == REG && code1 == REG && REGNO (arg1) < FIRST_PSEUDO_REGISTER @@ -504,38 +506,38 @@ extract_loc_address_regs (enum machine_m || ok_for_index_p_nonstrict (arg1))) { extract_loc_address_regs - (mode, arg0_loc, base_ok_p, PLUS, REG, modify_p, ad); + (false, mode, arg0_loc, base_ok_p, PLUS, REG, modify_p, ad); extract_loc_address_regs - (mode, arg1_loc, ! base_ok_p, PLUS, REG, modify_p, ad); + (false, mode, arg1_loc, ! base_ok_p, PLUS, REG, modify_p, ad); } /* If one operand is known to be a pointer, it must be the base with the other operand the index. Likewise if the other operand is a MULT. */ else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT) { - extract_loc_address_regs (mode, arg0_loc, false, PLUS, code1, - modify_p, ad); + extract_loc_address_regs (false, mode, arg0_loc, false, PLUS, + code1, modify_p, ad); if (code1 == MULT) ad->index_loc = arg1_loc; - extract_loc_address_regs (mode, arg1_loc, true, PLUS, code0, + extract_loc_address_regs (false, mode, arg1_loc, true, PLUS, code0, modify_p, ad); } else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT) { - extract_loc_address_regs (mode, arg0_loc, true, PLUS, code1, + extract_loc_address_regs (false, mode, arg0_loc, true, PLUS, code1, modify_p, ad); if (code1 == MULT) ad->index_loc = arg0_loc; - extract_loc_address_regs (mode, arg1_loc, false, PLUS, code0, - modify_p, ad); + extract_loc_address_regs (false, mode, arg1_loc, false, PLUS, + code0, modify_p, ad); } /* Otherwise, count equal chances that each might be a base or index register. This case should be rare. */ else { - extract_loc_address_regs (mode, arg0_loc, false, PLUS, code1, - modify_p, ad); - extract_loc_address_regs (mode, arg1_loc, true, PLUS, code0, + extract_loc_address_regs (false, mode, arg0_loc, false, PLUS, + code1, modify_p, ad); + extract_loc_address_regs (false, mode, arg1_loc, true, PLUS, code0, modify_p, ad); } } @@ -546,22 +548,22 @@ extract_loc_address_regs (enum machine_m up in the wrong place. */ case POST_MODIFY: case PRE_MODIFY: - extract_loc_address_regs (mode, &XEXP (x, 0), false, code, + extract_loc_address_regs (false, mode, &XEXP (x, 0), false, code, GET_CODE (XEXP (XEXP (x, 1), 1)), true, ad); gcc_assert (rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))); ad->base_reg_loc2 = &XEXP (XEXP (x, 1), 0); if (REG_P (XEXP (XEXP (x, 1), 1))) - extract_loc_address_regs (mode, &XEXP (XEXP (x, 1), 1), true, code, - REG, modify_p, ad); + extract_loc_address_regs (false, mode, &XEXP (XEXP (x, 1), 1), true, + code, REG, modify_p, ad); break; case POST_INC: case PRE_INC: case POST_DEC: case PRE_DEC: - extract_loc_address_regs (mode, &XEXP (x, 0), false, code, SCRATCH, - true, ad); + extract_loc_address_regs (false, mode, &XEXP (x, 0), false, code, + SCRATCH, true, ad); break; case REG: @@ -583,7 +585,7 @@ extract_loc_address_regs (enum machine_m for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) if (fmt[i] == 'e') - extract_loc_address_regs (mode, &XEXP (x, i), context_p, + extract_loc_address_regs (false, mode, &XEXP (x, i), context_p, code, SCRATCH, modify_p, ad); } } @@ -596,15 +598,15 @@ extract_loc_address_regs (enum machine_m MEM_MODE should be VOIDmode. */ static void extract_address_regs (enum machine_mode mem_mode, - rtx *loc, enum rtx_code outer_code, struct address *ad) + rtx *loc, enum rtx_code outer_code, struct address *ad) { ad->base_reg_loc = ad->base_reg_loc2 = ad->index_reg_loc = ad->index_loc = ad->disp_loc = NULL; ad->base_outer_code = SCRATCH; ad->index_code = SCRATCH; ad->base_modify_p = false; - extract_loc_address_regs (mem_mode, loc, false, outer_code, SCRATCH, - false, ad); + extract_loc_address_regs (true, mem_mode, loc, false, outer_code, SCRATCH, + false, ad); if (ad->index_loc == NULL) /* SUBREG ??? */ ad->index_loc = ad->index_reg_loc;