Commit e0d0c193 by Richard Guenther Committed by Richard Biener

re PR middle-end/28651 (signed compare incorrectly false for (int)(U+4)<(int)U…

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