https://gcc.gnu.org/g:4001281d69e9f8e01d2183f0e931e15ec4a522eb
commit r15-7962-g4001281d69e9f8e01d2183f0e931e15ec4a522eb Author: Juergen Christ <jchr...@linux.ibm.com> Date: Mon Mar 10 10:03:36 2025 +0100 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 <jchr...@linux.ibm.com> Diff: --- gcc/config/s390/s390.cc | 15 +++++++++++++++ gcc/testsuite/gcc.target/s390/delegitimize-1.c | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 645aedba67f0..d4e849b12de6 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 000000000000..5c49565db2f4 --- /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" } } */