Commit 0425d6f5 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/47538 (GNU Scientific Library miscompiled by gcc 4.6)

	PR tree-optimization/47538
	* tree-ssa-ccp.c (bit_value_binop_1): For uns computation use
	type instead of r1type, except for comparisons.  For right
	shifts and comparisons punt if there are mismatches in
	sizetype vs. non-sizetype types.

	* gcc.c-torture/execute/pr47538.c: New test.

Co-Authored-By: Richard Guenther <rguenther@suse.de>

From-SVN: r169441
parent 529da9b5
2011-01-31 Jakub Jelinek <jakub@redhat.com>
Richard Guenther <rguenther@suse.de>
PR tree-optimization/47538
* tree-ssa-ccp.c (bit_value_binop_1): For uns computation use
type instead of r1type, except for comparisons. For right
shifts and comparisons punt if there are mismatches in
sizetype vs. non-sizetype types.
2011-01-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-01-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* doc/sourcebuild.texi (Effective-Target Keywords): Document * doc/sourcebuild.texi (Effective-Target Keywords): Document
......
2011-01-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/47538
* gcc.c-torture/execute/pr47538.c: New test.
2011-01-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-01-31 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR target/45325 PR target/45325
......
/* PR tree-optimization/47538 */
struct S
{
double a, b, *c;
unsigned long d;
};
__attribute__((noinline, noclone)) void
foo (struct S *x, const struct S *y)
{
const unsigned long n = y->d + 1;
const double m = 0.25 * (y->b - y->a);
x->a = y->a;
x->b = y->b;
if (n == 1)
{
x->c[0] = 0.;
}
else if (n == 2)
{
x->c[1] = m * y->c[0];
x->c[0] = 2.0 * x->c[1];
}
else
{
double o = 0.0, p = 1.0;
unsigned long i;
for (i = 1; i <= n - 2; i++)
{
x->c[i] = m * (y->c[i - 1] - y->c[i + 1]) / (double) i;
o += p * x->c[i];
p = -p;
}
x->c[n - 1] = m * y->c[n - 2] / (n - 1.0);
o += p * x->c[n - 1];
x->c[0] = 2.0 * o;
}
}
int
main (void)
{
struct S x, y;
double c[4] = { 10, 20, 30, 40 }, d[4], e[4] = { 118, 118, 118, 118 };
y.a = 10;
y.b = 6;
y.c = c;
x.c = d;
y.d = 3;
__builtin_memcpy (d, e, sizeof d);
foo (&x, &y);
if (d[0] != 0 || d[1] != 20 || d[2] != 10 || d[3] != -10)
__builtin_abort ();
y.d = 2;
__builtin_memcpy (d, e, sizeof d);
foo (&x, &y);
if (d[0] != 60 || d[1] != 20 || d[2] != -10 || d[3] != 118)
__builtin_abort ();
y.d = 1;
__builtin_memcpy (d, e, sizeof d);
foo (&x, &y);
if (d[0] != -20 || d[1] != -10 || d[2] != 118 || d[3] != 118)
__builtin_abort ();
y.d = 0;
__builtin_memcpy (d, e, sizeof d);
foo (&x, &y);
if (d[0] != 0 || d[1] != 118 || d[2] != 118 || d[3] != 118)
__builtin_abort ();
return 0;
}
...@@ -1768,8 +1768,8 @@ bit_value_binop_1 (enum tree_code code, tree type, ...@@ -1768,8 +1768,8 @@ bit_value_binop_1 (enum tree_code code, tree type,
tree r1type, double_int r1val, double_int r1mask, tree r1type, double_int r1val, double_int r1mask,
tree r2type, double_int r2val, double_int r2mask) tree r2type, double_int r2val, double_int r2mask)
{ {
bool uns = (TREE_CODE (r1type) == INTEGER_TYPE bool uns = (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type)); && TYPE_IS_SIZETYPE (type) ? 0 : TYPE_UNSIGNED (type));
/* Assume we'll get a constant result. Use an initial varying value, /* Assume we'll get a constant result. Use an initial varying value,
we fall back to varying in the end if necessary. */ we fall back to varying in the end if necessary. */
*mask = double_int_minus_one; *mask = double_int_minus_one;
...@@ -1836,6 +1836,13 @@ bit_value_binop_1 (enum tree_code code, tree type, ...@@ -1836,6 +1836,13 @@ bit_value_binop_1 (enum tree_code code, tree type,
} }
else if (shift < 0) else if (shift < 0)
{ {
/* ??? We can have sizetype related inconsistencies in
the IL. */
if ((TREE_CODE (r1type) == INTEGER_TYPE
&& (TYPE_IS_SIZETYPE (r1type)
? 0 : TYPE_UNSIGNED (r1type))) != uns)
break;
shift = -shift; shift = -shift;
*mask = double_int_rshift (r1mask, shift, *mask = double_int_rshift (r1mask, shift,
TYPE_PRECISION (type), !uns); TYPE_PRECISION (type), !uns);
...@@ -1946,6 +1953,14 @@ bit_value_binop_1 (enum tree_code code, tree type, ...@@ -1946,6 +1953,14 @@ bit_value_binop_1 (enum tree_code code, tree type,
if (double_int_negative_p (r1mask) || double_int_negative_p (r2mask)) if (double_int_negative_p (r1mask) || double_int_negative_p (r2mask))
break; break;
/* For comparisons the signedness is in the comparison operands. */
uns = (TREE_CODE (r1type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type));
/* ??? We can have sizetype related inconsistencies in the IL. */
if ((TREE_CODE (r2type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (r2type) ? 0 : TYPE_UNSIGNED (r2type)) != uns)
break;
/* If we know the most significant bits we know the values /* If we know the most significant bits we know the values
value ranges by means of treating varying bits as zero value ranges by means of treating varying bits as zero
or one. Do a cross comparison of the max/min pairs. */ or one. Do a cross comparison of the max/min pairs. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment