From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24942 invoked by alias); 8 Dec 2001 00:00:58 -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 24914 invoked from network); 8 Dec 2001 00:00:57 -0000 Received: from unknown (HELO igw3.watson.ibm.com) (198.81.209.18) by sources.redhat.com with SMTP; 8 Dec 2001 00:00:57 -0000 Received: from sp1n293en1.watson.ibm.com (sp1n293en1.watson.ibm.com [9.2.112.57]) by igw3.watson.ibm.com (8.11.4/8.11.4) with ESMTP id fB800uT256262 for ; Fri, 7 Dec 2001 19:00:56 -0500 Received: from makai.watson.ibm.com (makai.watson.ibm.com [9.2.216.144]) by sp1n293en1.watson.ibm.com (8.11.4/8.11.4) with ESMTP id fB800uU39486 for ; Fri, 7 Dec 2001 19:00:56 -0500 Received: from watson.ibm.com (localhost [127.0.0.1]) by makai.watson.ibm.com (AIX4.3/8.9.3/8.9.3/01-10-2000) with ESMTP id TAA22812 for ; Fri, 7 Dec 2001 19:00:56 -0500 Message-Id: <200112080000.TAA22812@makai.watson.ibm.com> To: gcc@gcc.gnu.org Subject: Load hoisting bug Date: Fri, 07 Dec 2001 16:01:00 -0000 From: David Edelsohn X-SW-Source: 2001-12/txt/msg00391.txt.bz2 We have not had enough fun with loop optimizations lately, so I found one... The divconst-3.c regression on AIX which appeared at the beginning of November is due to GCC miscompiling itself. The miscompilation is caused by a loop optimization which was not safe. Prior to loop optimization: (note 47 177 53 NOTE_INSN_LOOP_BEG) (insn 68 66 69 (set (reg:SI 4 r4) (subreg:SI (reg/v:DI 119) 4)) 289 {*movsi_internal1} (nil) (nil)) (insn 69 68 71 (parallel[ (set (reg:DI 3 r3) (mult:DI (sign_extend:DI (reg:SI 3 r3)) (sign_extend:DI (reg:SI 4 r4)))) (clobber (scratch:SI)) (clobber (reg:SI 0 r0)) ] ) 76 {mull_call} (nil) (nil)) After loop optimization: Insn 68: regno 4 (life 1), savings 1 moved to 178 (insn 178 177 179 (set (reg:SI 4 r4) (subreg:SI (reg/v:DI 119) 4)) -1 (nil) (nil)) (note 47 205 202 NOTE_INSN_LOOP_BEG) (insn 69 66 71 (parallel[ (set (reg:DI 3 r3) (mult:DI (sign_extend:DI (reg:SI 3 r3)) (sign_extend:DI (reg:SI 4 r4)))) (clobber (scratch:SI)) (clobber (reg:SI 0 r0)) ] ) -1 (nil) (nil)) scan_loop() decides that it can move the SET of r4 out of the loop, placing it on the move_movables list. The register only is used within the loop (prior to register allocation). loop_invariant_p() returns true which seems incorrect to me. The value is invariant, but the register is not invariant. (set (reg:DI 3) ...) uses the register pair r3 and r4 on a 32-bit target! The instruction clobbers r3, so it needs to be restored on each iteration (as gcc-3.0 correctly performed), but the mainline now is hoisting the load out of the loop although the register is modified in the loop. The loop information array has r4 listed as set_in_loop=1. Is GCC getting confused by the use of a hard register? Is GCC getting confused because of DImode? The pattern could explicitly clobber r4, but GCC should know that DImode requires a pair of GPRs. I still am trying to figure out the origin of the problem. Any guidance would be appreciated. Thanks, David