RFC: PR middle-end/55142: Check Pmode instead of ptr_mode for address mode
H.J. Lu
hjl.tools@gmail.com
Mon Nov 5 21:55:00 GMT 2012
On Sat, Nov 3, 2012 at 1:14 AM, H.J. Lu <hjl.tools@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.lu@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.lu@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.
More information about the Gcc-patches
mailing list