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> --- 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 94d5a1ebbd7..c060ef81a42 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -10569,7 +10569,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) @@ -10586,6 +10586,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 2790d0ffc65..5fcfdcda81b 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 5b63bf67fe0..fe8aee057b3 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 4ca08751a0d..9d64d3a8721 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 f791994e3b9..19990d67202 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 444ee31242f..b395ef6f054 100644 --- a/gcc/tree-ssa-loop-im.cc +++ b/gcc/tree-ssa-loop-im.cc @@ -1412,11 +1412,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 5f78c0be207..80f488a4f9a 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 4017eea3413..13bb85c4b71 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 -- 2.34.1