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 <[email protected]>
---
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" } */
+
+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