On Tue, Nov 13, 2012 at 10:03 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Tue, Nov 13, 2012 at 3:30 PM, 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.
>>>
>>
>> We can check 0x7FFFFFF, i.e., disp < 0.  I use -16*1024*1024, which
>> is also used to check legitimate address displacements for PIC, to
>> reduce code sizes for small negative displacements.  Or we can always
>> encode negative displacements with zero-extension, including -1(%rsp).
>>
>>> Please add a fat ??? comment, why we paper-over this issue and repost
>>> the latest patch. I got lost in all the versions :(
>>>
>>
>> Here is the updated patch.
>>
>> gcc/
>>
>> 2012-11-13  Eric Botcazou  <ebotca...@adacore.com>
>>             H.J. Lu  <hongjiu...@intel.com>
>>
>>         PR target/55142
>>         * config/i386/i386.c (legitimize_pic_address): Properly handle
>>         REG + CONST.
>>         (ix86_print_operand_address): For x32, zero-extend negative
>>         displacement if it < -16*1024*1024.
>>
>> gcc/testsuite/
>>
>> 2012-11-13  H.J. Lu  <hongjiu...@intel.com>
>>
>>         PR target/55142
>>         * gcc.target/i386/pr55142-1.c: New file.
>>         * gcc.target/i386/pr55142-2.c: Likewise.
>
> OK, for mainline SVN (with the reservation that middle-end fix was not
> found to be a viable solution, so target fix is papering-over real
> issue. Let's wait for the next victim... ).

That is true.

> Oh, and please fix a typo of mine in the one line above the patch
> hunk; the modifier for SI addresses should be 'k', not 'l'.

Will do.

> BTW: Do we need this patch also for 4.7? x32 address-mode is long by
> default there, but the problem doesn't trigger.
>

This regression is triggered by revision 188008:

http://gcc.gnu.org/ml/gcc-cvs/2012-05/msg00038.html

aka the un-sign-extension of sizetype constants.  We can
backport it to 4.7 branch if we want to be on the safer side.

Thanks.


-- 
H.J.

Reply via email to