s390: fix delegitimization of addresses

Message ID 20250310091500.9038-1-jchrist@linux.ibm.com
State New
Headers
Series s390: fix delegitimization of addresses |

Commit Message

Juergen Christ March 10, 2025, 9:15 a.m. UTC
  In legitimize_pic_address we create a
(const (unspec ... UNSPEC_GOTENT))
in the GOT offset might be >= 4k.  However, the
s390_delegitimize_address does not contain a case for this scenario.

gcc/ChangeLog:

	* config/s390/s390.cc (s390_delegitimize_address): Add missing case.

gcc/testsuite/ChangeLog:

	* gcc.target/s390/delegitimize.c: New test.

Bootstrapped and tested on s390x.  Okay for trunk?

Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
---
 gcc/config/s390/s390.cc                      | 15 +++++++++++++
 gcc/testsuite/gcc.target/s390/delegitimize.c | 22 ++++++++++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/s390/delegitimize.c
  

Comments

Stefan Schulze Frielinghaus March 11, 2025, 10:49 a.m. UTC | #1
On Mon, Mar 10, 2025 at 10:15:00AM +0100, Juergen Christ wrote:
> In legitimize_pic_address we create a
> (const (unspec ... UNSPEC_GOTENT))
> in the GOT offset might be >= 4k.  However, the
> s390_delegitimize_address does not contain a case for this scenario.
> 
> gcc/ChangeLog:
> 
> 	* config/s390/s390.cc (s390_delegitimize_address): Add missing case.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/s390/delegitimize.c: New test.

The naming scheme of file names is with a trailing -1 even in case of
a single file which makes it easier to add later on further files:
https://gcc.gnu.org/onlinedocs/gccint/Test-Idioms.html

> 
> Bootstrapped and tested on s390x.  Okay for trunk?
> 
> Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
> ---
>  gcc/config/s390/s390.cc                      | 15 +++++++++++++
>  gcc/testsuite/gcc.target/s390/delegitimize.c | 22 ++++++++++++++++++++
>  2 files changed, 37 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/s390/delegitimize.c
> 
> diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
> index 29aef501fdd2..535659ee5181 100644
> --- a/gcc/config/s390/s390.cc
> +++ b/gcc/config/s390/s390.cc
> @@ -8218,6 +8218,21 @@ s390_delegitimize_address (rtx orig_x)
>  	return plus_constant (Pmode, XVECEXP (y, 0, 0), offset);
>      }
>  
> +  if (GET_CODE (x) == CONST)
> +    {
> +      /* Extract the symbol ref from:
> +	 (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
> +				       UNSPEC_PLT/GOTENT))  */
> +
> +      y = XEXP (x, 0);
> +      if (GET_CODE (y) == UNSPEC
> +	  && (XINT (y, 1) == UNSPEC_GOTENT
> +	      || XINT (y, 1) == UNSPEC_PLT31))
> +	return XVECEXP (y, 0, 0);
> +      else
> +	return orig_x;
> +    }
> +
>    if (GET_CODE (x) != MEM)
>      return orig_x;
>  
> diff --git a/gcc/testsuite/gcc.target/s390/delegitimize.c b/gcc/testsuite/gcc.target/s390/delegitimize.c
> new file mode 100644
> index 000000000000..bf143745dca2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/s390/delegitimize.c
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-options "-nostdinc -std=gnu11 -fshort-wchar -funsigned-char -fno-common -fno-PIE -fno-strict-aliasing -m64 -fPIC -mpacked-stack -mbackchain -msoft-float -march=z13 -mtune=z13 -mindirect-branch=thunk-extern -mfunction-return=thunk-extern -mindirect-branch-table -DCC_USING_EXPOLINE -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -DCONFIG_AS_CFI_VAL_OFFSET=1 -fno-delete-null-pointer-checks -O2 -fno-allow-store-data-races -fno-stack-protector -ftrivial-auto-var-init=zero -fno-stack-clash-protection -pg -mrecord-mcount -mnop-mcount -mfentry -fno-inline-functions-called-once -fmin-function-alignment=8 -fstrict-flex-arrays=3 -fno-strict-overflow -fno-stack-check -fconserve-stack -Wall -Wundef -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Werror=strict-prototypes -Wno-format-security -Wno-trigraphs -Wno-frame-address -Wno-address-of-packed-member -Wmissing-declarations -Wmissing-prototypes -Wframe-larger-than=2048 -Wno-main -Wno-dangling-pointer -Wvla -Wno-pointer-sign -Wcast-function-type -Wno-stringop-overflow -Wno-array-bounds -Wno-alloc-size-larger-than -Wimplicit-fallthrough=5 -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -Wenum-conversion -Wextra -Wunused -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-packed-not-aligned -Wno-format-overflow -Wno-format-truncation -Wno-stringop-truncation -Wno-override-init -Wno-missing-field-initializers -Wno-type-limits -Wno-shift-negative-value -Wno-maybe-uninitialized -Wno-sign-compare -Wno-unused-parameter -g -gdwarf-4 -fdump-rtl-final-details" } */

