From patchwork Sat Mar 12 01:57:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 596563 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AEBA3140271 for ; Sat, 12 Mar 2016 12:57:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=kuHh5LiF; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=wMWBDiveon8R4e/vB 4STuiauY8qHojJqvxIpi9IYW05u04f/G0T7PRSz0NZvspX/K3y8UG0ekvOCAvQH3 36nu2waYXYkO1ZoLJN6B5r6isfVTGy1xhMYtM8P4nIXt4dEkx5YgSbnyYBxjK4ks +nwePBHC5+97yQlkHhsNbTLdBM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=ymsXzipnW+/r8YztIvpqOMI qi6w=; b=kuHh5LiFX+9ITkNxggsk7RmsU/vsa1IAnffHbaGH/UMRqFcJnAZgc0o K3K3JcvI9SiLJ3ugbFsY32cHzbp6aPV4Pg7fVtXNfauyV8Fa9mnaCR94FBtDc2/V OWUAYRoFCji89IqSDID5CIRV++yhW5x7gN/JMqppQLlGmVRPp23o= Received: (qmail 7583 invoked by alias); 12 Mar 2016 01:57:25 -0000 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 Received: (qmail 7522 invoked by uid 89); 12 Mar 2016 01:57:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sk:flag_un, fputc, success!, update_stmt X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sat, 12 Mar 2016 01:57:21 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 9472DA7571; Sat, 12 Mar 2016 01:57:19 +0000 (UTC) Received: from bigtime.twiddle.net (ovpn-113-22.phx2.redhat.com [10.3.113.22]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u2C1vI0h024207; Fri, 11 Mar 2016 20:57:18 -0500 Subject: Re: [PATCH, match] Fix pr68714 To: Richard Biener References: <56D5F4AC.9030504@redhat.com> Cc: gcc-patches@gcc.gnu.org, Jakub Jelinek From: Richard Henderson Message-ID: <56E3777D.2080604@redhat.com> Date: Fri, 11 Mar 2016 17:57:17 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: X-IsSubscribed: yes On 03/02/2016 01:31 AM, Richard Biener wrote: > As a general remark I think handling of this simplification is > better done in the reassoc pass (see Jakubs comment #4) given > || and && associate. So I'd rather go down that route if possible. This seems to do the trick. r~ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c new file mode 100644 index 0000000..741d311 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68714.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +typedef int vec __attribute__((vector_size(16))); +vec f(vec x,vec y){ + return x (SSA_NAME_DEF_STMT (var)); + if (stmt == NULL) + return ERROR_MARK; + + /* ??? If we start creating more COND_EXPR, we could perform + this same optimization with them. For now, simplify. */ + if (gimple_assign_rhs_code (stmt) != VEC_COND_EXPR) + return ERROR_MARK; + + tree cond = gimple_assign_rhs1 (stmt); + tree_code cmp = TREE_CODE (cond); + if (TREE_CODE_CLASS (cmp) != tcc_comparison) + return ERROR_MARK; + + /* ??? For now, allow only canonical true and false result vectors. + We could expand this to other constants should the need arise, + but at the moment we don't create them. */ + tree t = gimple_assign_rhs2 (stmt); + tree f = gimple_assign_rhs3 (stmt); + bool inv; + if (integer_all_onesp (t)) + inv = false; + else if (integer_all_onesp (f)) + { + cmp = invert_tree_comparison (cmp, false); + inv = true; + } + else + return ERROR_MARK; + if (!integer_zerop (f)) + return ERROR_MARK; + + /* Success! */ + if (rets) + *rets = stmt; + if (reti) + *reti = inv; + return cmp; +} + +/* Optimize the condition of VEC_COND_EXPRs which have been combined + with OPCODE (either BIT_AND_EXPR or BIT_IOR_EXPR). */ + +static bool +optimize_vec_cond_expr (tree_code opcode, vec *ops) +{ + unsigned int length = ops->length (), i, j; + bool any_changes = false; + + if (length == 1) + return false; + + for (i = 0; i < length; ++i) + { + tree elt0 = (*ops)[i]->op; + + gassign *stmt0; + bool invert; + tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert); + if (cmp0 == ERROR_MARK) + continue; + + for (j = i + 1; j < length; ++j) + { + tree &elt1 = (*ops)[j]->op; + + gassign *stmt1; + tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL); + if (cmp1 == ERROR_MARK) + continue; + + tree cond0 = gimple_assign_rhs1 (stmt0); + tree x0 = TREE_OPERAND (cond0, 0); + tree y0 = TREE_OPERAND (cond0, 1); + + tree cond1 = gimple_assign_rhs1 (stmt1); + tree x1 = TREE_OPERAND (cond1, 0); + tree y1 = TREE_OPERAND (cond1, 1); + + tree comb; + if (opcode == BIT_AND_EXPR) + comb = maybe_fold_and_comparisons (cmp0, x0, y0, cmp1, x1, y1); + else if (opcode == BIT_IOR_EXPR) + comb = maybe_fold_or_comparisons (cmp0, x0, y0, cmp1, x1, y1); + else + gcc_unreachable (); + if (comb == NULL) + continue; + + /* Success! */ + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Transforming "); + print_generic_expr (dump_file, cond0, 0); + fprintf (dump_file, " %c ", opcode == BIT_AND_EXPR ? '&' : '|'); + print_generic_expr (dump_file, cond1, 0); + fprintf (dump_file, " into "); + print_generic_expr (dump_file, comb, 0); + fputc ('\n', dump_file); + } + + gimple_assign_set_rhs1 (stmt0, comb); + if (invert) + std::swap (*gimple_assign_rhs2_ptr (stmt0), + *gimple_assign_rhs3_ptr (stmt0)); + update_stmt (stmt0); + + elt1 = error_mark_node; + any_changes = true; + } + } + + if (any_changes) + { + operand_entry *oe; + j = 0; + FOR_EACH_VEC_ELT (*ops, i, oe) + { + if (oe->op == error_mark_node) + continue; + else if (i != j) + (*ops)[j] = oe; + j++; + } + ops->truncate (j); + } + + return any_changes; +} + /* Return true if STMT is a cast like: : ... @@ -4326,7 +4466,7 @@ static bool can_reassociate_p (tree op) { tree type = TREE_TYPE (op); - if ((INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) + if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) || NON_SAT_FIXED_POINT_TYPE_P (type) || (flag_associative_math && FLOAT_TYPE_P (type))) return true; @@ -4952,6 +5092,7 @@ reassociate_bb (basic_block bb) { auto_vec ops; tree powi_result = NULL_TREE; + bool is_vector = VECTOR_TYPE_P (TREE_TYPE (lhs)); /* There may be no immediate uses left by the time we get here because we may have eliminated them all. */ @@ -4970,15 +5111,21 @@ reassociate_bb (basic_block bb) } if (rhs_code == BIT_IOR_EXPR || rhs_code == BIT_AND_EXPR) - optimize_range_tests (rhs_code, &ops); + { + if (is_vector) + optimize_vec_cond_expr (rhs_code, &ops); + else + optimize_range_tests (rhs_code, &ops); + } - if (rhs_code == MULT_EXPR) - attempt_builtin_copysign (&ops); + if (rhs_code == MULT_EXPR && !is_vector) + { + attempt_builtin_copysign (&ops); - if (reassoc_insert_powi_p - && rhs_code == MULT_EXPR - && flag_unsafe_math_optimizations) - powi_result = attempt_builtin_powi (stmt, &ops); + if (reassoc_insert_powi_p + && flag_unsafe_math_optimizations) + powi_result = attempt_builtin_powi (stmt, &ops); + } /* If the operand vector is now empty, all operands were consumed by the __builtin_powi optimization. */