On Tue, Nov 13, 2012 at 8:15 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
>>>> Since x32 runs in 64-bit mode, for address -0x40000300(%rax), hardware >>>> sign-extends displacement from 32-bits to 64-bits and adds it to %rax. >>>> But x32 wants 32-bit -0x40000300, not 64-bit -0x40000300. This patch >>>> uses 32-bit registers instead of 64-bit registers when displacement >>>> < -16*1024*1024. -16*1024*1024 is used instead of 0 so that we will >>>> still generate -16(%rsp) instead of -16(%esp). >>>> >>>> Tested it on Linux/x32. OK to install? >>> >>> This problem uncovers a bug in the middle-end, so I guess it would be >>> better to fix it there. >>> >>> Uros. >> >> The problem is it isn't safe to transform >> >> (zero_extend:DI (plus:SI (FOO:SI) (const_int Y))) >> >> to >> >> (plus:DI (zero_extend:DI (FOO:SI)) (const_int Y)) >> >> when Y is negative and its absolute value is greater than FOO. However, >> we have to do this transformation since other parts of GCC depend on >> it. If we revert the fix for >> >> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49721 >> >> we will get >> >> FAIL: gcc.c-torture/compile/990523-1.c -O3 -g (internal compiler error) >> FAIL: gcc.c-torture/compile/990523-1.c -O3 -g (test for excess errors) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -fomit-frame-pointer >> -funroll-all-loo >> ps -finline-functions (internal compiler error) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -fomit-frame-pointer >> -funroll-all-loo >> ps -finline-functions (test for excess errors) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -fomit-frame-pointer >> -funroll-loops >> (internal compiler error) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -fomit-frame-pointer >> -funroll-loops >> (test for excess errors) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -fomit-frame-pointer (internal >> compi >> ler error) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -fomit-frame-pointer (test for >> exces >> s errors) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -g (internal compiler error) >> FAIL: gcc.c-torture/compile/pr41634.c -O3 -g (test for excess errors) >> FAIL: gcc.dg/Warray-bounds.c (internal compiler error) >> FAIL: gcc.dg/Warray-bounds.c (test for excess errors) >> >> since we generate pseudo registers to convert SImode to DImode >> after reload. Fixing it requires significant changes. >> >> This is only a problem for 64-bit register address since the symbolic >> address is 32-bit. Using 32-bit base/index registers will work around >> this issue. > > This address > > (plus:DI (zero_extend:DI (FOO:SI)) (const_int Y)) > > is OK for x32 as long as Y, which is encoded as 32-bit immediate, > is zero-extend from 32-bit to 64-bit. SImode address does it. > My patch optimizes it a little bit by using SImode address only > for Y < -16*1024*1024. I was wondering, why we operate with constant -16*1024*1024? Should we use 0x7FFFFFF instead? Since the MSB is always zero, we are safe. Please add a fat ??? comment, why we paper-over this issue and repost the latest patch. I got lost in all the versions :( Uros.