From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id F33AA3858031; Thu, 14 Oct 2021 12:58:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F33AA3858031 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-4398] tree-optimization/102659 - really avoid undef overflow in if-conversion X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 4cb52980e5d5fb64a393d385923da1b51ab34606 X-Git-Newrev: 9b2ad21ab3ebc21a3408108327fa1a7cbedaf217 Message-Id: <20211014125853.F33AA3858031@sourceware.org> Date: Thu, 14 Oct 2021 12:58:53 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Oct 2021 12:58:54 -0000 https://gcc.gnu.org/g:9b2ad21ab3ebc21a3408108327fa1a7cbedaf217 commit r12-4398-g9b2ad21ab3ebc21a3408108327fa1a7cbedaf217 Author: Richard Biener Date: Thu Oct 14 09:00:25 2021 +0200 tree-optimization/102659 - really avoid undef overflow in if-conversion This plugs the remaining hole of POINTER_PLUS_EXPR with undefined overflow. Unfortunately we have to go through some lengths to not put invariant conversions into the loop body since that confuses the vectorizers gather/scatter discovery which relies on identifying an invariant component of plus and minus expressions. We can emit those in the loop preheader but then we have to accept that being non-empty when looking for the LOOP_VECTORIZED internal function call in the vectorizer. 2021-10-14 Richard Biener PR tree-optimization/102659 * tree-if-conv.c (if_convertible_gimple_assign_stmt_p): Also rewrite pointer typed undefined overflow operations. (predicate_statements): Likewise. Make sure to emit invariant conversions in the preheader. * tree-vectorizer.c (vect_loop_vectorized_call): Look through non-empty preheaders. * tree-data-ref.c (dr_analyze_indices): Strip useless conversions to the MEM_REF base type. Diff: --- gcc/tree-data-ref.c | 1 + gcc/tree-if-conv.c | 37 ++++++++++++++++++++++++++++++------- gcc/tree-vectorizer.c | 3 ++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 18307a554fc..57bac06242f 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1370,6 +1370,7 @@ dr_analyze_indices (struct indices *dri, tree ref, edge nest, loop_p loop) tree op = TREE_OPERAND (ref, 0); tree access_fn = analyze_scalar_evolution (loop, op); access_fn = instantiate_scev (nest, loop, access_fn); + STRIP_NOPS (access_fn); if (TREE_CODE (access_fn) == POLYNOMIAL_CHREC) { tree memoff = TREE_OPERAND (ref, 1); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 0b6b07cfac6..15dcc1e2b94 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1047,7 +1047,8 @@ 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)) + 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))) @@ -2520,6 +2521,7 @@ predicate_statements (loop_p loop) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) { gassign *stmt = dyn_cast (gsi_stmt (gsi)); + tree lhs; if (!stmt) ; else if (is_false_predicate (cond) @@ -2574,15 +2576,36 @@ predicate_statements (loop_p loop) gsi_replace (&gsi, new_stmt, true); } - else if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))) - && TYPE_OVERFLOW_UNDEFINED - (TREE_TYPE (gimple_assign_lhs (stmt))) + 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))) { gsi_remove (&gsi, true); - gsi_insert_seq_before (&gsi, rewrite_to_defined_overflow (stmt), - GSI_LAST_NEW_STMT); + gimple_seq stmts = rewrite_to_defined_overflow (stmt); + bool first = true; + for (gimple_stmt_iterator gsi2 = gsi_start (stmts); + !gsi_end_p (gsi2);) + { + gassign *stmt2 = as_a (gsi_stmt (gsi2)); + gsi_remove (&gsi2, false); + /* Make sure to move invariant conversions out of the + loop. */ + if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt2)) + && expr_invariant_in_loop_p (loop, + gimple_assign_rhs1 (stmt2))) + gsi_insert_on_edge_immediate (loop_preheader_edge (loop), + stmt2); + else if (first) + { + gsi_insert_before (&gsi, stmt2, GSI_NEW_STMT); + first = false; + } + else + gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT); + } } else if (gimple_vdef (stmt)) { @@ -2601,7 +2624,7 @@ predicate_statements (loop_p loop) gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi)); update_stmt (stmt); } - tree lhs = gimple_get_lhs (gsi_stmt (gsi)); + 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-vectorizer.c b/gcc/tree-vectorizer.c index 20daa31187d..4712dc6e7f9 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -852,7 +852,8 @@ vect_loop_vectorized_call (class loop *loop, gcond **cond) do { g = last_stmt (bb); - if (g) + if ((g && gimple_code (g) == GIMPLE_COND) + || !single_succ_p (bb)) break; if (!single_pred_p (bb)) break;