re PR middle-end/28651 (signed compare incorrectly false for (int)(U+4)<(int)U where U is unsigned INT_MAX (for optimized x86))

2006-08-11  Richard Guenther  <rguenther@suse.de>

	PR middle-end/28651
	* simplify-rtx.c (simplify_const_relational_operation):
	Simplify A CMP B to A - B CMP 0 only for EQ and NE comparison
	codes.

	* gcc.c-torture/execute/pr28651.c: New testcase.

From-SVN: r116079
This commit is contained in:
Richard Guenther 2006-08-11 07:44:45 +00:00 committed by Richard Biener
parent 9b514d4c65
commit e0d0c1939b
4 changed files with 44 additions and 9 deletions

View File

@ -1,3 +1,10 @@
2006-08-11 Richard Guenther <rguenther@suse.de>
PR middle-end/28651
* simplify-rtx.c (simplify_const_relational_operation):
Simplify A CMP B to A - B CMP 0 only for EQ and NE comparison
codes.
2006-08-10 Eric Botcazou <ebotcazou@adacore.com>
* tree.c (build1_stat): Also propagate the TREE_CONSTANT and

View File

@ -3733,19 +3733,18 @@ simplify_const_relational_operation (enum rtx_code code,
a register or a CONST_INT, this can't help; testing for these cases will
prevent infinite recursion here and speed things up.
If CODE is an unsigned comparison, then we can never do this optimization,
because it gives an incorrect result if the subtraction wraps around zero.
ANSI C defines unsigned operations such that they never overflow, and
thus such cases can not be ignored; but we cannot do it even for
signed comparisons for languages such as Java, so test flag_wrapv. */
We can only do this for EQ and NE comparisons as otherwise we may
lose or introduce overflow which we cannot disregard as undefined as
we do not know the signedness of the operation on either the left or
the right hand side of the comparison. */
if (!flag_wrapv && INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
&& (code == EQ || code == NE)
&& ! ((REG_P (op0) || GET_CODE (trueop0) == CONST_INT)
&& (REG_P (op1) || GET_CODE (trueop1) == CONST_INT))
&& 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
/* We cannot do this for == or != if tem is a nonzero address. */
&& ((code != EQ && code != NE) || ! nonzero_address_p (tem))
&& code != GTU && code != GEU && code != LTU && code != LEU)
/* We cannot do this if tem is a nonzero address. */
&& ! nonzero_address_p (tem))
return simplify_const_relational_operation (signed_condition (code),
mode, tem, const0_rtx);

View File

@ -1,3 +1,8 @@
2006-08-11 Richard Guenther <rguenther@suse.de>
PR middle-end/28651
* gcc.c-torture/execute/pr28651.c: New testcase.
2006-08-10 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/static_initializer.ads: New test.

View File

@ -0,0 +1,24 @@
extern void abort (void);
int
foo (unsigned int u)
{
return (int)(u + 4) < (int)u;
}
int
main (int argc, char *argv[])
{
unsigned int u;
/* Run with no arguments so u will be MAX_INT and the optimizers
won't know its value. */
if (argc > 1)
u = 1;
else
u = 0x7fffffff;
if (foo (u) == 0)
abort();
return 0;
}