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.

Reply via email to