diff mbox series

x86_64: Fix up -fpic -mcmodel=large -fno-plt [PR98063]

Message ID 20201201085256.GQ3788@tucnak
State New
Headers show
Series x86_64: Fix up -fpic -mcmodel=large -fno-plt [PR98063] | expand

Commit Message

Jakub Jelinek Dec. 1, 2020, 8:52 a.m. UTC
Hi!

On the following testcase with -fpic -mcmodel=large -fno-plt we emit
call puts@GOTPCREL(%rip)
but that is not really appropriate for CM_LARGE_PIC, the .text can be larger
than 2GB in that case and the .got slot further away from %rip than what can
fit into the signed 32-bit immediate.

The following patch computes the address of the .got slot the way it is
computed for that model for function pointer loads, and calls that.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-12-01  Jakub Jelinek  <jakub@redhat.com>

	PR target/98063
	* config/i386/i386-expand.c (ix86_expand_call): Handle non-plt
	CM_LARGE_PIC calls.

	* gcc.target/i386/pr98063.c: New test.


	Jakub

Comments

Uros Bizjak Dec. 1, 2020, 9:40 a.m. UTC | #1
On Tue, Dec 1, 2020 at 9:53 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> On the following testcase with -fpic -mcmodel=large -fno-plt we emit
> call puts@GOTPCREL(%rip)
> but that is not really appropriate for CM_LARGE_PIC, the .text can be larger
> than 2GB in that case and the .got slot further away from %rip than what can
> fit into the signed 32-bit immediate.
>
> The following patch computes the address of the .got slot the way it is
> computed for that model for function pointer loads, and calls that.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2020-12-01  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/98063
>         * config/i386/i386-expand.c (ix86_expand_call): Handle non-plt
>         CM_LARGE_PIC calls.
>
>         * gcc.target/i386/pr98063.c: New test.

OK.

Thanks,
Uros.

>
> --- gcc/config/i386/i386-expand.c.jj    2020-11-26 16:22:29.091353066 +0100
> +++ gcc/config/i386/i386-expand.c       2020-11-30 12:55:52.936300739 +0100
> @@ -8063,7 +8063,17 @@ ix86_expand_call (rtx retval, rtx fnaddr
>             }
>           else if (!TARGET_PECOFF && !TARGET_MACHO)
>             {
> -             if (TARGET_64BIT)
> +             if (TARGET_64BIT
> +                 && ix86_cmodel == CM_LARGE_PIC
> +                 && DEFAULT_ABI != MS_ABI)
> +               {
> +                 fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
> +                                          UNSPEC_GOT);
> +                 fnaddr = gen_rtx_CONST (Pmode, fnaddr);
> +                 fnaddr = force_reg (Pmode, fnaddr);
> +                 fnaddr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, fnaddr);
> +               }
> +             else if (TARGET_64BIT)
>                 {
>                   fnaddr = gen_rtx_UNSPEC (Pmode,
>                                            gen_rtvec (1, addr),
> --- gcc/testsuite/gcc.target/i386/pr98063.c.jj  2020-11-30 13:00:31.699214198 +0100
> +++ gcc/testsuite/gcc.target/i386/pr98063.c     2020-11-30 13:24:05.352485291 +0100
> @@ -0,0 +1,13 @@
> +/* PR target/98063 */
> +/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
> +/* { dg-require-effective-target lp64 } */
> +/* { dg-require-effective-target fpic } */
> +/* { dg-options "-O2 -fpic -mcmodel=large -fno-plt -save-temps" } */
> +/* { dg-final { scan-assembler-not "puts@GOTPCREL" } } */
> +
> +int
> +main ()
> +{
> +  __builtin_puts ("Hello, world!");
> +  return 0;
> +}
>
>         Jakub
>
diff mbox series

Patch

--- gcc/config/i386/i386-expand.c.jj	2020-11-26 16:22:29.091353066 +0100
+++ gcc/config/i386/i386-expand.c	2020-11-30 12:55:52.936300739 +0100
@@ -8063,7 +8063,17 @@  ix86_expand_call (rtx retval, rtx fnaddr
 	    }
 	  else if (!TARGET_PECOFF && !TARGET_MACHO)
 	    {
-	      if (TARGET_64BIT)
+	      if (TARGET_64BIT
+		  && ix86_cmodel == CM_LARGE_PIC
+		  && DEFAULT_ABI != MS_ABI)
+		{
+		  fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+					   UNSPEC_GOT);
+		  fnaddr = gen_rtx_CONST (Pmode, fnaddr);
+		  fnaddr = force_reg (Pmode, fnaddr);
+		  fnaddr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, fnaddr);
+		}
+	      else if (TARGET_64BIT)
 		{
 		  fnaddr = gen_rtx_UNSPEC (Pmode,
 					   gen_rtvec (1, addr),
--- gcc/testsuite/gcc.target/i386/pr98063.c.jj	2020-11-30 13:00:31.699214198 +0100
+++ gcc/testsuite/gcc.target/i386/pr98063.c	2020-11-30 13:24:05.352485291 +0100
@@ -0,0 +1,13 @@ 
+/* PR target/98063 */
+/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fpic -mcmodel=large -fno-plt -save-temps" } */
+/* { dg-final { scan-assembler-not "puts@GOTPCREL" } } */
+
+int
+main ()
+{
+  __builtin_puts ("Hello, world!");
+  return 0;
+}