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. -- H.J.