re PR tree-optimization/46909 (Logical OR expressions are miscompiled)
PR tree-optimization/46909 * gimple-fold.c (and_var_with_comparison_1): Save partial result even in the is_and case, if both partial results are the same, return it. (or_var_with_comparison_1): Use is_or predicate instead of innercode == TRUTH_OR_EXPR test. Save partial result even in the is_or case, if both partial results are the same, return it. In the !is_or case when both partial results are the same, return the partial result instead of boolean_true_node. * gcc.c-torture/execute/pr46909-1.c: New test. * gcc.c-torture/execute/pr46909-2.c: New test. * gcc.dg/pr46909.c: New test. From-SVN: r167800
This commit is contained in:
parent
2b50313607
commit
8236c8eb4f
|
@ -1,3 +1,16 @@
|
|||
2010-12-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/46909
|
||||
* gimple-fold.c (and_var_with_comparison_1): Save partial
|
||||
result even in the is_and case, if both partial results
|
||||
are the same, return it.
|
||||
(or_var_with_comparison_1): Use is_or predicate instead of
|
||||
innercode == TRUTH_OR_EXPR test. Save partial result
|
||||
even in the is_or case, if both partial results are the
|
||||
same, return it. In the !is_or case when both partial
|
||||
results are the same, return the partial result instead
|
||||
of boolean_true_node.
|
||||
|
||||
2010-12-14 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
PR middle-end/46667
|
||||
|
|
|
@ -2008,14 +2008,11 @@ and_var_with_comparison_1 (gimple stmt,
|
|||
/* Handle the OR case, where we are redistributing:
|
||||
(inner1 OR inner2) AND (op2a code2 op2b)
|
||||
=> (t OR (inner2 AND (op2a code2 op2b))) */
|
||||
else
|
||||
{
|
||||
if (integer_onep (t))
|
||||
return boolean_true_node;
|
||||
else
|
||||
/* Save partial result for later. */
|
||||
partial = t;
|
||||
}
|
||||
else if (integer_onep (t))
|
||||
return boolean_true_node;
|
||||
|
||||
/* Save partial result for later. */
|
||||
partial = t;
|
||||
}
|
||||
|
||||
/* Compute the second partial result, (inner2 AND (op2a code op2b)) */
|
||||
|
@ -2036,6 +2033,10 @@ and_var_with_comparison_1 (gimple stmt,
|
|||
return inner1;
|
||||
else if (integer_zerop (t))
|
||||
return boolean_false_node;
|
||||
/* If both are the same, we can apply the identity
|
||||
(x AND x) == x. */
|
||||
else if (partial && same_bool_result_p (t, partial))
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Handle the OR case. where we are redistributing:
|
||||
|
@ -2445,7 +2446,7 @@ or_var_with_comparison_1 (gimple stmt,
|
|||
=> (t OR inner2)
|
||||
If the partial result t is a constant, we win. Otherwise
|
||||
continue on to try reassociating with the other inner test. */
|
||||
if (innercode == TRUTH_OR_EXPR)
|
||||
if (is_or)
|
||||
{
|
||||
if (integer_onep (t))
|
||||
return boolean_true_node;
|
||||
|
@ -2456,14 +2457,11 @@ or_var_with_comparison_1 (gimple stmt,
|
|||
/* Handle the AND case, where we are redistributing:
|
||||
(inner1 AND inner2) OR (op2a code2 op2b)
|
||||
=> (t AND (inner2 OR (op2a code op2b))) */
|
||||
else
|
||||
{
|
||||
if (integer_zerop (t))
|
||||
return boolean_false_node;
|
||||
else
|
||||
/* Save partial result for later. */
|
||||
partial = t;
|
||||
}
|
||||
else if (integer_zerop (t))
|
||||
return boolean_false_node;
|
||||
|
||||
/* Save partial result for later. */
|
||||
partial = t;
|
||||
}
|
||||
|
||||
/* Compute the second partial result, (inner2 OR (op2a code op2b)) */
|
||||
|
@ -2477,13 +2475,18 @@ or_var_with_comparison_1 (gimple stmt,
|
|||
{
|
||||
/* Handle the OR case, where we are reassociating:
|
||||
(inner1 OR inner2) OR (op2a code2 op2b)
|
||||
=> (inner1 OR t) */
|
||||
if (innercode == TRUTH_OR_EXPR)
|
||||
=> (inner1 OR t)
|
||||
=> (t OR partial) */
|
||||
if (is_or)
|
||||
{
|
||||
if (integer_zerop (t))
|
||||
return inner1;
|
||||
else if (integer_onep (t))
|
||||
return boolean_true_node;
|
||||
/* If both are the same, we can apply the identity
|
||||
(x OR x) == x. */
|
||||
else if (partial && same_bool_result_p (t, partial))
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Handle the AND case, where we are redistributing:
|
||||
|
@ -2500,13 +2503,13 @@ or_var_with_comparison_1 (gimple stmt,
|
|||
operand to the redistributed AND expression. The
|
||||
interesting case is when at least one is true.
|
||||
Or, if both are the same, we can apply the identity
|
||||
(x AND x) == true. */
|
||||
(x AND x) == x. */
|
||||
if (integer_onep (partial))
|
||||
return t;
|
||||
else if (integer_onep (t))
|
||||
return partial;
|
||||
else if (same_bool_result_p (t, partial))
|
||||
return boolean_true_node;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2010-12-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/46909
|
||||
* gcc.c-torture/execute/pr46909-1.c: New test.
|
||||
* gcc.c-torture/execute/pr46909-2.c: New test.
|
||||
* gcc.dg/pr46909.c: New test.
|
||||
|
||||
2010-12-14 Alexander Monakov <amonakov@ispras.ru>
|
||||
|
||||
PR rtl-optimization/46875
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* PR tree-optimization/46909 */
|
||||
|
||||
extern void abort ();
|
||||
|
||||
int
|
||||
__attribute__ ((__noinline__))
|
||||
foo (unsigned int x)
|
||||
{
|
||||
if (! (x == 4 || x == 6) || (x == 2 || x == 6))
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
for (i = -10; i < 10; i++)
|
||||
if (foo (i) != 1 - 2 * (i == 4))
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/* PR tree-optimization/46909 */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int
|
||||
__attribute__((noinline))
|
||||
foo (int x)
|
||||
{
|
||||
if ((x != 0 && x != 13) || x == 5 || x == 20)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int i;
|
||||
for (i = -10; i < 30; i++)
|
||||
if (foo (i) != 1 - 2 * (i == 0) - 2 * (i == 13))
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/* PR tree-optimization/46909 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-ifcombine" } */
|
||||
|
||||
extern void abort ();
|
||||
|
||||
int
|
||||
__attribute__ ((__noinline__))
|
||||
foo (unsigned int x)
|
||||
{
|
||||
if (! (x == 4 || x == 6) || (x == 2 || x == 6))
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "optimizing two comparisons to x_\[0-9\]+\\(D\\) != 4" "ifcombine" } } */
|
||||
/* { dg-final { cleanup-tree-dump "ifcombine" } } */
|
Loading…
Reference in New Issue