From 8236c8eb4f599f95d76aafcdc11720edbce407cf Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 14 Dec 2010 15:09:59 +0100 Subject: 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 --- gcc/gimple-fold.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'gcc/gimple-fold.c') diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index ba51ee8..bf5e804 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -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; } } } -- cgit v1.1