gimplify.c (gimplify_expr): Gimplify TRUTH_NOT_EXPR as BIT_XOR_EXPR, same as the...
authorRichard Guenther <rguenther@suse.de>
Tue, 19 Jul 2011 10:57:15 +0000 (10:57 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 19 Jul 2011 10:57:15 +0000 (10:57 +0000)
2011-07-19  Richard Guenther  <rguenther@suse.de>

* gimplify.c (gimplify_expr): Gimplify TRUTH_NOT_EXPR as
BIT_XOR_EXPR, same as the RTL expander does.
* tree-cfg.c (verify_expr): Disallow TRUTH_NOT_EXPR in the gimple IL.
(verify_gimple_assign_unary): Likewise.
* tree-ssa-propagate.c (valid_gimple_rhs_p): Disallow TRUTH_*_EXPR.
* tree-ssa-forwprop.c (forward_propagate_comparison): Handle
BIT_NOT_EXPR and BIT_XOR_EXPR instead of TRUTH_NOT_EXPR.

* gcc.dg/tree-ssa/bool-10.c: Adjust expected pattern.
* gcc.dg/tree-ssa/bool-11.c: Likewise.
* gcc.dg/torture/20110719-1.c: New testcase.

From-SVN: r176442

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/20110719-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/bool-10.c
gcc/testsuite/gcc.dg/tree-ssa/bool-11.c
gcc/tree-cfg.c
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-propagate.c

index d46d52d2138698dac00a97ef75dd78a76b035d69..2982c9bc13005060511510492e8638ed0a5a04a6 100644 (file)
@@ -1,3 +1,13 @@
+2011-07-19  Richard Guenther  <rguenther@suse.de>
+
+       * gimplify.c (gimplify_expr): Gimplify TRUTH_NOT_EXPR as
+       BIT_XOR_EXPR, same as the RTL expander does.
+       * tree-cfg.c (verify_expr): Disallow TRUTH_NOT_EXPR in the gimple IL.
+       (verify_gimple_assign_unary): Likewise.
+       * tree-ssa-propagate.c (valid_gimple_rhs_p): Disallow TRUTH_*_EXPR.
+       * tree-ssa-forwprop.c (forward_propagate_comparison): Handle
+       BIT_NOT_EXPR and BIT_XOR_EXPR instead of TRUTH_NOT_EXPR.
+
 2011-07-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/49768
index d1ce6d3dce83f5a1b74b4fc6ca02deacc65971ae..03e2ca622cb23116b7a96a61b16bcc0cc91550b0 100644 (file)
@@ -6787,17 +6787,24 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 
        case TRUTH_NOT_EXPR:
          {
-           tree orig_type = TREE_TYPE (*expr_p);
+           tree type = TREE_TYPE (*expr_p);
+           /* The parsers are careful to generate TRUTH_NOT_EXPR
+              only with operands that are always zero or one.
+              We do not fold here but handle the only interesting case
+              manually, as fold may re-introduce the TRUTH_NOT_EXPR.  */
            *expr_p = gimple_boolify (*expr_p);
-           if (!useless_type_conversion_p (orig_type, TREE_TYPE (*expr_p)))
-             {
-               *expr_p = fold_convert_loc (saved_location, orig_type, *expr_p);
-               ret = GS_OK;
-               break;
-             }
-           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
-                                is_gimple_val, fb_rvalue);
-           recalculate_side_effects (*expr_p);
+           if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
+             *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
+                                   TREE_TYPE (*expr_p),
+                                   TREE_OPERAND (*expr_p, 0));
+           else
+             *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
+                                   TREE_TYPE (*expr_p),
+                                   TREE_OPERAND (*expr_p, 0),
+                                   build_int_cst (TREE_TYPE (*expr_p), 1));
+           if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
+             *expr_p = fold_convert_loc (input_location, type, *expr_p);
+           ret = GS_OK;
            break;
          }
 
index 07c283dcc0c2fd4ec5b796844fc951df6cdc3087..d87ce8d7464e62f9f5ac4ddd7d981c5df51b4a36 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-19  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/bool-10.c: Adjust expected pattern.
+       * gcc.dg/tree-ssa/bool-11.c: Likewise.
+       * gcc.dg/torture/20110719-1.c: New testcase.
+
 2011-07-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/49768
diff --git a/gcc/testsuite/gcc.dg/torture/20110719-1.c b/gcc/testsuite/gcc.dg/torture/20110719-1.c
new file mode 100644 (file)
index 0000000..7797e08
--- /dev/null
@@ -0,0 +1,10 @@
+extern void abort (void);
+int i;
+int main()
+{
+  int b = i != 0;
+  int c = ~b;
+  if (c != -1)
+    abort ();
+  return 0;
+}
index d7bf20da81b61c9764e4674ac3214b6824ef81ea..58d064539a76a7b817ba4ad7bc842fc1443a0c40 100644 (file)
@@ -9,6 +9,6 @@ int f(_Bool x)
 /* There should be no != 1 which is produced by the front-end as
    bool_var != 1 is the same as !bool_var. */
 /* { dg-final { scan-tree-dump-times "!= 1" 0 "optimized"} } */
