diff options
author | Richard Biener <rguenther@suse.de> | 2016-09-01 13:38:25 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-09-01 13:38:25 +0000 |
commit | 2a99de7b1ebe7b38e756dc736b59a684a8d87e1d (patch) | |
tree | 2c5540b959e469b5363ccd20b388751a071d7d79 | |
parent | bc4ec5430bf8225f515242fc7c030eb891c32301 (diff) | |
download | gcc-2a99de7b1ebe7b38e756dc736b59a684a8d87e1d.zip gcc-2a99de7b1ebe7b38e756dc736b59a684a8d87e1d.tar.gz gcc-2a99de7b1ebe7b38e756dc736b59a684a8d87e1d.tar.bz2 |
re PR middle-end/77436 (Incorrect constant result for summing loop inserted)
2016-09-01 Richard Biener <rguenther@suse.de>
PR middle-end/77436
* tree-chrec.c (tree_fold_binomial): Use widest_int, properly
check whether the result fits the desired result type.
* gcc.dg/torture/pr77436.c: New testcase.
From-SVN: r239937
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr77436.c | 11 | ||||
-rw-r--r-- | gcc/tree-chrec.c | 18 |
4 files changed, 32 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad60eb2..c18752b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-09-01 Richard Biener <rguenther@suse.de> + + PR middle-end/77436 + * tree-chrec.c (tree_fold_binomial): Use widest_int, properly + check whether the result fits the desired result type. + 2016-09-01 Nathan Sidwell <nathan@acm.org> * config/nvptx/nvptx.md (cbranch<mode>4): Op 2 can be const. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c0af038..7213077 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-09-01 Richard Biener <rguenther@suse.de> + + PR middle-end/77436 + * gcc.dg/torture/pr77436.c: New testcase. + 2016-09-01 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> * gcc.dg/pr64252.c: Require int32plus. diff --git a/gcc/testsuite/gcc.dg/torture/pr77436.c b/gcc/testsuite/gcc.dg/torture/pr77436.c new file mode 100644 index 0000000..513867d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr77436.c @@ -0,0 +1,11 @@ +/* { dg-do run } */ + +int main() +{ + unsigned short sum = 0; + for (short x = -(__SHRT_MAX__ -1); x <= (__SHRT_MAX__ -1); x++) + sum += x; + if (sum != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 79f07b0..e7e47b1 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -490,7 +490,6 @@ tree_fold_binomial (tree type, tree n, unsigned int k) { bool overflow; unsigned int i; - tree res; /* Handle the most frequent cases. */ if (k == 0) @@ -498,18 +497,20 @@ tree_fold_binomial (tree type, tree n, unsigned int k) if (k == 1) return fold_convert (type, n); + widest_int num = wi::to_widest (n); + /* Check that k <= n. */ - if (wi::ltu_p (n, k)) + if (wi::ltu_p (num, k)) return NULL_TREE; /* Denominator = 2. */ - wide_int denom = wi::two (TYPE_PRECISION (TREE_TYPE (n))); + widest_int denom = 2; /* Index = Numerator-1. */ - wide_int idx = wi::sub (n, 1); + widest_int idx = num - 1; /* Numerator = Numerator*Index = n*(n-1). */ - wide_int num = wi::smul (n, idx, &overflow); + num = wi::smul (num, idx, &overflow); if (overflow) return NULL_TREE; @@ -528,9 +529,10 @@ tree_fold_binomial (tree type, tree n, unsigned int k) } /* Result = Numerator / Denominator. */ - wide_int di_res = wi::udiv_trunc (num, denom); - res = wide_int_to_tree (type, di_res); - return int_fits_type_p (res, type) ? res : NULL_TREE; + num = wi::udiv_trunc (num, denom); + if (! wi::fits_to_tree_p (num, type)) + return NULL_TREE; + return wide_int_to_tree (type, num); } /* Helper function. Use the Newton's interpolating formula for |