Commit 6b12efe9 by Richard Guenther Committed by Richard Biener

re PR middle-end/31029 (Fold does not fold C - a == a)

2009-03-31  Richard Guenther  <rguenther@suse.de>

	PR middle-end/31029
	* fold-const.c (fold_binary): Fold X +- Y CMP X to Y CMP 0 for
	equality comparisons.  Fold C - X CMP X if C % 2 == 1.

	* gcc.dg/fold-compare-4.c: New testcase.
	* gcc.dg/fold-compare-5.c: Likewise.

From-SVN: r145345
parent 108f6c2f
2009-03-31 Richard Guenther <rguenther@suse.de>
PR middle-end/31029
* fold-const.c (fold_binary): Fold X +- Y CMP X to Y CMP 0 for
equality comparisons. Fold C - X CMP X if C % 2 == 1.
2009-03-31 Richard Guenther <rguenther@suse.de>
* tree.h (div_if_zero_remainder): Declare.
* fold-const.c (div_if_zero_remainder): Export.
* tree-ssa-forwprop.c
......
......@@ -12191,22 +12191,33 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
fold_convert (TREE_TYPE (arg0), arg1),
TREE_OPERAND (arg0, 1)));
/* Transform comparisons of the form X +- C CMP X. */
if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
/* Transform comparisons of the form X +- Y CMP X to Y CMP 0. */
if ((TREE_CODE (arg0) == PLUS_EXPR
|| TREE_CODE (arg0) == POINTER_PLUS_EXPR
|| TREE_CODE (arg0) == MINUS_EXPR)
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
|| POINTER_TYPE_P (TREE_TYPE (arg0))))
{
tree cst = TREE_OPERAND (arg0, 1);
tree val = TREE_OPERAND (arg0, 1);
return omit_two_operands (type,
fold_build2 (code, type,
val,
build_int_cst (TREE_TYPE (val),
0)),
TREE_OPERAND (arg0, 0), arg1);
}
if (code == EQ_EXPR
&& !integer_zerop (cst))
return omit_two_operands (type, boolean_false_node,
TREE_OPERAND (arg0, 0), arg1);
else
return omit_two_operands (type, boolean_true_node,
TREE_OPERAND (arg0, 0), arg1);
/* Transform comparisons of the form C - X CMP X if C % 2 == 1. */
if (TREE_CODE (arg0) == MINUS_EXPR
&& TREE_CODE (TREE_OPERAND (arg0, 0)) == INTEGER_CST
&& operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)
&& (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 0)) & 1) == 1)
{
return omit_two_operands (type,
code == NE_EXPR
? boolean_true_node : boolean_false_node,
TREE_OPERAND (arg0, 1), arg1);
}
/* If we have X - Y == 0, we can convert that to X == Y and similarly
......
2009-03-31 Richard Guenther <rguenther@suse.de>
PR middle-end/31029
* gcc.dg/fold-compare-4.c: New testcase.
* gcc.dg/fold-compare-5.c: Likewise.
2009-03-31 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/forwprop-12.c: New testcase.
2009-03-31 Joseph Myers <joseph@codesourcery.com>
......
/* { dg-do compile } */
/* { dg-options "-fdump-tree-original" } */
int test1 (int a, int b)
{
return a - b == a;
}
int test2 (int a, int b)
{
return a + b == a;
}
int test3 (int a)
{
return a + 5 == a;
}
int test4 (int a)
{
return a - 5 == a;
}
/* { dg-final { scan-tree-dump-times "b == 0" 2 "original" } } */
/* { dg-final { scan-tree-dump-times "return 0" 2 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */
/* { dg-do compile } */
/* { dg-options "-fdump-tree-original" } */
int test1 (int a)
{
return 2 - a == a;
}
int test2 (int a)
{
return 1 - a == a;
}
int test3 (int a)
{
return 1 - a != a;
}
/* { dg-final { scan-tree-dump-times "return 2 - a == a" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "return 0" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "return 1" 1 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */
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