From patchwork Fri Jul 22 19:26:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 651726 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 3rx0yW5JMqz9sR9 for ; Sat, 23 Jul 2016 05:26:57 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=AcEZRWjl; 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:from :to:cc:subject:date:message-id; q=dns; s=default; b=OoafCa+txZ3k u15fH2DQTnSnL1UNnS4shD9Ub/d2ZcBuF0a2llAss0gOHb/NykfLKR2/BoZX0ntc eTNOioJU2Zqw9HcwU93tbFmJDvtHASlHQ90E5HBENGqjV9RfiijPe/WySsOx3hBn aAL/kwv6dlQMxDHXRvKAMgDuubv/18o= 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:from :to:cc:subject:date:message-id; s=default; bh=+g7zKZgWry8o2SuO9I plGTWvnic=; b=AcEZRWjln2WwEwJ4X9gy+F6anPqvK36xjgtT0owQSYI0HhUdNR JJEm6E+OZP6+AxQv1iwSjyXqvnnz7MDpd/KcTBmtsr3Gw+EsNxz45csLvB4TlFce DHtxD/YZrGZyP9qhisLnlr4P4wggbt4s4OYod8thgVBg7OXtfMZkRc4P4= Received: (qmail 28173 invoked by alias); 22 Jul 2016 19:26:50 -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 28163 invoked by uid 89); 22 Jul 2016 19:26:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=anti, fold_build2, bsi, minmax X-HELO: mail-qt0-f193.google.com Received: from mail-qt0-f193.google.com (HELO mail-qt0-f193.google.com) (209.85.216.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 22 Jul 2016 19:26:38 +0000 Received: by mail-qt0-f193.google.com with SMTP id c52so5622018qte.1 for ; Fri, 22 Jul 2016 12:26:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=fdXppXYAiYdv36+RUd32u8WyM2axDVq9MNR3jx1Boj8=; b=TfDkPVhNVYK02lbILjdkTpZbCa2F9OfFcbzqc79Z/BI/woexDNCGr4Fo4YSE1TZ1BC y/YkM+CREO830u27kGXG21xp6LdbH2e/73sh/1Kn1E/4YxnWRo7B1fpfqudhhtXu98v0 yYrecqMMFUOMVf72ZKNr5LMHpCduNvfOSIN2N6Cu24BYNVbhQRjHoQzAnFlwAPkJyQyo SupOPRvL3f3TvfqY8Fp0L/Xv3it96GM0DRmCwR61W26KUTc+JwijUWdlvVdiU6I3v48M QSFR35HkNn1iFk4wJLCmvcpjXqHyzk4cn4f0Gb3Ad4+AySZSkF97KzyaffYLyNZ9A7Ui BDYw== X-Gm-Message-State: AEkoouvZPxEfKKTRhfaKYd+k6nWNZJLsxCyQo7ZpgOWRVsUZzyxWZj91s2UBnKwjs+qtEw== X-Received: by 10.200.47.39 with SMTP id j36mr8875087qta.10.1469215596398; Fri, 22 Jul 2016 12:26:36 -0700 (PDT) Received: from localhost.localdomain (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id 50sm8126430qts.11.2016.07.22.12.26.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Jul 2016 12:26:35 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: Patrick Palka Subject: [PATCH] Teach VRP to register assertions along default switch labels (PR 18046) Date: Fri, 22 Jul 2016 15:26:30 -0400 Message-Id: <20160722192630.23771-1-patrick@parcs.ath.cx> This patch teaches VRP to register along a default switch label assertions that corresponds to the anti range of each case label. Does this look OK to commit after bootstrap + regtest on x86_64-pc-linux-gnu? --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vrp103.c | 30 ++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/vrp104.c | 32 +++++++++++++++++++ gcc/tree-vrp.c | 39 ++++++++++++++++++++++-- 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp103.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp104.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c index 5ec4687..551fbac 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread2-details" } */ /* { dg-final { scan-tree-dump-times "FSM" 3 "thread1" } } */ -/* { dg-final { scan-tree-dump-times "FSM" 4 "thread2" } } */ +/* { dg-final { scan-tree-dump-times "FSM" 5 "thread2" } } */ int sum0, sum1, sum2, sum3; int foo (char *s, char **ret) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp103.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp103.c new file mode 100644 index 0000000..eea98bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp103.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/18046 */ +/* { dg-options "-O2 -fdump-tree-vrp" } */ +/* { dg-final { scan-tree-dump-times "baz \\(0\\);" 4 "vrp1" } } */ + +void foo (); +void bar (); +void baz (int); + +void +test (int i) +{ + switch (i) + { + case 1: + case 2: + case 3: + foo (); + break; + case 5: + bar (); + break; + default: + /* These tests should be folded to 0, resulting in 4 calls to bar (0). */ + baz (i == 1); + baz (i == 2); + baz (i == 3); + baz (i == 5); + break; + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp104.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp104.c new file mode 100644 index 0000000..6410847 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp104.c @@ -0,0 +1,32 @@ +/* PR tree-optimization/18046 */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "switch" 1 "optimized" } } */ + +void foo (); +void bar (); + +void +test (int i) +{ + switch (i) + { + case 1: + foo (); + break; + case 2: + bar (); + break; + default: + break; + } + + /* This switch should be gone after threading/VRP. */ + switch (i) + { + case 1: + foo (); + break; + default: + break; + } +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 06364b7..32a4de3 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5917,6 +5917,7 @@ find_switch_asserts (basic_block bb, gswitch *last) ci[idx].expr = gimple_switch_label (last, idx); ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr)); } + edge default_edge = find_edge (bb, ci[0].bb); qsort (ci, n, sizeof (struct case_info), compare_case_labels); for (idx = 0; idx < n; ++idx) @@ -5945,8 +5946,8 @@ find_switch_asserts (basic_block bb, gswitch *last) max = CASE_LOW (ci[idx].expr); } - /* Nothing to do if the range includes the default label until we - can register anti-ranges. */ + /* Can't extract a useful assertion out of a range that includes the + default label. */ if (min == NULL_TREE) continue; @@ -5963,6 +5964,40 @@ find_switch_asserts (basic_block bb, gswitch *last) fold_convert (TREE_TYPE (op), max)); } + /* For each case label, register along the default label an assertion that + corresponds to the anti-range of that label. */ + for (idx = 0; idx < n; ++idx) + { + tree min, max; + tree cl = ci[idx].expr; + + min = CASE_LOW (cl); + max = CASE_HIGH (cl); + + if (min == NULL_TREE) + continue; + + if (max == NULL_TREE) + { + /* Register the assertion OP != MIN. */ + min = fold_convert (TREE_TYPE (op), min); + register_edge_assert_for (op, default_edge, bsi, NE_EXPR, op, min); + } + else + { + /* Register the assertion (unsigned)OP - MIN > (MAX - MIN), + which will give OP the anti-range ~[MIN,MAX]. */ + tree uop = fold_convert (unsigned_type_for (TREE_TYPE (op)), op); + min = fold_convert (TREE_TYPE (uop), min); + max = fold_convert (TREE_TYPE (uop), max); + + tree lhs = fold_build2 (MINUS_EXPR, TREE_TYPE (uop), uop, min); + tree rhs = int_const_binop (MINUS_EXPR, max, min); + register_new_assert_for (op, lhs, GT_EXPR, rhs, + NULL, default_edge, bsi); + } + } + XDELETEVEC (ci); }