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
This commit is contained in:
Richard Biener 2016-09-01 13:38:25 +00:00 committed by Richard Biener
parent bc4ec5430b
commit 2a99de7b1e
4 changed files with 32 additions and 8 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -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