From 3c0194d7ff21d61c02f3c6b111c83ef24a69e1f0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 11 Oct 2021 12:27:10 +0200 Subject: [PATCH] tree-optimization/102659 - avoid undefined overflow after if-conversion The following makes sure to rewrite arithmetic with undefined behavior on overflow to a well-defined variant when moving them to be always executed as part of doing if-conversion for loop vectorization. 2021-10-11 Richard Biener PR tree-optimization/102659 * tree-if-conv.c (need_to_rewrite_undefined): New flag. (if_convertible_gimple_assign_stmt_p): Mark the loop for rewrite when stmts with undefined behavior on integer overflow appear. (combine_blocks): Predicate also when we need to rewrite stmts. (predicate_statements): Rewrite affected stmts to something with well-defined behavior on overflow. (tree_if_conversion): Initialize need_to_rewrite_undefined. * gcc.dg/torture/pr69760.c: Adjust the testcase. * gcc.target/i386/avx2-vect-mask-store-move1.c: Expect to move the conversions to unsigned as well. --- gcc/testsuite/gcc.dg/torture/pr69760.c | 3 +-- .../gcc.target/i386/avx2-vect-mask-store-move1.c | 2 +- gcc/tree-if-conv.c | 28 +++++++++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr69760.c b/gcc/testsuite/gcc.dg/torture/pr69760.c index 53733c7..47e01ae 100644 --- a/gcc/testsuite/gcc.dg/torture/pr69760.c +++ b/gcc/testsuite/gcc.dg/torture/pr69760.c @@ -1,11 +1,10 @@ /* PR tree-optimization/69760 */ /* { dg-do run { target { { *-*-linux* *-*-gnu* *-*-uclinux* } && mmap } } } */ -/* { dg-options "-O2" } */ #include #include -__attribute__((noinline, noclone)) void +__attribute__((noinline, noclone)) static void test_func (double *a, int L, int m, int n, int N) { int i, k; diff --git a/gcc/testsuite/gcc.target/i386/avx2-vect-mask-store-move1.c b/gcc/testsuite/gcc.target/i386/avx2-vect-mask-store-move1.c index 989ba40..6a47a09 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-vect-mask-store-move1.c +++ b/gcc/testsuite/gcc.target/i386/avx2-vect-mask-store-move1.c @@ -78,4 +78,4 @@ avx2_test (void) abort (); } -/* { dg-final { scan-tree-dump-times "Move stmt to created bb" 6 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Move stmt to created bb" 10 "vect" } } */ diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index d7b7b30..6a67acf 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -132,6 +132,11 @@ along with GCC; see the file COPYING3. If not see predicate_statements for the kinds of predication we support. */ static bool need_to_predicate; +/* True if we have to rewrite stmts that may invoke undefined behavior + when a condition C was false so it doesn't if it is always executed. + See predicate_statements for the kinds of predication we support. */ +static bool need_to_rewrite_undefined; + /* Indicate if there are any complicated PHIs that need to be handled in if-conversion. Complicated PHI has more than two arguments and can't be degenerated to two arguments PHI. See more information in comment @@ -1042,6 +1047,12 @@ 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)) + && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)) + && arith_code_with_undefined_signed_overflow + (gimple_assign_rhs_code (stmt))) + /* We have to rewrite stmts with undefined overflow. */ + need_to_rewrite_undefined = true; /* When if-converting stores force versioning, likewise if we ended up generating store data races. */ @@ -2563,6 +2574,20 @@ 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))) + && 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_SAME_STMT); + if (gsi_end_p (gsi)) + gsi = gsi_last_bb (gimple_bb (stmt)); + else + gsi_prev (&gsi); + } else if (gimple_vdef (stmt)) { tree lhs = gimple_assign_lhs (stmt); @@ -2647,7 +2672,7 @@ combine_blocks (class loop *loop) insert_gimplified_predicates (loop); predicate_all_scalar_phis (loop); - if (need_to_predicate) + if (need_to_predicate || need_to_rewrite_undefined) predicate_statements (loop); /* Merge basic blocks. */ @@ -3148,6 +3173,7 @@ tree_if_conversion (class loop *loop, vec *preds) rloop = NULL; ifc_bbs = NULL; need_to_predicate = false; + need_to_rewrite_undefined = false; any_complicated_phi = false; /* Apply more aggressive if-conversion when loop or its outer loop were -- 2.7.4