diff mbox

[AArch64] PR target/71112: Properly create lowpart of pic_offset_table_rtx with -fpie

Message ID 583D45D0.5000201@foss.arm.com
State New
Headers show

Commit Message

Kyrill Tkachov Nov. 29, 2016, 9:09 a.m. UTC
Hi all,

This ICE only occurs on big-endian ILP32 -fpie code. The expansion code generates the invalid load:
(insn 6 5 7 (set (reg/f:SI 76)
         (unspec:SI [
                 (mem/u/c:SI (lo_sum:SI (nil)
                         (symbol_ref:SI ("dbs") [flags 0x40] <var_decl 0x7f6e387c0ab0 dbs>)) [0  S4 A8])
             ] UNSPEC_GOTSMALLPIC28K))
      (expr_list:REG_EQUAL (symbol_ref:SI ("dbs") [flags 0x40] <var_decl 0x7f6e387c0ab0 dbs>)
         (nil)))

to load the symbol. Note the (nil) argument to lo_sum.
The buggy hunk meant to take the lowpart of the pic_offset_table_rtx register but it did so by explicitly
constructing a subreg, for which the offset is wrong for big-endian. The right way is to use gen_lowpart which
knows what exactly to do, with this patch we emit:
(insn 6 5 7 (set (reg/f:SI 76)
         (unspec:SI [
                 (mem/u/c:SI (lo_sum:SI (subreg:SI (reg:DI 73) 4)
                         (symbol_ref:SI ("dbs") [flags 0x40] <var_decl 0x7ffb097e6ab0 dbs>)) [0  S4 A8])
             ] UNSPEC_GOTSMALLPIC28K))
      (expr_list:REG_EQUAL (symbol_ref:SI ("dbs") [flags 0x40] <var_decl 0x7ffb097e6ab0 dbs>)
         (nil)))

and everything works fine.

Bootstrapped and tested on aarch64-none-linux-gnu.
Also tested on aarch64_be-none-elf.
Ok for trunk?

Thanks,
Kyrill

2016-11-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     PR target/71112
     * config/aarch64/aarch64.c (aarch64_load_symref_appropriately,
     case SYMBOL_SMALL_GOT_28K): Use gen_lowpart rather than constructing
     subreg directly.

2016-11-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

     PR target/71112
     * gcc.c-torture/compile/pr71112.c: New test.

Comments

Andrew Pinski Nov. 30, 2016, 5:27 a.m. UTC | #1
On Tue, Nov 29, 2016 at 1:09 AM, Kyrill Tkachov
<kyrylo.tkachov@foss.arm.com> wrote:
> Hi all,

>

> This ICE only occurs on big-endian ILP32 -fpie code. The expansion code

> generates the invalid load:

> (insn 6 5 7 (set (reg/f:SI 76)

>         (unspec:SI [

>                 (mem/u/c:SI (lo_sum:SI (nil)

>                         (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

> 0x7f6e387c0ab0 dbs>)) [0  S4 A8])

>             ] UNSPEC_GOTSMALLPIC28K))

>      (expr_list:REG_EQUAL (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

> 0x7f6e387c0ab0 dbs>)

>         (nil)))

>

> to load the symbol. Note the (nil) argument to lo_sum.

> The buggy hunk meant to take the lowpart of the pic_offset_table_rtx

> register but it did so by explicitly

> constructing a subreg, for which the offset is wrong for big-endian. The

> right way is to use gen_lowpart which

> knows what exactly to do, with this patch we emit:

> (insn 6 5 7 (set (reg/f:SI 76)

>         (unspec:SI [

>                 (mem/u/c:SI (lo_sum:SI (subreg:SI (reg:DI 73) 4)

>                         (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

> 0x7ffb097e6ab0 dbs>)) [0  S4 A8])

>             ] UNSPEC_GOTSMALLPIC28K))

>      (expr_list:REG_EQUAL (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

> 0x7ffb097e6ab0 dbs>)

>         (nil)))

>

> and everything works fine.

>

> Bootstrapped and tested on aarch64-none-linux-gnu.

> Also tested on aarch64_be-none-elf.

> Ok for trunk?


Naveen posted the exact same patch:
https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02305.html
Though with a slightly different testcase :).

Thanks,
Andrew

>

> Thanks,

> Kyrill

