From patchwork Thu May 26 10:20:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 97518 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D0F9BB6FA0 for ; Thu, 26 May 2011 20:20:22 +1000 (EST) Received: (qmail 12021 invoked by alias); 26 May 2011 10:20:20 -0000 Received: (qmail 12013 invoked by uid 22791); 26 May 2011 10:20:18 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CF, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx4-phx2.redhat.com (HELO mx4-phx2.redhat.com) (209.132.183.25) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 26 May 2011 10:20:01 +0000 Received: from mail06.corp.redhat.com (zmail06.collab.prod.int.phx2.redhat.com [10.5.5.45]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p4QAK0wv012774; Thu, 26 May 2011 06:20:00 -0400 Date: Thu, 26 May 2011 06:20:00 -0400 (EDT) From: Kai Tietz To: gcc-patches@gcc.gnu.org Cc: Richard Guenther Message-ID: <1943095191.242428.1306405200685.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> In-Reply-To: <373566883.242226.1306404169706.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> Subject: [patch gimplify]: Make sure comparison using boolean-type after gimplification MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello, this patch ensures that after gimplification also comparison expressions using FE's boolean_type_node. As we need to deal here with C/C++'s (obj-c/c++ and java's), Ada's, and Fortran's specific boolean types, this patch alters some checks in tree-cfg for Ada's sake, and we need to deal in fold-const about type-conversion of comparisons special. Additionally it takes care that in forwprop pass we don't do type hoising for boolean types. ChangeLog 2011-05-26 Kai Tietz * gimplify.c (gimple_boolify): Boolify all comparison expressions. (gimplify_expr): Use 'useless_type_conversion_p' for comparing org_type with boolean_type_node for TRUTH-expressions and comparisons. * fold-const.c (fold_unary_loc): Handle comparison conversions with boolean-type special. * tree-cfg.c (verify_gimple_comparison): Adjust check for boolean or compatible types. (verify_gimple_assign_unary): Likewise. * tree-ssa-forwprop.c (forward_propagate_comparison): Handle boolean case special. Tested on x86_64-pc-linux-gnu (multilib) with regression test for all standard languages (C, C++, Obj-C, Fortran, Java) plus Obj-C++ and Ada. Ok for apply? The following tests are failing due this change (what is to be expected here and needs some additional handling in forwprop). FAIL: gcc.dg/binop-xor1.c scan-tree-dump-times optimized "]*>" 5 FAIL: gcc.dg/binop-xor1.c scan-tree-dump-times optimized "\^" 1 FAIL: gcc.dg/binop-xor3.c scan-tree-dump-times optimized "]*>" 1 FAIL: gcc.dg/binop-xor3.c scan-tree-dump-times optimized "\^" 1 XPASS: gcc.dg/tree-ssa/20030807-7.c scan-tree-dump-times vrp1 "if " 1 FAIL: gcc.dg/tree-ssa/builtin-expect-5.c scan-tree-dump forwprop1 "builtin_expect[^\n]*, 1\);\n[^\n]*if" FAIL: gcc.dg/tree-ssa/pr21031.c scan-tree-dump-times forwprop1 "Replaced" 2 FAIL: gcc.dg/tree-ssa/pr30978.c scan-tree-dump optimized "e_. = a_..D. > 0;" FAIL: gcc.dg/tree-ssa/ssa-fre-6.c scan-tree-dump-times fre1 "Replaced " 5 FAIL: gcc.dg/tree-ssa/vrp47.c scan-tree-dump-times dom1 "x[^ ]* & y" 1 FAIL: gcc.dg/tree-ssa/vrp47.c scan-tree-dump-times vrp1 "x[^ ]* \^ 1" 1 FAIL: gcc.dg/vect/pr49038.c execution test FAIL: gcc.dg/vect/pr49038.c -flto execution test FAIL: gcc.target/i386/andor-2.c scan-assembler-not sete The Ada, Obj-C, Obj-C++, C++, Fortran, and Java testsuite don't show any new regressions by this. Some failing testcases are simply caused by different folding behavior and producing simplier code. The binop-xor tests 1 and 3 might be better removed for now, or marked as being expect to fail. The cause for their failing is in doing tree-analysis via fold-const on gimplified trees, which now don't allow folding here to look through. To illustrate required changes for other tests, I attach here some required changes for testsuite Regards, Kai Index: gcc/gcc/gimplify.c =================================================================== --- gcc.orig/gcc/gimplify.c 2011-05-23 13:49:29.235177000 +0200 +++ gcc/gcc/gimplify.c 2011-05-26 10:36:40.757641800 +0200 @@ -2837,15 +2837,18 @@ 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; return expr; default: + if (COMPARISON_CLASS_P (expr)) + { + /* These expressions always produce boolean results. */ + 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) @@ -6758,7 +6761,7 @@ gimplify_expr (tree *expr_p, gimple_seq tree org_type = TREE_TYPE (*expr_p); *expr_p = gimple_boolify (*expr_p); - if (org_type != boolean_type_node) + if (!useless_type_conversion_p (org_type, boolean_type_node)) { *expr_p = fold_convert (org_type, *expr_p); ret = GS_OK; @@ -7203,7 +7206,7 @@ gimplify_expr (tree *expr_p, gimple_seq fold_truth_not_expr) happily uses operand type and doesn't automatically uses boolean_type as result, we need to keep orignal type. */ - if (org_type != boolean_type_node) + if (!useless_type_conversion_p (org_type, boolean_type_node)) { *expr_p = fold_convert (org_type, *expr_p); ret = GS_OK; @@ -7281,9 +7284,28 @@ gimplify_expr (tree *expr_p, gimple_seq plain wrong if bitfields are involved. */ { tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1)); + tree org_type = TREE_TYPE (*expr_p); + + if (!useless_type_conversion_p (org_type, boolean_type_node)) + { + TREE_TYPE (*expr_p) = boolean_type_node; + *expr_p = fold_convert_loc (saved_location, org_type, *expr_p); + ret = GS_OK; + goto dont_recalculate; + } if (!AGGREGATE_TYPE_P (type)) - goto expr_2; + { + enum gimplify_status r0, r1; + + r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, + post_p, is_gimple_val, fb_rvalue); + r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, + post_p, is_gimple_val, fb_rvalue); + + ret = MIN (r0, r1); + } + else if (TYPE_MODE (type) != BLKmode) ret = gimplify_scalar_mode_aggregate_compare (expr_p); else Index: gcc/gcc/fold-const.c =================================================================== --- gcc.orig/gcc/fold-const.c 2011-05-23 13:49:29.000000000 +0200 +++ gcc/gcc/fold-const.c 2011-05-26 10:39:48.721510200 +0200 @@ -7641,6 +7641,12 @@ fold_unary_loc (location_t loc, enum tre } else if (COMPARISON_CLASS_P (arg0)) { + /* Don't optimize type change, if op0 is of kind boolean_type_node. + Otherwise this will lead to race-condition on gimplification + trying to boolify comparison expression. */ + if (TREE_TYPE (op0) == boolean_type_node) + return NULL_TREE; + if (TREE_CODE (type) == BOOLEAN_TYPE) { arg0 = copy_node (arg0); @@ -7672,11 +7678,12 @@ fold_unary_loc (location_t loc, enum tre if (TREE_TYPE (op0) == type) return op0; - /* If we have (type) (a CMP b) and type is an integral type, return + /* If we have (type) (a CMP b) and type is a boolean type, return new expression involving the new type. */ - if (COMPARISON_CLASS_P (op0) && INTEGRAL_TYPE_P (type)) - return fold_build2_loc (loc, TREE_CODE (op0), type, TREE_OPERAND (op0, 0), - TREE_OPERAND (op0, 1)); + if (COMPARISON_CLASS_P (op0) && TREE_CODE (type) == BOOLEAN_TYPE) + return fold_build2_loc (loc, TREE_CODE (op0), type, + TREE_OPERAND (op0, 0), + TREE_OPERAND (op0, 1)); /* Handle cases of two conversions in a row. */ if (CONVERT_EXPR_P (op0)) Index: gcc/gcc/tree-cfg.c =================================================================== --- gcc.orig/gcc/tree-cfg.c 2011-05-20 19:44:41.000000000 +0200 +++ gcc/gcc/tree-cfg.c 2011-05-25 13:17:22.743935300 +0200 @@ -3208,7 +3208,10 @@ 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)) + || !(TREE_CODE (type) == BOOLEAN_TYPE + || (TREE_TYPE (type) && TREE_CODE (type) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE) + || (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1))) { error ("type mismatch in comparison expression"); debug_generic_expr (type); @@ -3352,6 +3355,8 @@ verify_gimple_assign_unary (gimple stmt) case TRUTH_NOT_EXPR: /* We require two-valued operand types. */ if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE + || (TREE_TYPE (rhs1_type) && TREE_CODE (rhs1_type) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (rhs1_type)) == BOOLEAN_TYPE) || (INTEGRAL_TYPE_P (rhs1_type) && TYPE_PRECISION (rhs1_type) == 1))) { Index: gcc/gcc/tree-ssa-forwprop.c =================================================================== --- gcc.orig/gcc/tree-ssa-forwprop.c 2011-05-23 13:49:29.000000000 +0200 +++ gcc/gcc/tree-ssa-forwprop.c 2011-05-23 13:55:35.281805900 +0200 @@ -1152,7 +1152,10 @@ forward_propagate_comparison (gimple stm 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))) + if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)) + && (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE + || (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) + && TYPE_PRECISION (TREE_TYPE (lhs)) == 1))) { /* Avoid using fold here as that may create a COND_EXPR with non-boolean condition as canonical form. */ Index: gcc.dg/tree-ssa/pr30978.c =================================================================== --- gcc.dg/tree-ssa/pr30978.c (revision 174264) +++ gcc.dg/tree-ssa/pr30978.c (working copy) @@ -10,5 +10,5 @@ return e; } -/* { dg-final { scan-tree-dump "e_. = a_..D. > 0;" "optimized" } } */ +/* { dg-final { scan-tree-dump " = a_..D. > 0;\n[^\n]*e_. = \\\(int\\\)" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ Index: gcc.dg/tree-ssa/builtin-expect-5.c =================================================================== --- gcc.dg/tree-ssa/builtin-expect-5.c (revision 174264) +++ gcc.dg/tree-ssa/builtin-expect-5.c (working copy) @@ -11,5 +11,5 @@ /* { 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 {builtin_expect[^\n]*, 1\);} "forwprop1"} } */ /* { dg-final { cleanup-tree-dump "forwprop?" } } */ Index: gcc.dg/tree-ssa/pr21031.c =================================================================== --- gcc.dg/tree-ssa/pr21031.c (revision 174264) +++ gcc.dg/tree-ssa/pr21031.c (working copy) @@ -16,5 +16,5 @@ 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.dg/tree-ssa/ssa-fre-6.c =================================================================== --- gcc.dg/tree-ssa/ssa-fre-6.c (revision 174264) +++ gcc.dg/tree-ssa/ssa-fre-6.c (working copy) @@ -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" } } */