-/* { dg-final { scan-tree-dump-times "!x" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "~x" 1 "optimized"} } */
 
 /* { dg-final { cleanup-tree-dump "optimized" } } */
index 8d88b7e87d5ecdd71c544350c566a9f317077479..ee266c79cb96325834b7b8a02855193bd84ecb7a 100644 (file)
@@ -9,6 +9,6 @@ int f(_Bool x)
 /* There should be no == 0 which is produced by the front-end as
    bool_var == 0 is the same as !bool_var. */
 /* { dg-final { scan-tree-dump-times "== 0" 0 "optimized"} } */
-/* { dg-final { scan-tree-dump-times "!x" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "~x" 1 "optimized"} } */
 
 /* { dg-final { cleanup-tree-dump "optimized" } } */
index 12d8fb4e5f062262d21258c993994802d070b3b7..cd134728bb7d2bbf5df69aedb86898f11c7af786 100644 (file)
@@ -2680,7 +2680,8 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       break;
 
     case NON_LVALUE_EXPR:
-       gcc_unreachable ();
+    case TRUTH_NOT_EXPR:
+      gcc_unreachable ();
 
     CASE_CONVERT:
     case FIX_TRUNC_EXPR:
@@ -2688,7 +2689,6 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
     case NEGATE_EXPR:
     case ABS_EXPR:
     case BIT_NOT_EXPR:
-    case TRUTH_NOT_EXPR:
       CHECK_OP (0, "invalid operand to unary operator");
       break;
 
@@ -3344,19 +3344,6 @@ verify_gimple_assign_unary (gimple stmt)
       /* FIXME.  */
       return false;
 
-    case TRUTH_NOT_EXPR:
-      /* We require two-valued operand types.  */
-      if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE
-           || (INTEGRAL_TYPE_P (rhs1_type)
-               && TYPE_PRECISION (rhs1_type) == 1)))
-        {
-         error ("invalid types in truth not");
-         debug_generic_expr (lhs_type);
-         debug_generic_expr (rhs1_type);
-         return true;
-        }
-      break;
-
     case NEGATE_EXPR:
     case ABS_EXPR:
     case BIT_NOT_EXPR:
index 8e6b7040af0aaa12dc59ad99ceb2adf9e427782e..1f2a60c49ba1d8f6ce5b60b8f122ca65a5207d3d 100644 (file)
@@ -1127,7 +1127,8 @@ forward_propagate_comparison (gimple stmt)
       && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt))
          || TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
             == tcc_comparison
-          || gimple_assign_rhs_code (use_stmt) == TRUTH_NOT_EXPR)
+          || gimple_assign_rhs_code (use_stmt) == BIT_NOT_EXPR
+         || gimple_assign_rhs_code (use_stmt) == BIT_XOR_EXPR)
       && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (use_stmt))))
     {
       tree lhs = gimple_assign_lhs (use_stmt);
@@ -1164,7 +1165,10 @@ forward_propagate_comparison (gimple stmt)
       }
       /* We can propagate the condition into a statement that
         computes the logical negation of the comparison result.  */
-      else if (gimple_assign_rhs_code (use_stmt) == TRUTH_NOT_EXPR)
+      else if ((gimple_assign_rhs_code (use_stmt) == BIT_NOT_EXPR
+               && TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
+              || (gimple_assign_rhs_code (use_stmt) == BIT_XOR_EXPR
+                  && integer_onep (gimple_assign_rhs2 (use_stmt))))
        {
          tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
          bool nans = HONOR_NANS (TYPE_MODE (type));
index 7f1d84ebdfefdece3ffd3179679182541be2cd12..64c3fdfe5704f16cdb662f994cc511b76298ff28 100644 (file)
@@ -601,19 +601,6 @@ valid_gimple_rhs_p (tree expr)
           }
           break;
 
-       case TRUTH_NOT_EXPR:
-         if (!is_gimple_val (TREE_OPERAND (expr, 0)))
-           return false;
-         break;
-
-       case TRUTH_AND_EXPR:
-       case TRUTH_XOR_EXPR:
-       case TRUTH_OR_EXPR:
-         if (!is_gimple_val (TREE_OPERAND (expr, 0))
-             || !is_gimple_val (TREE_OPERAND (expr, 1)))
-           return false;
-         break;
-
        default:
          return false;
        }