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

Reply via email to