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

commit r16-449-gd884e9c5c746a41b069905f990fa72b9e550cccc
Author: Andrew Pinski <quic_apin...@quicinc.com>
Date:   Thu Sep 26 23:25:17 2024 +0000

    gimple: Add gimple_with_undefined_signed_overflow and use it [PR111276]
    
    While looking into the ifcombine, I noticed that rewrite_to_defined_overflow
    was rewriting already defined code. In the previous attempt at fixing this,
    the review mentioned we should not be calling rewrite_to_defined_overflow
    in those cases. The places which called rewrite_to_defined_overflow didn't
    always check the lhs of the assignment. This fixes the problem by
    introducing a helper function which is to be used before calling
    rewrite_to_defined_overflow.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
    gcc/ChangeLog:
    
            PR tree-optimization/111276
            * gimple-fold.cc (arith_code_with_undefined_signed_overflow): Make 
static.
            (gimple_with_undefined_signed_overflow): New function.
            * gimple-fold.h (arith_code_with_undefined_signed_overflow): Remove.
            (gimple_with_undefined_signed_overflow): Add declaration.
            * tree-if-conv.cc (if_convertible_gimple_assign_stmt_p): Use
            gimple_with_undefined_signed_overflow instead of manually
            checking lhs and the code of the stmt.
            (predicate_statements): Likewise.
            * tree-ssa-ifcombine.cc (ifcombine_rewrite_to_defined_overflow): 
Likewise.
            * tree-ssa-loop-im.cc (move_computations_worker): Likewise.
            * tree-ssa-reassoc.cc (update_range_test): Likewise. Reformat.
            * tree-scalar-evolution.cc (final_value_replacement_loop): Use
            gimple_with_undefined_signed_overflow instead of
            arith_code_with_undefined_signed_overflow.
            * tree-ssa-loop-split.cc (split_loop): Likewise.
    
    Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>

Diff:
---
 gcc/gimple-fold.cc           | 26 +++++++++++++++++++++++++-
 gcc/gimple-fold.h            |  2 +-
 gcc/tree-if-conv.cc          | 16 +++-------------
 gcc/tree-scalar-evolution.cc |  5 +----
 gcc/tree-ssa-ifcombine.cc    | 10 ++--------
 gcc/tree-ssa-loop-im.cc      |  6 +-----
 gcc/tree-ssa-loop-split.cc   |  5 +----
 gcc/tree-ssa-reassoc.cc      | 40 ++++++++++++++++------------------------
 8 files changed, 50 insertions(+), 60 deletions(-)

diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 5884b79cce5a..7721795b20df 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -10573,7 +10573,7 @@ gimple_fold_indirect_ref (tree t)
    integer types involves undefined behavior on overflow and the
    operation can be expressed with unsigned arithmetic.  */
 
-bool
+static bool
 arith_code_with_undefined_signed_overflow (tree_code code)
 {
   switch (code)
@@ -10590,6 +10590,30 @@ arith_code_with_undefined_signed_overflow (tree_code 
code)
     }
 }
 
