On Sun, Nov 11, 2012 at 1:37 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Fri, Nov 9, 2012 at 9:23 AM, Uros Bizjak <ubiz...@gmail.com> wrote: >> On Fri, Nov 9, 2012 at 10:17 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. -- H.J.