summaryrefslogtreecommitdiff
path: root/gcc/tree-chrec.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-09-01 13:38:25 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-09-01 13:38:25 +0000
commit2a99de7b1ebe7b38e756dc736b59a684a8d87e1d (patch)
tree2c5540b959e469b5363ccd20b388751a071d7d79 /gcc/tree-chrec.c
parentbc4ec5430bf8225f515242fc7c030eb891c32301 (diff)
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
Diffstat (limited to 'gcc/tree-chrec.c')
-rw-r--r--gcc/tree-chrec.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 79f07b029d1..e7e47b1bc52 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