Patch: Print SImode register names to force addr32 prefix

Uros Bizjak ubizjak@gmail.com
Tue Nov 13 07:28:00 GMT 2012


On Tue, Nov 13, 2012 at 8:15 AM, H.J. Lu <hjl.tools@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.



More information about the Gcc-patches mailing list