From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23508 invoked by alias); 8 Apr 2003 17:47:50 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 23497 invoked from network); 8 Apr 2003 17:47:49 -0000 Received: from unknown (HELO mail.libertysurf.net) (213.36.80.91) by sources.redhat.com with SMTP; 8 Apr 2003 17:47:49 -0000 Received: from localhost.localdomain (212.83.191.94) by mail.libertysurf.net (6.5.026) id 3E8A4CE900129D42; Tue, 8 Apr 2003 19:47:45 +0200 From: Eric Botcazou To: Jan Hubicka Subject: Reload bug Date: Tue, 08 Apr 2003 18:52:00 -0000 User-Agent: KMail/1.4.3 Cc: gcc@gcc.gnu.org MIME-Version: 1.0 Message-Id: <200304081937.16859.ebotcazou@libertysurf.fr> Content-Type: Multipart/Mixed; boundary="------------Boundary-00=_CDD1FAUGYRGOC7EUJ856" X-SW-Source: 2003-04/txt/msg00324.txt.bz2 --------------Boundary-00=_CDD1FAUGYRGOC7EUJ856 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Content-length: 1766 Hello Jan, I've narrowed down the bug reported as PR optimization/10233, a regression from GCC 3.2 present on the 3.2 branch since 3.2.1 (but latent on all active branches), to this patch Thu Oct 17 17:14:07 CEST 2002 Jan Hubicka PR opt/7630 * reload.c (reload_inner_reg_of_subreg): New argument output; (push_reload): Update call. We are trying to reload (subreg:SI (reg/v:DI 29 rmm0 [68]) 4) as the 'in' argument of push_reload. Before your patch, the compiler correctly detected that the whole register needs to be reloaded because we can't access the high part of MMX regs. But now reload_inner_reg_of_subreg returns 0 for this subreg because its return value depends upon the context: if we pass it an 'in' argument, it will not check the following condition /* If the outer part is a word or smaller, INNER larger than a word and the number of regs for INNER is not the same as the number of words in INNER, then INNER will need reloading. */ which happens to apply to this subreg. Then the subsequent logic is fooled and we end up reloading (reg/v:SI 29 emm0) The rationale for the patch is there: http://gcc.gnu.org/ml/gcc-patches/2002-10/msg00628.html The last sentence: "However it is completely irrelevant for input operand in all cases - we always can move just the small part of register and use it directly, so I've added new operand to bypass this logic in the input operand case." Did you intend to disable the condition for low parts only? (there appears to be no testcase associated with the patch so it's hard to tell). If so, does the following patch fit your needs? -- Eric Botcazou * reload.c (reload_inner_reg_of_subreg): Require reloading for non-low parts of input operands. --------------Boundary-00=_CDD1FAUGYRGOC7EUJ856 Content-Type: text/x-diff; charset="iso-8859-1"; name="pr10233.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pr10233.diff" Content-length: 1007 Index: reload.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/reload.c,v retrieving revision 1.178.2.4.2.6 diff -u -p -r1.178.2.4.2.6 reload.c --- reload.c 29 Mar 2003 19:30:39 -0000 1.178.2.4.2.6 +++ reload.c 8 Apr 2003 17:40:34 -0000 @@ -826,10 +826,12 @@ reload_inner_reg_of_subreg (x, mode, out word and the number of regs for INNER is not the same as the number of words in INNER, then INNER will need reloading. */ return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD - && output && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD) - != HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner)))); + != HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))) + /* This is not necessary for low parts of input operands + because we can always access them directly. */ + && (output || ! subreg_lowpart_p (x))); } /* Record one reload that needs to be performed. --------------Boundary-00=_CDD1FAUGYRGOC7EUJ856--