Commit 53020648 by Richard Guenther Committed by Richard Biener

gimplify.c (gimplify_expr): Gimplify TRUTH_NOT_EXPR as BIT_XOR_EXPR, same as the RTL expander does.

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
parent b8b2b009
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> 2011-07-19 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/49768 PR tree-optimization/49768
......
...@@ -6787,17 +6787,24 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ...@@ -6787,17 +6787,24 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case TRUTH_NOT_EXPR: 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); *expr_p = gimple_boolify (*expr_p);
if (!useless_type_conversion_p (orig_type, TREE_TYPE (*expr_p))) if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
{ *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
*expr_p = fold_convert_loc (saved_location, orig_type, *expr_p); TREE_TYPE (*expr_p),
ret = GS_OK; TREE_OPERAND (*expr_p, 0));
break; else
} *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, TREE_TYPE (*expr_p),
is_gimple_val, fb_rvalue); TREE_OPERAND (*expr_p, 0),
recalculate_side_effects (*expr_p); 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; break;
} }
......
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> 2011-07-19 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/49768 PR tree-optimization/49768
......
extern void abort (void);
int i;
int main()
{
int b = i != 0;
int c = ~b;
if (c != -1)
abort ();
return 0;
}
...@@ -9,6 +9,6 @@ int f(_Bool x) ...@@ -9,6 +9,6 @@ int f(_Bool x)
/* There should be no != 1 which is produced by the front-end as /* There should be no != 1 which is produced by the front-end as
bool_var != 1 is the same as !bool_var. */ bool_var != 1 is the same as !bool_var. */
/* { dg-final { scan-tree-dump-times "!= 1" 0 "optimized"} } */ /* { 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" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -9,6 +9,6 @@ int f(_Bool x) ...@@ -9,6 +9,6 @@ int f(_Bool x)
/* There should be no == 0 which is produced by the front-end as /* There should be no == 0 which is produced by the front-end as
bool_var == 0 is the same as !bool_var. */ bool_var == 0 is the same as !bool_var. */
/* { dg-final { scan-tree-dump-times "== 0" 0 "optimized"} } */ /* { 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" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -2680,7 +2680,8 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) ...@@ -2680,7 +2680,8 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
break; break;
case NON_LVALUE_EXPR: case NON_LVALUE_EXPR:
gcc_unreachable (); case TRUTH_NOT_EXPR:
gcc_unreachable ();
CASE_CONVERT: CASE_CONVERT:
case FIX_TRUNC_EXPR: case FIX_TRUNC_EXPR:
...@@ -2688,7 +2689,6 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) ...@@ -2688,7 +2689,6 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
case NEGATE_EXPR: case NEGATE_EXPR:
case ABS_EXPR: case ABS_EXPR:
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
CHECK_OP (0, "invalid operand to unary operator"); CHECK_OP (0, "invalid operand to unary operator");
break; break;
...@@ -3344,19 +3344,6 @@ verify_gimple_assign_unary (gimple stmt) ...@@ -3344,19 +3344,6 @@ verify_gimple_assign_unary (gimple stmt)
/* FIXME. */ /* FIXME. */
return false; 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 NEGATE_EXPR:
case ABS_EXPR: case ABS_EXPR:
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
......
...@@ -1127,7 +1127,8 @@ forward_propagate_comparison (gimple stmt) ...@@ -1127,7 +1127,8 @@ forward_propagate_comparison (gimple stmt)
&& (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)) && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt))
|| TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt)) || TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
== tcc_comparison == 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)))) && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (use_stmt))))
{ {
tree lhs = gimple_assign_lhs (use_stmt); tree lhs = gimple_assign_lhs (use_stmt);
...@@ -1164,7 +1165,10 @@ forward_propagate_comparison (gimple stmt) ...@@ -1164,7 +1165,10 @@ forward_propagate_comparison (gimple stmt)
} }
/* We can propagate the condition into a statement that /* We can propagate the condition into a statement that
computes the logical negation of the comparison result. */ 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)); tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
bool nans = HONOR_NANS (TYPE_MODE (type)); bool nans = HONOR_NANS (TYPE_MODE (type));
......
...@@ -601,19 +601,6 @@ valid_gimple_rhs_p (tree expr) ...@@ -601,19 +601,6 @@ valid_gimple_rhs_p (tree expr)
} }
break; 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: default:
return false; return false;
} }
......
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