From patchwork Fri Aug 5 13:08:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 656199 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 3s5RvX3bGcz9sf9 for ; Fri, 5 Aug 2016 23:08:39 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Yt+PuWh1; 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=VsRa/WpjTrbP 6EHQlciogNJgemhuE1gCyaHm6fTka+zxuXLEIT6aiNid/jWY3gPzK3WFqsN5P5d2 UgIyLFIjxX9onbYmmaWVRfuCjUWoK3aJud7/5j51zR2yfDYo6Z3KxbXhmTP9InMz li5rC0ES8tuFZStTadYxfonrevwvzfo= 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=wkU14OMECsf4C5UHG8 V+RdPC3yQ=; b=Yt+PuWh1oBSpCrroMt/162lEecLr8O0KRzQYmFAt44OUEAU/wk Beun5t9K4BnbTbPW8zh+pBLt4NFMe4CnNuCZTLfmBUu/iR9RkDkA2ApOl9wtI5+y 8dxV/TsGUSC4P67a4jhFwpHnXw8lZLqer3nNFX7SMs2+qTJD9AjvPkW4Q= Received: (qmail 18971 invoked by alias); 5 Aug 2016 13:08:32 -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 18961 invoked by uid 89); 5 Aug 2016 13:08:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=H*Ad:D*cx X-HELO: mail-qk0-f193.google.com Received: from mail-qk0-f193.google.com (HELO mail-qk0-f193.google.com) (209.85.220.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 05 Aug 2016 13:08:21 +0000 Received: by mail-qk0-f193.google.com with SMTP id x189so15254815qkd.0 for ; Fri, 05 Aug 2016 06:08:21 -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=uu3oczY+0i+yWA47K6LDhi8WoE9w4cFKQik2q3olAGA=; b=Sm/8Gi1UmZuISTl2HCuqGHirSaaKuovqL8/4WpfzWaaZyFYm4ccqsRWBzhUyAaKPtH BujwWNOPYTY1besywrbfgwiudAImox7wuEjZQBD/ZRemVFE4qrrflaPNVVLRi+r8XSiT eirhJ+JEPSaovfKmob0NNe6rLySCzLXPN8xBWys1t88WgMKwz2C81lt1KkfhjYyX5wAk 0DmBk10ySkcINSsjPk1mgbb28DQ7dQP6mM+b1zG7plLfOeypHSQm1jraldcBPzAo7AwS 5UngbFrNoNy4w1r3NOjfdV432ijgi5/kt1g56VCbxVbm5Kbmfx7HkjmsXeDie0HTYupL 66SQ== X-Gm-Message-State: AEkoouu3dg2lcH4FE8dR/mrAT3vdd3ZgkG0ZcR9vKft/V0vfjmmUvmA067kpbR8p8Lu2ug== X-Received: by 10.55.74.14 with SMTP id x14mr12052307qka.102.1470402498960; Fri, 05 Aug 2016 06:08:18 -0700 (PDT) Received: from localhost.localdomain (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id b195sm9582480qkg.9.2016.08.05.06.08.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Aug 2016 06:08:18 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: Patrick Palka Subject: [PATCH] Fix PR tree-optimization/72810 Date: Fri, 5 Aug 2016 09:08:10 -0400 Message-Id: <20160805130810.24901-1-patrick@parcs.ath.cx> Sometimes the case labels of a switch have a different type than the switch operand, e.g. in the test case below, the case labels have type t and the switch operand has type int. Because the verifier expects that case labels of a switch each have the exact same type, it's important to avoid changing their types when truncating their range. Does this patch look OK to commit after bootstrap + regtesting? gcc/ChangeLog: PR tree-optimization/72810 * tree-vrp.c (simplify_switch_using_ranges): Avoid changing the types of the case labels when truncating. gcc/testsuite/ChangeLog: PR tree-optimization/72810 * tree-ssa/vrp110.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/vrp110.c | 24 +++++++++++++++++++ gcc/tree-vrp.c | 43 +++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp110.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp110.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp110.c new file mode 100644 index 0000000..34d7eb4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp110.c @@ -0,0 +1,24 @@ +/* { dg-options "-O2" } */ + +extern void foo (void); +extern void bar (void); + +void +test (int i) +{ + if (i == 1) + return; + + typedef int t; + t j = i; + switch (j) + { + case 1: + case 2: + foo (); + break; + case 7: + bar (); + break; + } +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 7e3b513..2c166db 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9643,61 +9643,66 @@ simplify_switch_using_ranges (gswitch *stmt) tree min_label = gimple_switch_label (stmt, min_idx); tree max_label = gimple_switch_label (stmt, max_idx); + /* Avoid changing the types of the case labels when truncating. */ + tree case_label_type = TREE_TYPE (CASE_LOW (min_label)); + tree vr_min = fold_convert (case_label_type, vr->min); + tree vr_max = fold_convert (case_label_type, vr->max); + if (vr->type == VR_RANGE) { /* If OP's value range is [2,8] and the low label range is 0 ... 3, truncate the label's range to 2 .. 3. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr->min) < 0 + if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr->min) >= 0) - CASE_LOW (min_label) = vr->min; + && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0) + CASE_LOW (min_label) = vr_min; /* If OP's value range is [2,8] and the high label range is 7 ... 10, truncate the label's range to 7 .. 8. */ - if (tree_int_cst_compare (CASE_LOW (max_label), vr->max) <= 0 + if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0 && CASE_HIGH (max_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (max_label), vr->max) > 0) - CASE_HIGH (max_label) = vr->max; + && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) + CASE_HIGH (max_label) = vr_max; } else if (vr->type == VR_ANTI_RANGE) { - tree one_cst = build_one_cst (TREE_TYPE (op)); + tree one_cst = build_one_cst (case_label_type); if (min_label == max_label) { /* If OP's value range is ~[7,8] and the label's range is 7 ... 10, truncate the label's range to 9 ... 10. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr->min) == 0 + if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0 && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr->max) > 0) + && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0) CASE_LOW (min_label) - = int_const_binop (PLUS_EXPR, vr->max, one_cst); + = int_const_binop (PLUS_EXPR, vr_max, one_cst); /* If OP's value range is ~[7,8] and the label's range is 5 ... 8, truncate the label's range to 5 ... 6. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr->min) < 0 + if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr->max) == 0) + && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0) CASE_HIGH (min_label) - = int_const_binop (MINUS_EXPR, vr->min, one_cst); + = int_const_binop (MINUS_EXPR, vr_min, one_cst); } else { /* If OP's value range is ~[2,8] and the low label range is 0 ... 3, truncate the label's range to 0 ... 1. */ - if (tree_int_cst_compare (CASE_LOW (min_label), vr->min) < 0 + if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0 && CASE_HIGH (min_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (min_label), vr->min) >= 0) + && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0) CASE_HIGH (min_label) - = int_const_binop (MINUS_EXPR, vr->min, one_cst); + = int_const_binop (MINUS_EXPR, vr_min, one_cst); /* If OP's value range is ~[2,8] and the high label range is 7 ... 10, truncate the label's range to 9 ... 10. */ - if (tree_int_cst_compare (CASE_LOW (max_label), vr->max) <= 0 + if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0 && CASE_HIGH (max_label) != NULL_TREE - && tree_int_cst_compare (CASE_HIGH (max_label), vr->max) > 0) + && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0) CASE_LOW (max_label) - = int_const_binop (PLUS_EXPR, vr->max, one_cst); + = int_const_binop (PLUS_EXPR, vr_max, one_cst); } }