"H.J. Lu" <hjl.to...@gmail.com> writes:
> On Sat, Nov 3, 2012 at 1:14 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
>> Hi,
>>
>> The testcase shows -O -mx32 -maddress-mode=long -fPIC -S generates;
>>
>> x.i:22:37: internal compiler error: in plus_constant, at explow.c:88
>>   info[0x6ffffeff - dyn->d_tag + 12] = dyn;
>>
>> expand_expr_real_2 has
>>
>>       /* No sense saving up arithmetic to be done
>>          if it's all in the wrong mode to form part of an address.
>>          And force_operand won't know whether to sign-extend or
>>          zero-extend.  */
>>       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
>>           || mode != ptr_mode)
>>
>> With mode == SImode, Pmode == DImode and ptr_mode == SImode, we
>> generate wrong address.  Instead of zero-extending address
>> 0xf7ffdd64, we sign-extend it to 0xfffffffff7ffdd64.  This patch
>> checks Pmode instead of ptr_mode for address mode.  It fixes the testcase
>> and generates a working x32 glibc. Is this patch correct?
>>
>> Thanks.
>>
>>
>> H.J.
>> ---
>> gcc/
>>
>> 2012-11-03  H.J. Lu  <hongjiu...@intel.com>
>>
>>         PR middle-end/55142
>>         * expr.c (expand_expr_real_2): Check Pmode instead of ptr_mode
>>         for wrong address mode.
>>
>> gcc/testsuite/
>>
>> 2012-11-03  H.J. Lu  <hongjiu...@intel.com>
>>
>>         PR middle-end/55142
>>         * gcc.target/i386/pr55142.c: New file.
>>
>> diff --git a/gcc/expr.c b/gcc/expr.c
>> index 0ad3b57..1600380 100644
>> --- a/gcc/expr.c
>> +++ b/gcc/expr.c
>> @@ -8290,7 +8290,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum 
>> machine_mode tmode,
>>          And force_operand won't know whether to sign-extend or
>>          zero-extend.  */
>>        if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
>> -         || mode != ptr_mode)
>> +         || mode != Pmode)
>>         {
>>           expand_operands (treeop0, treeop1,
>>                            subtarget, &op0, &op1, EXPAND_NORMAL);
>> @@ -8333,7 +8333,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum 
>> machine_mode tmode,
>>          And force_operand won't know whether to sign-extend or
>>          zero-extend.  */
>>        if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
>> -         || mode != ptr_mode)
>> +         || mode != Pmode)
>>         goto binop;
>>
>>        expand_operands (treeop0, treeop1,
>> diff --git a/gcc/testsuite/gcc.target/i386/pr55142.c 
>> b/gcc/testsuite/gcc.target/i386/pr55142.c
>> new file mode 100644
>> index 0000000..c8a9625
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr55142.c
>> @@ -0,0 +1,34 @@
>> +/* { dg-do compile { target { ! { ia32 } } } } */
>> +/* { dg-require-effective-target fpic } */
>> +/* { dg-options "-O2 -mx32 -maddress-mode=long -fpic" } */
>> +
>> +typedef int int32_t;
>> +typedef unsigned int uint32_t;
>> +typedef int32_t Elf32_Sword;
>> +typedef struct
>> +{
>> +  Elf32_Sword d_tag;
>> +} Elf32_Dyn;
>> +struct link_map
>> +{
>> +  Elf32_Dyn *l_ld;
>> +  Elf32_Dyn *l_info[34];
>> +};
>> +extern struct link_map _dl_rtld_map __attribute__ ((visibility ("hidden")));
>> +static void elf_get_dynamic_info (struct link_map *l)
>> +{
>> +  Elf32_Dyn *dyn = l->l_ld;
>> +  Elf32_Dyn **info;
>> +  info = l->l_info;
>> +  while (dyn->d_tag != 0)
>> +    {
>> +      if ((uint32_t) (0x6ffffeff - dyn->d_tag) < 11)
>> +       info[0x6ffffeff - dyn->d_tag + 12] = dyn;
>> +      ++dyn;
>> +    }
>> +}
>> +void
>> +foo (void)
>> +{
>> +  elf_get_dynamic_info (&_dl_rtld_map);
>> +}
>
> Any comments? I'd like to get it fixed for 4.8.

I can't approve this anyway, but the existing ptr_mode sounds right for
EXPAND_INTIALIZER.  I assume it would be for EXPAND_SUM too, although
I've always been a bit unsure what that means.

> This patch only impacts targets with Pmode != ptr_mode.  Richard, can
> you take a look at this for mips?

MIPS isn't affected FWIW.  Having Pmode != ptr_mode was just a temporary
experiment on the 3.4 rewrite branch.

Richard

Reply via email to