aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2023-08-11 00:23:14 +0200
committerJan Hubicka <jh@suse.cz>2023-08-11 00:23:14 +0200
commit39204ae9ddbfca710880d7f5fda48234a1e85e4e (patch)
treec5457d18279e722c9917a3380ad826e9e70658f7 /gcc
parent0ac323238e91c6093709ce8f4176c0c8fb1a693d (diff)
downloadgcc-39204ae9ddbfca710880d7f5fda48234a1e85e4e.zip
gcc-39204ae9ddbfca710880d7f5fda48234a1e85e4e.tar.gz
gcc-39204ae9ddbfca710880d7f5fda48234a1e85e4e.tar.bz2
Fix division by zero in loop splitting
Profile update I added to tree-ssa-loop-split can divide by zero in situation that the conditional is predicted with 0 probability which is triggered by jump threading update in the testcase. gcc/ChangeLog: PR middle-end/110923 * tree-ssa-loop-split.cc (split_loop): Watch for division by zero. gcc/testsuite/ChangeLog: PR middle-end/110923 * gcc.dg/tree-ssa/pr110923.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr110923.c14
-rw-r--r--gcc/tree-ssa-loop-split.cc12
2 files changed, 22 insertions, 4 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110923.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110923.c
new file mode 100644
index 0000000..8f5720a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110923.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-lsplit-details-blocks" } */
+int a, b, c, d;
+int main() {
+ for (a = 0; a < 2; a++) {
+ if (b > 2)
+ c = 0;
+ if (b > a)
+ d = 0;
+ }
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "loop split" 1 "lsplit" } } */
+/* { dg-final { scan-tree-dump-not "Invalid sum" "lsplit" } } */
diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc
index 2f7918c..6446480 100644
--- a/gcc/tree-ssa-loop-split.cc
+++ b/gcc/tree-ssa-loop-split.cc
@@ -703,7 +703,7 @@ split_loop (class loop *loop1)
split between of the two new loops. Keep orignal estimate since
it is likely better then completely dropping it.
- TODO: If we know that onle of the new loops has constant
+ TODO: If we know that one of the new loops has constant
number of iterations, we can do better. We could also update
upper bounds. */
if (loop1->any_estimate
@@ -713,11 +713,15 @@ split_loop (class loop *loop1)
? true_edge->probability.to_sreal () : (sreal)1;
sreal scale2 = false_edge->probability.reliable_p ()
? false_edge->probability.to_sreal () : (sreal)1;
+ sreal div1 = loop1_prob.to_sreal ();
/* +1 to get header interations rather than latch iterations and then
-1 to convert back. */
- loop1->nb_iterations_estimate
- = MAX ((((sreal)loop1->nb_iterations_estimate.to_shwi () + 1) * scale
- / loop1_prob.to_sreal ()).to_nearest_int () - 1, 0);
+ if (div1 != 0)
+ loop1->nb_iterations_estimate
+ = MAX ((((sreal)loop1->nb_iterations_estimate.to_shwi () + 1)
+ * scale / div1).to_nearest_int () - 1, 0);
+ else
+ loop1->any_estimate = false;
loop2->nb_iterations_estimate
= MAX ((((sreal)loop2->nb_iterations_estimate.to_shwi () + 1) * scale2
/ profile_probability::very_likely ().to_sreal ())