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>
PR tree-optimization/49768
......
......@@ -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;
}
......
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
......
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)
/* 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" } } */
......@@ -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" } } */
......@@ -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:
......
......@@ -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));
......
......@@ -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;
}
......
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