aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJuergen Christ <jchrist@linux.ibm.com>2025-03-10 10:03:36 +0100
committerJuergen Christ <jchrist@linux.ibm.com>2025-03-11 14:54:16 +0100
commit4001281d69e9f8e01d2183f0e931e15ec4a522eb (patch)
tree1ca172f8c64d749dc8636ea17d059376f6304100 /gcc
parentdc47161c1f32c3f27d1157ba0de9d98ea1b7fc82 (diff)
downloadgcc-4001281d69e9f8e01d2183f0e931e15ec4a522eb.zip
gcc-4001281d69e9f8e01d2183f0e931e15ec4a522eb.tar.gz
gcc-4001281d69e9f8e01d2183f0e931e15ec4a522eb.tar.bz2
s390: fix delegitimization of addresses
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-1.c: New test. Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/s390/s390.cc15
-rw-r--r--gcc/testsuite/gcc.target/s390/delegitimize-1.c22
2 files changed, 37 insertions, 0 deletions
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 645aedb..d4e849b 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -8238,6 +8238,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-1.c b/gcc/testsuite/gcc.target/s390/delegitimize-1.c
new file mode 100644
index 0000000..5c49565
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/delegitimize-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-m64 -fPIC -O2 -g -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" } } */