aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-09-26 23:25:17 +0000
committerAndrew Pinski <quic_apinski@quicinc.com>2025-05-07 14:33:06 +0000
commitd884e9c5c746a41b069905f990fa72b9e550cccc (patch)
treead5743e371edcb3eb5c0c909541e973fb9574f18
parent8335fd561fa823d32556512c09dfce44463e8eaa (diff)
downloadgcc-d884e9c5c746a41b069905f990fa72b9e550cccc.zip
gcc-d884e9c5c746a41b069905f990fa72b9e550cccc.tar.gz
gcc-d884e9c5c746a41b069905f990fa72b9e550cccc.tar.bz2
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_apinski@quicinc.com>
-rw-r--r--gcc/gimple-fold.cc26
-rw-r--r--gcc/gimple-fold.h2
-rw-r--r--gcc/tree-if-conv.cc16
-rw-r--r--gcc/tree-scalar-evolution.cc5
-rw-r--r--gcc/tree-ssa-ifcombine.cc10
-rw-r--r--gcc/tree-ssa-loop-im.cc6
-rw-r--r--gcc/tree-ssa-loop-split.cc5
-rw-r--r--gcc/tree-ssa-reassoc.cc40
8 files changed, 50 insertions, 60 deletions
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 5884b79..7721795 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 2790d0f..5fcfdcd 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 5b63bf6..fe8aee0 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 4ca0875..9d64d3a 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 f791994..19990d6 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 b7f9f9b..ae2fd87 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 5f78c0b..80f488a 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 4017eea..13bb85c 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