aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-10-11 12:27:10 +0200
committerRichard Biener <rguenther@suse.de>2021-10-13 13:11:12 +0200
commit3c0194d7ff21d61c02f3c6b111c83ef24a69e1f0 (patch)
tree8ffe45c73c7ed019e0f9f1eea777ed3eb47e9b9f
parent77c7abe3588d407ed820224f8d1b1a17a16831a0 (diff)
downloadgcc-3c0194d7ff21d61c02f3c6b111c83ef24a69e1f0.zip
gcc-3c0194d7ff21d61c02f3c6b111c83ef24a69e1f0.tar.gz
gcc-3c0194d7ff21d61c02f3c6b111c83ef24a69e1f0.tar.bz2
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 <rguenther@suse.de> 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.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr69760.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-vect-mask-store-move1.c2
-rw-r--r--gcc/tree-if-conv.c28
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 <unistd.h>
#include <sys/mman.h>
-__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<gimple *> *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