https://gcc.gnu.org/g:da96bdfff0806e5a6f3f5ceb113add47037614c6

commit r16-1173-gda96bdfff0806e5a6f3f5ceb113add47037614c6
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Thu Jun 5 13:20:26 2025 +0200

    Fix crash with constant initializer caused by IPA
    
    The testcase compiled with -O2 -gnatn makes the compiler crash in
    vect_can_force_dr_alignment_p during SLP vectorization:
    
      if (decl_in_symtab_p (decl)
          && !symtab_node::get (decl)->can_increase_alignment_p ())
        return false;
    
    because symtab_node::get (decl) returns a null node.  The phenomenon occurs
    for a pair of twin symbols listed like so in .cgraph:
    
    Opt7_Pkg.T12b/17 (Opt7_Pkg.T12b)
      Type: variable definition analyzed
      Visibility: semantic_interposition external public artificial
      Aux: @0x44d45e0
      References:
      Referring: opt7_pkg__enum_name_table/13 (addr) 
opt7_pkg__enum_name_table/13
    (addr)
      Availability: not-ready
      Varpool flags: initialized read-only const-value-known
    
    Opt7_Pkg.T8b/16 (Opt7_Pkg.T8b)
      Type: variable definition analyzed
      Visibility: semantic_interposition external public artificial
      Aux: @0x7f9fda3fff00
      References:
      Referring: opt7_pkg__enum_name_table/13 (addr) 
opt7_pkg__enum_name_table/13
    (addr)
      Availability: not-ready
      Varpool flags: initialized read-only const-value-known
    
    with:
    
    opt7_pkg__enum_name_table/13 (Opt7_Pkg.Enum_Name_Table)
      Type: variable definition analyzed
      Visibility: semantic_interposition external public
      Aux: @0x44d45e0
      References: Opt7_Pkg.T8b/16 (addr) Opt7_Pkg.T8b/16 (addr) Opt7_Pkg.T12b/17
    (addr) Opt7_Pkg.T12b/17 (addr)
      Referring: opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
    opt7_pkg__image/2 (read) opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
    opt7_pkg__image/2 (read) opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
      Availability: not-ready
      Varpool flags: initialized read-only const-value-known
    
    being the crux of the matter.
    
    What happens is that symtab_remove_unreachable_nodes leaves the last symbol
    in kind of a limbo state: in .remove_symbols, we have:
    
    opt7_pkg__enum_name_table/13 (Opt7_Pkg.Enum_Name_Table)
      Type: variable
      Body removed by symtab_remove_unreachable_nodes
      Visibility: externally_visible semantic_interposition external public
      References:
      Referring: opt7_pkg__image/2 (read) opt7_pkg__image/2 (read)
      Availability: not_available
      Varpool flags: initialized read-only const-value-known
    
    This means that the "body" (DECL_INITIAL) of the symbol has been disregarded
    during reachability analysis, causing the first two symbols to be discarded:
    
    Reclaiming variables: Opt7_Pkg.T12b/17 Opt7_Pkg.T8b/16
    
    but the DECL_INITIAL is explicitly preserved for later constant folding,
    which makes it possible to retrofit the DECLs corresponding to the first
    two symbols in the GIMPLE IR and ultimately leads to the crash.
    
    gcc/
            * tree-vect-data-refs.cc (vect_can_force_dr_alignment_p): Return
            false if the variable has no symtab node.
    
    gcc/testsuite/
            * gnat.dg/specs/opt7.ads: New test.
            * gnat.dg/specs/opt7_pkg.ads: New helper.
            * gnat.dg/specs/opt7_pkg.adb: Likewise.

Diff:
---
 gcc/testsuite/gnat.dg/specs/opt7.ads     | 15 +++++++++++++++
 gcc/testsuite/gnat.dg/specs/opt7_pkg.adb | 15 +++++++++++++++
 gcc/testsuite/gnat.dg/specs/opt7_pkg.ads |  9 +++++++++
 gcc/tree-vect-data-refs.cc               |  3 ++-
 4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gnat.dg/specs/opt7.ads 
b/gcc/testsuite/gnat.dg/specs/opt7.ads
new file mode 100644
index 000000000000..ee151f082a88
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt7.ads
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -gnatn" }
+
+with Opt7_Pkg; use Opt7_Pkg;
+
+package Opt7 is
+
+  type Rec is record
+    E : Enum;
+  end record;
+
+  function Image (R : Rec) return String is
+    (if R.E = A then Image (R.E) else "");
+
+end Opt7;
diff --git a/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb 
b/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb
new file mode 100644
index 000000000000..1c9d79bb8721
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt7_pkg.adb
@@ -0,0 +1,15 @@
+package body Opt7_Pkg is
+
+  type Constant_String_Access is access constant String;
+
+  type Enum_Name is array (Enum) of Constant_String_Access;
+
+  Enum_Name_Table : constant Enum_Name :=
+    (A => new String'("A"), B => new String'("B"));
+
+  function Image (E : Enum) return String is
+  begin
+    return Enum_Name_Table (E).all;
+  end Image;
+
+end Opt7_Pkg;
diff --git a/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads 
b/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads
new file mode 100644
index 000000000000..2dd271b63adb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/opt7_pkg.ads
@@ -0,0 +1,9 @@
+-- { dg-excess-errors "no code generated" }
+
+package Opt7_Pkg is
+
+  type Enum is (A, B);
+
+  function Image (E : Enum) return String with Inline;
+
+end Opt7_Pkg;
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 1792ee4ea05f..036903a948f6 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -7249,7 +7249,8 @@ vect_can_force_dr_alignment_p (const_tree decl, 
poly_uint64 alignment)
     return false;
 
   if (decl_in_symtab_p (decl)
-      && !symtab_node::get (decl)->can_increase_alignment_p ())
+      && (!symtab_node::get (decl)
+         || !symtab_node::get (decl)->can_increase_alignment_p ()))
     return false;
 
   if (TREE_STATIC (decl))

Reply via email to