This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[C]: Unnecessary int(16)->long(32) promotion: Bug in C front end?
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 08 Jul 2011 14:36:23 +0200
- Subject: [C]: Unnecessary int(16)->long(32) promotion: Bug in C front end?
Hi,
I am on 4.7 trunk (175991)
Configured with: ../../gcc.gnu.org/trunk/configure --target=avr
--prefix=/local/gnu/install/gcc-4.7 --disable-nls --disable-shared
--enable-languages=c,c++ --with-dwarf2 --disable-lto
Suppose the following source from gcc.c-torture/compile/pr30338.c:
extern char *grub_scratch_mem;
int testload_func (char *arg, int flags)
{
int i;
for (i = 0; i < 0x10ac0; i++)
if (*((unsigned char *) ((0x200000 + i + (int) grub_scratch_mem)))
!= *((unsigned char *) ((0x300000 + i + (int) grub_scratch_mem))))
return 0;
return 1;
}
And compiled with the command line
> avr-gcc pr30338.c -S -Os -dp -mmcu=atmega128 -fdump-tree-original
pr30338.c: In function 'testload_func':
pr30338.c:9:11: warning: cast to pointer from integer of different
size [-Wint-to-pointer-cast]
pr30338.c:10:14: warning: cast to pointer from integer of different
size [-Wint-to-pointer-cast]
Frist of all, the warning is incorrect because Pmode=HImode=int on AVR.
Second, the dump reads:
{
int i;
int i;
i = 0;
<D.1213>:;
if (*(unsigned char *) (int) (((long int) i + 2097152) + (long int)
(int) grub_scratch_mem) != *(unsigned char *) (int) (((long int) i +
3145728) + (long int) (int) grub_scratch_mem))
{
return 0;
}
i++ ;
goto <D.1213>;
return 1;
}
Why is there a (long int) at all? There is nothing in the source that
mentions long or L or UL suffix on a constant. That is: all constants
can be truncated mod 2**16.
However, I observe the long throughout all passes, e.g. SImode and
finally in extendhisi2 insn that do all computation in SImode instead
of HImode.
Is this a bug in the C front end?
BTW: With -x c++ all the function collapses to while(1);
Johann