diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/gimplify.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/20110719-1.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/bool-10.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/bool-11.c | 2 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 17 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-propagate.c | 13 |
9 files changed, 53 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d46d52d..2982c9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index d1ce6d3..03e2ca6 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 07c283d..d87ce8d74 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..7797e08 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/20110719-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-10.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-10.c index d7bf20d..58d0645 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/bool-10.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-10.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-11.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-11.c index 8d88b7e..ee266c7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/bool-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-11.c @@ -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" } } */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 12d8fb4..cd13472 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -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: diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 8e6b704..1f2a60c 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -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)); diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 7f1d84e..64c3fdf 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -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; } |