mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-23 00:10:05 +08:00
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:
parent
9b514d4c65
commit
e0d0c1939b
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
24
gcc/testsuite/gcc.c-torture/execute/pr28651.c
Normal file
24
gcc/testsuite/gcc.c-torture/execute/pr28651.c
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user