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. This patch only impacts targets with Pmode != ptr_mode. Richard, can you take a look at this for mips? Thanks. -- H.J.