On Mon, Nov 5, 2012 at 3:06 PM, Richard Sandiford <rdsandif...@googlemail.com> wrote: > "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.
Did you mean my patch was wrong to change ptr_mode to Pmode? Do you have any suggestions? This code has been this way when it was first checked into the current GCC tree back in Mar., 1992. >> This patch only impacts targets with Pmode != ptr_mode. Richard, can What are targets which will be affected by this change? Thanks. -- H.J.