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>
This commit is contained in:
Juergen Christ 2025-03-10 10:03:36 +01:00
parent dc47161c1f
commit 4001281d69
2 changed files with 37 additions and 0 deletions

View file

@ -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;

View file

@ -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" } } */