Please remove all the options which are not necessary for the test.

With the above changes, ok for trunk.

Thanks,
Stefan

> +
> +struct sk_buff {
> +  struct {
> +    struct {
> +      struct {
> +        int inner_ipproto;
> +      };
> +    };
> +  };
> +};
> +void skb_udp_tunnel_segment(struct sk_buff *skb);
> +const int *inet_offloads[42], *inet6_offloads[42];
> +_Bool skb_udp_tunnel_segment_is_ipv6;
> +void skb_udp_tunnel_segment(struct sk_buff *skb) {
> +  const int **offloads =
> +      skb_udp_tunnel_segment_is_ipv6 ? inet6_offloads : inet_offloads;
> +  *(volatile typeof(_Generic(0, default : 0)) *)&offloads[skb->inner_ipproto];
> +}
> +
> +/* { dg-final { scan-rtl-dump-not "Failed to expand as dwarf:" "final" } } */
> -- 
> 2.43.5
>
  

Patch

diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 29aef501fdd2..535659ee5181 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -8218,6 +8218,21 @@  s390_delegitimize_address (rtx orig_x)
 	return plus_constant (Pmode, XVECEXP (y, 0, 0), offset);
     }
 
+  if (GET_CODE (x) == CONST)
+    {
+      /* Extract the symbol ref from:
+	 (const:DI (unspec:DI [(symbol_ref:DI ("foo"))]
+				       UNSPEC_PLT/GOTENT))  */
+
+      y = XEXP (x, 0);
+      if (GET_CODE (y) == UNSPEC
+	  && (XINT (y, 1) == UNSPEC_GOTENT
+	      || XINT (y, 1) == UNSPEC_PLT31))
+	return XVECEXP (y, 0, 0);
+      else
+	return orig_x;
+    }
+
   if (GET_CODE (x) != MEM)
     return orig_x;
 
diff --git a/gcc/testsuite/gcc.target/s390/delegitimize.c b/gcc/testsuite/gcc.target/s390/delegitimize.c
new file mode 100644
index 000000000000..bf143745dca2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/delegitimize.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-options "-nostdinc -std=gnu11 -fshort-wchar -funsigned-char -fno-common -fno-PIE -fno-strict-aliasing -m64 -fPIC -mpacked-stack -mbackchain -msoft-float -march=z13 -mtune=z13 -mindirect-branch=thunk-extern -mfunction-return=thunk-extern -mindirect-branch-table -DCC_USING_EXPOLINE -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -DCONFIG_AS_CFI_VAL_OFFSET=1 -fno-delete-null-pointer-checks -O2 -fno-allow-store-data-races -fno-stack-protector -ftrivial-auto-var-init=zero -fno-stack-clash-protection -pg -mrecord-mcount -mnop-mcount -mfentry -fno-inline-functions-called-once -fmin-function-alignment=8 -fstrict-flex-arrays=3 -fno-strict-overflow -fno-stack-check -fconserve-stack -Wall -Wundef -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Werror=strict-prototypes -Wno-format-security -Wno-trigraphs -Wno-frame-address -Wno-address-of-packed-member -Wmissing-declarations -Wmissing-prototypes -Wframe-larger-than=2048 -Wno-main -Wno-dangling-pointer -Wvla -Wno-pointer-sign -Wcast-function-type -Wno-stringop-overflow -Wno-array-bounds -Wno-alloc-size-larger-than -Wimplicit-fallthrough=5 -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -Wenum-conversion -Wextra -Wunused -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-packed-not-aligned -Wno-format-overflow -Wno-format-truncation -Wno-stringop-truncation -Wno-override-init -Wno-missing-field-initializers -Wno-type-limits -Wno-shift-negative-value -Wno-maybe-uninitialized -Wno-sign-compare -Wno-unused-parameter -g -gdwarf-4 -fdump-rtl-final-details" } */
+
+struct sk_buff {
+  struct {
+    struct {
+      struct {
+        int inner_ipproto;
+      };
+    };
+  };
+};
+void skb_udp_tunnel_segment(struct sk_buff *skb);
+const int *inet_offloads[42], *inet6_offloads[42];
+_Bool skb_udp_tunnel_segment_is_ipv6;
+void skb_udp_tunnel_segment(struct sk_buff *skb) {
+  const int **offloads =
+      skb_udp_tunnel_segment_is_ipv6 ? inet6_offloads : inet_offloads;
+  *(volatile typeof(_Generic(0, default : 0)) *)&offloads[skb->inner_ipproto];
+}
+
+/* { dg-final { scan-rtl-dump-not "Failed to expand as dwarf:" "final" } } */