diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2024-09-26 23:25:17 +0000 |
---|---|---|
committer | Andrew Pinski <quic_apinski@quicinc.com> | 2025-05-07 14:33:06 +0000 |
commit | d884e9c5c746a41b069905f990fa72b9e550cccc (patch) | |
tree | ad5743e371edcb3eb5c0c909541e973fb9574f18 | |
parent | 8335fd561fa823d32556512c09dfce44463e8eaa (diff) | |
download | gcc-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.cc | 26 | ||||
-rw-r--r-- | gcc/gimple-fold.h | 2 | ||||
-rw-r--r-- | gcc/tree-if-conv.cc | 16 | ||||
-rw-r--r-- | gcc/tree-scalar-evolution.cc | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-ifcombine.cc | 10 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.cc | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-split.cc | 5 | ||||
-rw-r--r-- | 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 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 |