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
+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
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
--- /dev/null
+extern void abort (void);
+int i;
+int main()
+{
+ int b = i != 0;
+ int c = ~b;
+ if (c != -1)
+ abort ();
+ return 0;
+}
/* 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" } } */
/* 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" } } */
break;
case NON_LVALUE_EXPR:
- gcc_unreachable ();
+ case TRUTH_NOT_EXPR:
+ gcc_unreachable ();
CASE_CONVERT:
case FIX_TRUNC_EXPR:
case NEGATE_EXPR:
case ABS_EXPR:
case BIT_NOT_EXPR:
- case TRUTH_NOT_EXPR:
CHECK_OP (0, "invalid operand to unary operator");
break;
/* 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:
&& (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);
}
/* 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));
}
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;
}