>

> 2016-11-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

>

>     PR target/71112

>     * config/aarch64/aarch64.c (aarch64_load_symref_appropriately,

>     case SYMBOL_SMALL_GOT_28K): Use gen_lowpart rather than constructing

>     subreg directly.

>

> 2016-11-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

>

>     PR target/71112

>     * gcc.c-torture/compile/pr71112.c: New test.
Kyrill Tkachov Nov. 30, 2016, 9:10 a.m. UTC | #2
On 30/11/16 05:27, Andrew Pinski wrote:
> On Tue, Nov 29, 2016 at 1:09 AM, Kyrill Tkachov

> <kyrylo.tkachov@foss.arm.com> wrote:

>> Hi all,

>>

>> This ICE only occurs on big-endian ILP32 -fpie code. The expansion code

>> generates the invalid load:

>> (insn 6 5 7 (set (reg/f:SI 76)

>>          (unspec:SI [

>>                  (mem/u/c:SI (lo_sum:SI (nil)

>>                          (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

>> 0x7f6e387c0ab0 dbs>)) [0  S4 A8])

>>              ] UNSPEC_GOTSMALLPIC28K))

>>       (expr_list:REG_EQUAL (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

>> 0x7f6e387c0ab0 dbs>)

>>          (nil)))

>>

>> to load the symbol. Note the (nil) argument to lo_sum.

>> The buggy hunk meant to take the lowpart of the pic_offset_table_rtx

>> register but it did so by explicitly

>> constructing a subreg, for which the offset is wrong for big-endian. The

>> right way is to use gen_lowpart which

>> knows what exactly to do, with this patch we emit:

>> (insn 6 5 7 (set (reg/f:SI 76)

>>          (unspec:SI [

>>                  (mem/u/c:SI (lo_sum:SI (subreg:SI (reg:DI 73) 4)

>>                          (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

>> 0x7ffb097e6ab0 dbs>)) [0  S4 A8])

>>              ] UNSPEC_GOTSMALLPIC28K))

>>       (expr_list:REG_EQUAL (symbol_ref:SI ("dbs") [flags 0x40] <var_decl

>> 0x7ffb097e6ab0 dbs>)

>>          (nil)))

>>

>> and everything works fine.

>>

>> Bootstrapped and tested on aarch64-none-linux-gnu.

>> Also tested on aarch64_be-none-elf.

>> Ok for trunk?

> Naveen posted the exact same patch:

> https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02305.html

> Though with a slightly different testcase :).


Ah, indeed. Sorry for the noise :)
Kyrill

> Thanks,

> Andrew

>

>> Thanks,

>> Kyrill

>>

>> 2016-11-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

>>

>>      PR target/71112

>>      * config/aarch64/aarch64.c (aarch64_load_symref_appropriately,

>>      case SYMBOL_SMALL_GOT_28K): Use gen_lowpart rather than constructing

>>      subreg directly.

>>

>> 2016-11-29  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

>>

>>      PR target/71112

>>      * gcc.c-torture/compile/pr71112.c: New test.
diff mbox

Patch

commit 99052634535958a776a2e7b7c9c6169cb656f5a8
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Mon Nov 28 12:26:57 2016 +0000

    [AArch64] PR target/71112: Properly create lowpart of pic_offset_table_rtx with -fpie

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 686a8e92..aa833c8 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1299,7 +1299,7 @@  aarch64_load_symref_appropriately (rtx dest, rtx imm,
 	    emit_move_insn (gp_rtx, gen_rtx_HIGH (Pmode, s));
 
 	    if (mode != GET_MODE (gp_rtx))
-	      gp_rtx = simplify_gen_subreg (mode, gp_rtx, GET_MODE (gp_rtx), 0);
+	      gp_rtx = gen_lowpart (mode, gp_rtx);
 	  }
 
 	if (mode == ptr_mode)
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr71112.c b/gcc/testsuite/gcc.c-torture/compile/pr71112.c
new file mode 100644
index 0000000..69e2df6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr71112.c
@@ -0,0 +1,10 @@ 
+/* PR target/71112.  */
+/* { dg-additional-options "-fpie" { target pie } } */
+
+extern int dbs[100];
+void f (int *);
+int nscd_init (void)
+{
+  f (dbs);
+  return 0;
+}