https://gcc.gnu.org/g:46c49068d0c4ee642d6122a8633bfe16e1cd2b42

commit 46c49068d0c4ee642d6122a8633bfe16e1cd2b42
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Tue Apr 29 11:29:26 2025 +0200

    Sauvegarde simplification MEM_REF.

Diff:
---
 gcc/gimple-fold.cc | 52 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index b64561396874..fc4397a49a02 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -340,6 +340,12 @@ maybe_fold_reference (tree expr)
   if (result && is_gimple_min_invariant (result))
     return result;
 
+  if (result
+      && TREE_CODE (result) == MEM_REF
+      && TREE_CODE (expr) == ARRAY_REF
+      && TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF)
+    return result;
+
   return NULL_TREE;
 }
 
@@ -10126,9 +10132,10 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) 
(tree))
         FIXME: This code can't handle nested references with variable indexes
         (they will be handled only by iteration of ccp).  Perhaps we can bring
         get_ref_base_and_extent here and make it use a valueize callback.  */
-      if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
-         && valueize
-         && (idx = (*valueize) (TREE_OPERAND (t, 1)))
+      if (((TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
+           && valueize
+           && (idx = (*valueize) (TREE_OPERAND (t, 1))))
+          || (idx = TREE_OPERAND (t, 1)))
          && poly_int_tree_p (idx))
        {
          tree low_bound, unit_size;
@@ -10139,12 +10146,13 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) 
(tree))
              && (unit_size = array_ref_element_size (t),
                  tree_fits_uhwi_p (unit_size)))
            {
-             poly_offset_int woffset
+             poly_offset_int woffset, woffset_bytes;
+             woffset_bytes
                = wi::sext (wi::to_poly_offset (idx)
                            - wi::to_poly_offset (low_bound),
                            TYPE_PRECISION (sizetype));
-             woffset *= tree_to_uhwi (unit_size);
-             woffset *= BITS_PER_UNIT;
+             woffset_bytes *= tree_to_uhwi (unit_size);
+             woffset = woffset_bytes * BITS_PER_UNIT;
              if (woffset.to_shwi (&offset))
                {
                  base = TREE_OPERAND (t, 0);
@@ -10157,12 +10165,32 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) 
(tree))
                  if (maybe_lt (offset, 0))
                    return NULL_TREE;
                  /* We cannot determine ctor.  */
-                 if (!ctor)
-                   return NULL_TREE;
-                 return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
-                                             tree_to_uhwi (unit_size)
-                                             * BITS_PER_UNIT,
-                                             base);
+                 if (ctor)
+                   return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
+                                               tree_to_uhwi (unit_size)
+                                               * BITS_PER_UNIT,
+                                               base);
+                 if (TREE_CODE (base) == MEM_REF)
+                   {
+                     woffset_bytes += wi::to_offset (TREE_OPERAND (base, 1));
+                     tree offset_type = TREE_TYPE (TREE_OPERAND (base, 1));
+                     if (TREE_CODE (offset_type) == POINTER_TYPE
+                         && TREE_CODE (TREE_TYPE (offset_type)) == ARRAY_TYPE)
+                       {
+                         tree type = build_pointer_type (
+                                 TREE_TYPE (TREE_TYPE (offset_type)));
+                         if (wi::fits_to_tree_p (woffset_bytes, type))
+                           {
+                             tree offset = wide_int_to_tree (type,
+                                                             woffset_bytes);
+                             return fold_build2_loc (EXPR_LOCATION (t), 
MEM_REF,
+                                                     TREE_TYPE (t),
+                                                     TREE_OPERAND (base, 0),
+                                                     offset);
+                           }
+                       }
+
+                   }
                }
            }
        }

Reply via email to