+/* Return true if STMT has an operation that operates on a signed
+   integer types involves undefined behavior on overflow and the
+   operation can be expressed with unsigned arithmetic.  */
+
+bool
+gimple_with_undefined_signed_overflow (gimple *stmt)
+{
+  if (!is_gimple_assign (stmt))
+    return false;
+  tree lhs = gimple_assign_lhs (stmt);
+  if (!lhs)
+    return false;
+  tree lhs_type = TREE_TYPE (lhs);
+  if (!INTEGRAL_TYPE_P (lhs_type)
+      && !POINTER_TYPE_P (lhs_type))
+    return false;
+  if (!TYPE_OVERFLOW_UNDEFINED (lhs_type))
+    return false;
+  if (!arith_code_with_undefined_signed_overflow
+       (gimple_assign_rhs_code (stmt)))
+    return false;
+  return true;
+}
+
 /* Rewrite STMT, an assignment with a signed integer or pointer arithmetic
    operation that can be transformed to unsigned arithmetic by converting
    its operand, carrying out the operation in the corresponding unsigned
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 2790d0ffc652..5fcfdcda81b1 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -59,7 +59,7 @@ extern tree gimple_get_virt_method_for_vtable (HOST_WIDE_INT, 
tree,
 extern tree gimple_fold_indirect_ref (tree);
 extern bool gimple_fold_builtin_sprintf (gimple_stmt_iterator *);
 extern bool gimple_fold_builtin_snprintf (gimple_stmt_iterator *);
-extern bool arith_code_with_undefined_signed_overflow (tree_code);
+extern bool gimple_with_undefined_signed_overflow (gimple *);
 extern void rewrite_to_defined_overflow (gimple_stmt_iterator *);
 extern gimple_seq rewrite_to_defined_overflow (gimple *);
 extern void replace_call_with_value (gimple_stmt_iterator *, tree);
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 5b63bf67fe0e..fe8aee057b34 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -1066,11 +1066,7 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt,
        fprintf (dump_file, "tree could trap...\n");
       return false;
     }
-  else if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
-           || POINTER_TYPE_P (TREE_TYPE (lhs)))
-          && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
-          && arith_code_with_undefined_signed_overflow
-                               (gimple_assign_rhs_code (stmt)))
+  else if (gimple_with_undefined_signed_overflow (stmt))
     /* We have to rewrite stmts with undefined overflow.  */
     need_to_rewrite_undefined = true;
 
@@ -2830,7 +2826,6 @@ predicate_statements (loop_p loop)
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
        {
          gassign *stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
-         tree lhs;
          if (!stmt)
            ;
          else if (is_false_predicate (cond)
@@ -2886,12 +2881,7 @@ predicate_statements (loop_p loop)
 
              gsi_replace (&gsi, new_stmt, true);
            }
-         else if (((lhs = gimple_assign_lhs (stmt)), true)
-                  && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
-                      || POINTER_TYPE_P (TREE_TYPE (lhs)))
-                  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
-                  && arith_code_with_undefined_signed_overflow
-                                               (gimple_assign_rhs_code (stmt)))
+         else if (gimple_with_undefined_signed_overflow (stmt))
            rewrite_to_defined_overflow (&gsi);
          else if (gimple_vdef (stmt))
            {
@@ -2946,7 +2936,7 @@ predicate_statements (loop_p loop)
              gsi_replace (&gsi, new_call, true);
            }
 
-         lhs = gimple_get_lhs (gsi_stmt (gsi));
+         tree lhs = gimple_get_lhs (gsi_stmt (gsi));
          if (lhs && TREE_CODE (lhs) == SSA_NAME)
            ssa_names.add (lhs);
          gsi_next (&gsi);
diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 4ca08751a0d3..9d64d3a87217 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -3932,10 +3932,7 @@ final_value_replacement_loop (class loop *loop)
          gsi2 = gsi_start (stmts);
          while (!gsi_end_p (gsi2))
            {
-             gimple *stmt = gsi_stmt (gsi2);
-             if (is_gimple_assign (stmt)
-                 && arith_code_with_undefined_signed_overflow
-                      (gimple_assign_rhs_code (stmt)))
+             if (gimple_with_undefined_signed_overflow (gsi_stmt (gsi2)))
                rewrite_to_defined_overflow (&gsi2);
              gsi_next (&gsi2);
            }
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index f791994e3b9b..19990d67202c 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -514,15 +514,9 @@ ifcombine_mark_ssa_name_walk (tree *t, int *, void *data_)
 static inline void
 ifcombine_rewrite_to_defined_overflow (gimple_stmt_iterator gsi)
 {
-  gassign *ass = dyn_cast <gassign *> (gsi_stmt (gsi));
-  if (!ass)
+  if (!gimple_with_undefined_signed_overflow (gsi_stmt (gsi)))
     return;
-  tree lhs = gimple_assign_lhs (ass);
-  if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
-       || POINTER_TYPE_P (TREE_TYPE (lhs)))
-      && arith_code_with_undefined_signed_overflow
-      (gimple_assign_rhs_code (ass)))
-    rewrite_to_defined_overflow (&gsi);
+  rewrite_to_defined_overflow (&gsi);
 }
 
 
diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index b7f9f9befa54..ae2fd87d5894 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -1419,11 +1419,7 @@ move_computations_worker (basic_block bb)
          when the target loop header is executed and the stmt may
         invoke undefined integer or pointer overflow rewrite it to
         unsigned arithmetic.  */
-      if (is_gimple_assign (stmt)
-         && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
-         && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (gimple_assign_lhs (stmt)))
-         && arith_code_with_undefined_signed_overflow
-              (gimple_assign_rhs_code (stmt))
+      if (gimple_with_undefined_signed_overflow (stmt)
          && (!ALWAYS_EXECUTED_IN (bb)
              || !(ALWAYS_EXECUTED_IN (bb) == level
                   || flow_loop_nested_p (ALWAYS_EXECUTED_IN (bb), level))))
diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc
index 5f78c0be2075..80f488a4f9ae 100644
--- a/gcc/tree-ssa-loop-split.cc
+++ b/gcc/tree-ssa-loop-split.cc
@@ -663,10 +663,7 @@ split_loop (class loop *loop1)
                gsi = gsi_start (stmts2);
                while (!gsi_end_p (gsi))
                  {
-                   gimple *stmt = gsi_stmt (gsi);
-                   if (is_gimple_assign (stmt)
-                       && arith_code_with_undefined_signed_overflow
-                                               (gimple_assign_rhs_code (stmt)))
+                   if (gimple_with_undefined_signed_overflow (gsi_stmt (gsi)))
                      rewrite_to_defined_overflow (&gsi);
                    gsi_next (&gsi);
                  }
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 4017eea34135..13bb85c4b712 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -2925,30 +2925,22 @@ update_range_test (struct range_entry *range, struct 
range_entry *otherrange,
         !gsi_end_p (gsi); gsi_next (&gsi))
       {
        gimple *stmt = gsi_stmt (gsi);
-       if (is_gimple_assign (stmt))
-         if (tree lhs = gimple_assign_lhs (stmt))
-           if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
-                || POINTER_TYPE_P (TREE_TYPE (lhs)))
-               && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)))
-             {
-               enum tree_code code = gimple_assign_rhs_code (stmt);
-               if (arith_code_with_undefined_signed_overflow (code))
-                 {
-                   gimple_stmt_iterator gsip = gsi;
-                   gimple_stmt_iterator gsin = gsi;
-                   gsi_prev (&gsip);
-                   gsi_next (&gsin);
-                   rewrite_to_defined_overflow (&gsi);
-                   unsigned uid = gimple_uid (stmt);
-                   if (gsi_end_p (gsip))
-                     gsip = gsi_after_labels (bb);
-                   else
-                     gsi_next (&gsip);
-                   for (; gsi_stmt (gsip) != gsi_stmt (gsin);
-                        gsi_next (&gsip))
-                     gimple_set_uid (gsi_stmt (gsip), uid);
-                 }
-             }
+       if (gimple_with_undefined_signed_overflow (stmt))
+         {
+           gimple_stmt_iterator gsip = gsi;
+           gimple_stmt_iterator gsin = gsi;
+           gsi_prev (&gsip);
+           gsi_next (&gsin);
+           rewrite_to_defined_overflow (&gsi);
+           unsigned uid = gimple_uid (stmt);
+           if (gsi_end_p (gsip))
+             gsip = gsi_after_labels (bb);
+           else
+             gsi_next (&gsip);
+           for (; gsi_stmt (gsip) != gsi_stmt (gsin);
+                gsi_next (&gsip))
+             gimple_set_uid (gsi_stmt (gsip), uid);
+         }
       }
 
   if (opcode == BIT_IOR_EXPR

Reply via email to