From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10458 invoked by alias); 19 Jul 2011 11:28:13 -0000 Received: (qmail 10448 invoked by uid 22791); 19 Jul 2011 11:28:11 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_TM X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 19 Jul 2011 11:27:54 +0000 Received: by qwh5 with SMTP id 5so2258107qwh.20 for ; Tue, 19 Jul 2011 04:27:53 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.17.17 with SMTP id q17mr5711509qca.154.1311074858613; Tue, 19 Jul 2011 04:27:38 -0700 (PDT) Received: by 10.229.38.195 with HTTP; Tue, 19 Jul 2011 04:27:38 -0700 (PDT) In-Reply-To: References: Date: Tue, 19 Jul 2011 12:08:00 -0000 Message-ID: Subject: Re: [patch tree-optimization]: [2 of 3]: Boolify compares & more From: Kai Tietz To: Richard Guenther Cc: GCC Patches Content-Type: text/plain; charset=ISO-8859-1 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-07/txt/msg01497.txt.bz2 Hello, So this is the updated patch for boolifying of comparisons. There are two different kind of regression caused by this. One is fixed by the VRP patch I've sent and it waits for review. The other one is about vectorization in gcc.dg/vect/vect-cond3.c testcase. This is caused by vectorization pass, which can't handle different types for vectorization, as now the conditions are always boolean-typed. ChangeLog 2011-07-19 Kai Tietz * fold-const.c (fold_unary_loc): Preserve non-boolean-typed casts. * gimplify.c (gimple_boolify): Handle boolification of comparisons. (gimplify_expr): Boolifiy non aggregate-typed comparisons. * tree-cfg.c (verify_gimple_comparison): Check result type of comparison expression. * tree-ssa.c (useless_type_conversion_p): Preserve incompatible casts from/to boolean, * tree-ssa-forwprop.c (forward_propagate_comparison): Adjust test of condition result and disallow type-cast sinking into comparison. * gcc.dg/tree-ssa/builtin-expect-5.c: Adjusted. * gcc.dg/tree-ssa/pr21031.c: Likewise. * gcc.dg/tree-ssa/pr30978.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-6.c: Likewise. * gcc.dg/binop-xor1.c: Mark it as expected fail. * gcc.dg/binop-xor3.c: Likewise. * gcc.dg/uninit-15.c: Adjust reported message. Bootstrapped and regression tested for x86_64-pc-linux-gnu. Ok for apply? Regards, Kai PS: Might be that due your recent patch to forwprop, that patch doesn't apply here cleanly. Index: gcc-head/gcc/fold-const.c =================================================================== --- gcc-head.orig/gcc/fold-const.c +++ gcc-head/gcc/fold-const.c @@ -7665,11 +7665,11 @@ fold_unary_loc (location_t loc, enum tre non-integral type. Do not fold the result as that would not simplify further, also folding again results in recursions. */ - if (INTEGRAL_TYPE_P (type)) + if (TREE_CODE (type) == BOOLEAN_TYPE) return build2_loc (loc, TREE_CODE (op0), type, TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1)); - else + else if (!INTEGRAL_TYPE_P (type)) return build3_loc (loc, COND_EXPR, type, op0, fold_convert (type, boolean_true_node), fold_convert (type, boolean_false_node)); Index: gcc-head/gcc/gimplify.c =================================================================== --- gcc-head.orig/gcc/gimplify.c +++ gcc-head/gcc/gimplify.c @@ -2860,18 +2860,23 @@ gimple_boolify (tree expr) case TRUTH_NOT_EXPR: TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); - /* FALLTHRU */ - case EQ_EXPR: case NE_EXPR: - case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: /* These expressions always produce boolean results. */ - TREE_TYPE (expr) = boolean_type_node; + if (TREE_CODE (type) != BOOLEAN_TYPE) + TREE_TYPE (expr) = boolean_type_node; return expr; default: + if (COMPARISON_CLASS_P (expr)) + { + /* There expressions always prduce boolean results. */ + if (TREE_CODE (type) != BOOLEAN_TYPE) + TREE_TYPE (expr) = boolean_type_node; + return expr; + } /* Other expressions that get here must have boolean values, but might need to be converted to the appropriate mode. */ - if (type == boolean_type_node) + if (TREE_CODE (type) == BOOLEAN_TYPE) return expr; return fold_convert_loc (loc, boolean_type_node, expr); } @@ -6791,7 +6796,7 @@ gimplify_expr (tree *expr_p, gimple_seq *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); + *expr_p = fold_convert_loc (input_location, orig_type, *expr_p); ret = GS_OK; break; } @@ -7309,7 +7314,19 @@ gimplify_expr (tree *expr_p, gimple_seq tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1)); if (!AGGREGATE_TYPE_P (type)) - goto expr_2; + { + tree org_type = TREE_TYPE (*expr_p); + *expr_p = gimple_boolify (*expr_p); + if (!useless_type_conversion_p (org_type, + TREE_TYPE (*expr_p))) + { + *expr_p = fold_convert_loc (input_location, + org_type, *expr_p); + ret = GS_OK; + } + else + goto expr_2; + } else if (TYPE_MODE (type) != BLKmode) ret = gimplify_scalar_mode_aggregate_compare (expr_p); else Index: gcc-head/gcc/tree-cfg.c =================================================================== --- gcc-head.orig/gcc/tree-cfg.c +++ gcc-head/gcc/tree-cfg.c @@ -3203,7 +3203,9 @@ verify_gimple_comparison (tree type, tre && (!POINTER_TYPE_P (op0_type) || !POINTER_TYPE_P (op1_type) || TYPE_MODE (op0_type) != TYPE_MODE (op1_type))) - || !INTEGRAL_TYPE_P (type)) + || !INTEGRAL_TYPE_P (type) + || (TREE_CODE (type) != BOOLEAN_TYPE + && TYPE_PRECISION (type) != 1)) { error ("type mismatch in comparison expression"); debug_generic_expr (type); Index: gcc-head/gcc/tree-ssa.c =================================================================== --- gcc-head.orig/gcc/tree-ssa.c +++ gcc-head/gcc/tree-ssa.c @@ -1306,10 +1306,10 @@ useless_type_conversion_p (tree outer_ty || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) return false; - /* Preserve conversions to BOOLEAN_TYPE if it is not of precision - one. */ - if (TREE_CODE (inner_type) != BOOLEAN_TYPE - && TREE_CODE (outer_type) == BOOLEAN_TYPE + /* Preserve conversions to/from BOOLEAN_TYPE if types are not + of precision one. */ + if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) + != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) && TYPE_PRECISION (outer_type) != 1) return false; Index: gcc-head/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c +++ gcc-head/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c @@ -11,5 +11,5 @@ f (int i, float j) /* { dg-final { scan-tree-dump-times { if } 2 "forwprop1"} } */ /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 0\);\n[^\n]*if} "forwprop1"} } */ -/* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 1\);\n[^\n]*if} "forwprop1"} } */ +/* { dg-final { scan-tree-dump-not {builtin_expect[^\n]*, 1\);\n[^\n]*if} "forwprop1"} } */ /* { dg-final { cleanup-tree-dump "forwprop?" } } */ Index: gcc-head/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c +++ gcc-head/gcc/testsuite/gcc.dg/tree-ssa/pr21031.c @@ -16,5 +16,5 @@ foo (int a) return 0; } -/* { dg-final { scan-tree-dump-times "Replaced" 2 "forwprop1"} } */ +/* { dg-final { scan-tree-dump-times "Replaced" 1 "forwprop1"} } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ Index: gcc-head/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c +++ gcc-head/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c @@ -10,5 +10,5 @@ int foo(int a) return e; } -/* { dg-final { scan-tree-dump "e_. = a_..D. > 0;" "optimized" } } */ +/* { dg-final { scan-tree-dump " = a_..D. > 0;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ Index: gcc-head/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c +++ gcc-head/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-6.c @@ -2,5 +2,5 @@ /* { dg-options "-O -fdump-tree-fre1-details" } */ int i; int foo(void) { i = 2; int j = i * 2; int k = i + 2; return j == k; } -/* { dg-final { scan-tree-dump-times "Replaced " 5 "fre1" } } */ +/* { dg-final { scan-tree-dump-times "Replaced " 6 "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ Index: gcc-head/gcc/tree-ssa-forwprop.c =================================================================== --- gcc-head.orig/gcc/tree-ssa-forwprop.c +++ gcc-head/gcc/tree-ssa-forwprop.c @@ -1122,30 +1174,22 @@ forward_propagate_comparison (gimple stm if (!use_stmt) return false; - /* Conversion of the condition result to another integral type. */ + /* Test of the condition result. */ if (is_gimple_assign (use_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) - && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (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 + && TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (use_stmt)))))) { tree lhs = gimple_assign_lhs (use_stmt); - /* We can propagate the condition into a conversion. */ - if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt))) - { - /* Avoid using fold here as that may create a COND_EXPR with - non-boolean condition as canonical form. */ - tmp = build2 (gimple_assign_rhs_code (stmt), TREE_TYPE (lhs), - gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt)); - } /* We can propagate the condition into X op CST where op is EQ_EXPR or NE_EXPR and CST is either one or zero. */ - else if (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt)) - == tcc_comparison - && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == SSA_NAME - && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST) + if (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt)) + == tcc_comparison + && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == SSA_NAME + && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST) { enum tree_code code = gimple_assign_rhs_code (use_stmt); tree cst = gimple_assign_rhs2 (use_stmt); @@ -1164,7 +1208,8 @@ forward_propagate_comparison (gimple stm } /* 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) == TRUTH_NOT_EXPR + || gimple_assign_rhs_code (use_stmt) == BIT_NOT_EXPR) { tree type = TREE_TYPE (gimple_assign_rhs1 (stmt)); bool nans = HONOR_NANS (TYPE_MODE (type)); @@ -1810,6 +1855,7 @@ simplify_bitwise_binary (gimple_stmt_ite arg2)); tem = make_ssa_name (tem, newop); gimple_assign_set_lhs (newop, tem); + gimple_set_location (newop, gimple_location (stmt)); gsi_insert_before (gsi, newop, GSI_SAME_STMT); gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR, tem, NULL_TREE, NULL_TREE); @@ -1839,6 +1885,7 @@ simplify_bitwise_binary (gimple_stmt_ite newop = gimple_build_assign_with_ops (code, tem, def1_arg1, def2_arg1); tem = make_ssa_name (tem, newop); gimple_assign_set_lhs (newop, tem); + gimple_set_location (newop, gimple_location (stmt)); gsi_insert_before (gsi, newop, GSI_SAME_STMT); gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR, tem, NULL_TREE, NULL_TREE); @@ -1867,6 +1914,7 @@ simplify_bitwise_binary (gimple_stmt_ite tem, def1_arg1, arg2); tem = make_ssa_name (tem, newop); gimple_assign_set_lhs (newop, tem); + gimple_set_location (newop, gimple_location (stmt)); /* Make sure to re-process the new stmt as it's walking upwards. */ gsi_insert_before (gsi, newop, GSI_NEW_STMT); gimple_assign_set_rhs1 (stmt, tem); Index: gcc-head/gcc/testsuite/gcc.dg/binop-xor1.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/binop-xor1.c +++ gcc-head/gcc/testsuite/gcc.dg/binop-xor1.c @@ -7,8 +7,5 @@ foo (int a, int b, int c) return ((a && !b && c) || (!a && b && c)); } -/* We expect to see ""; confirm that, so that we know to count - it in the real test. */ -/* { dg-final { scan-tree-dump-times "\]*>" 5 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "\\\^" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\\^" 1 "optimized" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ Index: gcc-head/gcc/testsuite/gcc.dg/binop-xor3.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/binop-xor3.c +++ gcc-head/gcc/testsuite/gcc.dg/binop-xor3.c @@ -7,8 +7,5 @@ foo (int a, int b) return ((a && !b) || (!a && b)); } -/* We expect to see ""; confirm that, so that we know to count - it in the real test. */ -/* { dg-final { scan-tree-dump-times "\]*>" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "\\\^" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\\^" 1 "optimized" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ Index: gcc-head/gcc/testsuite/gcc.dg/uninit-15.c =================================================================== --- gcc-head.orig/gcc/testsuite/gcc.dg/uninit-15.c +++ gcc-head/gcc/testsuite/gcc.dg/uninit-15.c @@ -18,9 +18,9 @@ foo (int i) void baz (void); void -bar (void) +bar (void) /* { dg-warning "'j' is used uninitialized" } */ { int j; /* { dg-message "note: 'j' was declared here" "" { xfail *-*-* } } */ - for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" } */ + for (; foo (j); ++j) baz (); }