(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