diff options
author | Richard Biener <rguenther@suse.de> | 2023-02-20 12:58:50 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-02-21 14:02:58 +0100 |
commit | a7e706df2280de4a42f68b6c44401e4348d3593c (patch) | |
tree | e693cda033b51bd08424591afdde3fa0a296f2d5 | |
parent | e28c5b33b987374f753b32306b0d3ecf610b64f2 (diff) | |
download | gcc-a7e706df2280de4a42f68b6c44401e4348d3593c.zip gcc-a7e706df2280de4a42f68b6c44401e4348d3593c.tar.gz gcc-a7e706df2280de4a42f68b6c44401e4348d3593c.tar.bz2 |
tree-optimization/108793 - niter compute type mismatch
When computing the number of iterations until wrap types are mixed up,
eventually leading to checking ICEs with a pointer bitwise inversion.
The following uses niter_type for the calculation.
PR tree-optimization/108793
* tree-ssa-loop-niter.cc (number_of_iterations_until_wrap):
Use convert operands to niter_type when computing num.
* gcc.dg/torture/pr108793.c: New testcase.
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr108793.c | 10 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.cc | 11 |
2 files changed, 16 insertions, 5 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr108793.c b/gcc/testsuite/gcc.dg/torture/pr108793.c new file mode 100644 index 0000000..83973eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr108793.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ + +typedef int *p; +extern p a[], b[]; +int f () { + int n = 0; + for (p* i = &a[0]; i > &b[0]; i++) + n++; + return n; +} diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 1ce5e73..dc4c7a4 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -1494,8 +1494,9 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0, if (integer_zerop (assumptions)) return false; - num = fold_build2 (MINUS_EXPR, niter_type, wide_int_to_tree (type, max), - iv1->base); + num = fold_build2 (MINUS_EXPR, niter_type, + wide_int_to_tree (niter_type, max), + fold_convert (niter_type, iv1->base)); /* When base has the form iv + 1, if we know iv >= n, then iv + 1 < n only when iv + 1 overflows, i.e. when iv == TYPE_VALUE_MAX. */ @@ -1531,8 +1532,9 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0, if (integer_zerop (assumptions)) return false; - num = fold_build2 (MINUS_EXPR, niter_type, iv0->base, - wide_int_to_tree (type, min)); + num = fold_build2 (MINUS_EXPR, niter_type, + fold_convert (niter_type, iv0->base), + wide_int_to_tree (niter_type, min)); low = min; if (TREE_CODE (iv0->base) == INTEGER_CST) high = wi::to_wide (iv0->base) + 1; @@ -1546,7 +1548,6 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0, /* (delta + step - 1) / step */ step = fold_convert (niter_type, step); - num = fold_convert (niter_type, num); num = fold_build2 (PLUS_EXPR, niter_type, num, step); niter->niter = fold_build2 (FLOOR_DIV_EXPR, niter_type, num, step); |