From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27187 invoked by alias); 11 Sep 2005 02:10:44 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 25678 invoked by uid 48); 11 Sep 2005 02:10:19 -0000 Date: Sun, 11 Sep 2005 02:10:00 -0000 From: "raeburn at raeburn dot org" To: gcc-bugs@gcc.gnu.org Message-ID: <20050911021012.23813.raeburn@raeburn.org> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug rtl-optimization/23813] New: redundant register assignments not eliminated X-Bugzilla-Reason: CC X-SW-Source: 2005-09/txt/msg01314.txt.bz2 List-Id: (CVS sources from ~6AM today US/Eastern, i.e., about 16 hours before submission) Compiling source below with -O9 -fomit-frame-pointer, there are cases where registers are assigned multiple times without any labels in between; a register assigned zero, used in an inclusive-or, then overwritten; another register assigned zero and never used. This 64-bit byteswap routine also exhibits the problems I submitted in 23810, 23811, 23812, but I think one or two of these might be separate problems from those. typedef unsigned long long uint64_t; typedef unsigned long uint32_t; uint64_t bitreverse (uint64_t n) { /* Dr. Dobbs Journal 1983, reported in Sean Eron Anderson's "bit twiddling hacks" web site, http://graphics.stanford.edu/~seander/bithacks.html . */ #define REV64_STEP(VAR, SHIFT, MASK) \ VAR = (((VAR >> SHIFT) & MASK) | ((VAR << SHIFT) & (0xFFFFFFFFFFFFFFFFULL & ~MASK))) REV64_STEP(n, 1, 0x5555555555555555ULL); /* odd/even bits */ REV64_STEP(n, 2, 0x3333333333333333ULL); /* bitpairs */ REV64_STEP(n, 4, 0x0F0F0F0F0F0F0F0FULL); /* nibbles */ REV64_STEP(n, 8, 0x00FF00FF00FF00FFULL); /* bytes */ REV64_STEP(n, 16, 0x0000FFFF0000FFFFULL); /* halfwords */ REV64_STEP(n, 32, 0x00000000FFFFFFFFULL); /* full words */ return n; } assembly generated: bitreverse: pushl %edi pushl %esi pushl %ebx movl 16(%esp), %eax movl 20(%esp), %edx movl %eax, %ecx movl %edx, %ebx shrdl $1, %ebx, %ecx shldl $1, %eax, %edx addl %eax, %eax shrl %ebx andl $-1431655766, %eax andl $-1431655766, %edx andl $1431655765, %ecx andl $1431655765, %ebx orl %eax, %ecx orl %edx, %ebx movl %ecx, %eax movl %ebx, %edi movl %ecx, %esi movl %ebx, %edx shrdl $2, %edi, %esi shldl $2, %eax, %edx andl $858993459, %esi shrl $2, %edi andl $-858993460, %edx sall $2, %eax andl $858993459, %edi andl $-858993460, %eax orl %edx, %edi orl %eax, %esi movl %edi, %ebx movl %esi, %eax movl %esi, %ecx movl %edi, %edx shrdl $4, %ebx, %ecx shldl $4, %eax, %edx andl $252645135, %ecx shrl $4, %ebx andl $-252645136, %edx sall $4, %eax andl $252645135, %ebx andl $-252645136, %eax orl %edx, %ebx orl %eax, %ecx movl %ebx, %edi movl %ecx, %esi movl %ecx, %eax shrdl $8, %edi, %esi movl %ebx, %edx shrl $8, %edi andl $16711935, %esi andl $16711935, %edi shldl $8, %eax, %edx sall $8, %eax andl $-16711936, %edx andl $-16711936, %eax orl %edx, %edi orl %eax, %esi # we're about to copy this from esi to eax then clear esi; # wouldn't putting output in eax be better? movl %edi, %ebx movl %esi, %eax movl %esi, %ecx movl %edi, %edx xorl %esi, %esi # esi set to zero # PRs 23810, 23811 look at this code: shrdl $16, %ebx, %ecx shldl $16, %eax, %edx andl $65535, %ecx shrl $16, %ebx andl $-65536, %edx andl $65535, %ebx sall $16, %eax orl %edx, %ebx andl $-65536, %eax movl %ebx, %edx orl %eax, %ecx # output to ecx then move to eax, instead of just output to eax? movl %ecx, %ebx # ebx only used to ior into edx, while ecx value still live movl %ecx, %eax # assign eax twice?? movl %edx, %eax xorl %edx, %edx # clear edx twice?? xorl %edx, %edx orl %esi, %eax # esi still zero orl %ebx, %edx movl $0, %ecx # why? insn note shows REG_UNUSED popl %ebx popl %esi popl %edi ret A version of this swap routine that splits the 64-bit value into two 32-bit chunks, performs bit- reversals on the chunks, and puts the two chunks back together in reverse order, comes out shorter, despite still showing the PR23810/23811 problems, but it does the same work as this function should. I suspect at least some of these come from preserving DImode operations until fairly late, e.g., assigning a DImode to eax/edx, then shifting right 32 (eax:=edx, edx:=0), stuff like that. I haven't figured out the esi and ecx bits yet though. -- Summary: redundant register assignments not eliminated Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P2 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: raeburn at raeburn dot org CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23813