https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97027

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |msebor at gcc dot 
gnu.org
             Status|NEW                         |ASSIGNED
           Keywords|                            |missed-optimization

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
The following change seems to take care of the problem:

diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index ebb17cd852c..f04a1e4297d 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -4678,9 +4678,10 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT
offset,
       if (gimple_assign_single_p (stmt))
        {
          exp = gimple_assign_rhs1 (stmt);
-         if (TREE_CODE (exp) != MEM_REF)
+         if (TREE_CODE (exp) != CONSTRUCTOR
+             && TREE_CODE (exp) != MEM_REF)
            return false;
-         /* Handle MEM_REF below.  */
+         /* Handle CONSTRUCTOR and MEM_REF below.  */
        }
       else if (gimple_code (stmt) == GIMPLE_PHI)
        {
@@ -4704,6 +4705,23 @@ count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT
offset,
        }
     }

+  if (TREE_CODE (exp) == CONSTRUCTOR)
+    {
+      if (nbytes)
+       return false;
+
+      tree type = TREE_TYPE (exp);
+      tree size = TYPE_SIZE_UNIT (type);
+      if (!size || !tree_fits_uhwi_p (size))
+       return false;
+
+      unsigned HOST_WIDE_INT byte_size = tree_to_uhwi (size);
+      if (byte_size < offset)
+       return false;
+
+      nbytes = byte_size - offset;
+    }
+
   if (TREE_CODE (exp) == MEM_REF)
     {
       if (nbytes)

Reply via email to