From patchwork Fri May 13 14:21:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 53950 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9A925396D807 for ; Fri, 13 May 2022 14:25:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9A925396D807 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1652451911; bh=AGHhfoBcif9qeArWESGMhrDC4twD/iZdzvvdcQ54A1c=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Zzmm46GwUqW9kYi8WHZrGvXArmQEvl1uob+RMm3WgV3UXPYEK6rneMNL9qo1O8t02 pE0biFaNwgG8tPHBcDNbJVi7eDGLrXOo14PSygjR0UPiXj27/1qh8RpaX/a7yhyOcd +86Q6hBeYV/lLipgZwld487j3+J4LSIlvjywju1Q= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id C9333396DC16 for ; Fri, 13 May 2022 14:21:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C9333396DC16 Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-369--ZTC_f61Ni-KTYFMGKAXTw-1; Fri, 13 May 2022 10:21:41 -0400 X-MC-Unique: -ZTC_f61Ni-KTYFMGKAXTw-1 Received: by mail-qv1-f72.google.com with SMTP id j2-20020a0cfd42000000b0045ad9cba5deso6970686qvs.5 for ; Fri, 13 May 2022 07:21:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent :content-language:to:cc:from:subject; bh=XWtBlRbb+lP+ZPXcL6iNI5toE7nfiRjqyf0oxijZ2oc=; b=XVUlos61IxMMdg5qDYBGWgPOxNOo8s7+nrCdUiNteFxWRSs9n8t25Ry1hUBuwEPkSo KypaML4szv4FLA1MVtSW2R4YLp3tGsbYoSqUdwYOdkVc/jTP0WYUWGyluKGXyG+KHKeH 3SxmgYykH4tyV5z+Mw7RgA4O1EQf/5Ce0R1yJVa3D1jP7SNr2FozjtmKio28CRCHUZxJ zYuxnHfEDYZxRXsjE63sPdrexy3bPLKw/WOpE4YR82VVtdYsQFcsLxoVpW4INeCVdN8V 2/zCYOw0tfhsJcG2TUWH9wgM5p/4E05jUAZZrKi0jjmH43i9jNXaDlx8XxV1jRYfMBeS jJkg== X-Gm-Message-State: AOAM531JfktrtT4y/iAzS5G3Y3lUolujVM2w7obBGLBoMuYCj1VmVdt5 F+n1XPqDdMDDUOQN4//0wQ307BU2bEL9KBogLfsZg7WxzcHyhtSAXk1cv3oOeUh5BImI9zEfhRQ kizAsBzS6o61gOLLI2CvSG1d5wjJmvdGcsvAcQJdFBnOy+g8SnHTZsiUZQMS1wtT8ncHLqA== X-Received: by 2002:a05:620a:2849:b0:687:651:54ee with SMTP id h9-20020a05620a284900b00687065154eemr3918123qkp.446.1652451700264; Fri, 13 May 2022 07:21:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw21MP07IGShQZdoH1wGhs0M/W02brtoz95426qGx6ekK1dxtrz6Wqi/fm/KS9F1rk7mHQvuQ== X-Received: by 2002:a05:620a:2849:b0:687:651:54ee with SMTP id h9-20020a05620a284900b00687065154eemr3918099qkp.446.1652451699883; Fri, 13 May 2022 07:21:39 -0700 (PDT) Received: from ?IPV6:2607:fea8:a261:5e00::94b0? ([2607:fea8:a261:5e00::94b0]) by smtp.gmail.com with ESMTPSA id o4-20020ac87c44000000b002f39b99f6basm1597100qtv.84.2022.05.13.07.21.38 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 13 May 2022 07:21:39 -0700 (PDT) Message-ID: Date: Fri, 13 May 2022 10:21:37 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.0 To: gcc-patches Subject: [COMMITTED] PR tree-optimization/104547 - Add relation between op1 & op2 to lhs_opN_relation API. X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-CA X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew MacLeod via Gcc-patches From: Andrew MacLeod Reply-To: Andrew MacLeod Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" We use the relation between op1 and op2 to help fold a statement, but it was not provided to the lhs_op1_relation and lhs_op2_relation routines to determine if is also creates a relation between the LHS and either operand. This patch adds the relation to the API.  It also implelements the basic operation that for unsigned values,    lhs = op1 - op2 that   if op1 > op2, then LHS < op1  and  if op1 >= op2, then LHS <= op1 If someone wants to make this work with signed values and handle all the cases, or extend it to deal with the relations between LHS and op2, feel free.. it gives me a headache when I try. The relevant routine is operator_minus::lhs_op1_relation().  and would simply have to add the operator_minus::lhs_op2_relation to deal with the op2 case. This resolves the PR, bootstraps on x86_64-pc-linux-gnu with no regressions.  pushed. Andrew commit cf2141a0c640fc9b1c497db3f4d5b270f4b8252a Author: Andrew MacLeod Date: Tue Feb 15 10:17:26 2022 -0500 Add relation between op1 & op2 to lhs_opN_relation API. We use the relation between op1 and op2 to help fold a statement, but it was not provided to the lhs_op1_relation and lhs_op2_relation routines to determine if is also creates a relation between the LHS and either operand. gcc/ PR tree-optimization/104547 * gimple-range-fold.cc (fold_using_range::range_of_range_op): Add the op1/op2 relation to the relation call. * range-op.cc (*::lhs_op1_relation): Add param. (*::lhs_op2_relation): Ditto. (operator_minus::lhs_op1_relation): New. (range_relational_tests): Add relation param. * range-op.h (lhs_op1_relation, lhs_op2_relation): Adjust prototype. gcc/testsuite/ * g++.dg/pr104547.C: New. diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 08d791a0418..bc8174e15e6 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -640,13 +640,13 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) } if (gimple_range_ssa_p (op1)) { - rel = handler->lhs_op1_relation (r, range1, range2); + rel = handler->lhs_op1_relation (r, range1, range2, rel); if (rel != VREL_NONE) src.register_relation (s, rel, lhs, op1); } if (gimple_range_ssa_p (op2)) { - rel= handler->lhs_op2_relation (r, range1, range2); + rel= handler->lhs_op2_relation (r, range1, range2, rel); if (rel != VREL_NONE) src.register_relation (s, rel, lhs, op2); } diff --git a/gcc/range-op.cc b/gcc/range-op.cc index eaa02309d70..d015b9f1363 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -249,7 +249,8 @@ range_operator::op2_range (irange &r ATTRIBUTE_UNUSED, enum tree_code range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, const irange &op1 ATTRIBUTE_UNUSED, - const irange &op2 ATTRIBUTE_UNUSED) const + const irange &op2 ATTRIBUTE_UNUSED, + relation_kind rel ATTRIBUTE_UNUSED) const { return VREL_NONE; } @@ -257,7 +258,8 @@ range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, enum tree_code range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, const irange &op1 ATTRIBUTE_UNUSED, - const irange &op2 ATTRIBUTE_UNUSED) const + const irange &op2 ATTRIBUTE_UNUSED, + relation_kind rel ATTRIBUTE_UNUSED) const { return VREL_NONE; } @@ -1182,9 +1184,11 @@ public: const wide_int &rh_lb, const wide_int &rh_ub) const; virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1, - const irange &op2) const; + const irange &op2, + relation_kind rel) const; virtual enum tree_code lhs_op2_relation (const irange &lhs, const irange &op1, - const irange &op2) const; + const irange &op2, + relation_kind rel) const; } op_plus; // Check to see if the range of OP2 indicates anything about the relation @@ -1193,7 +1197,8 @@ public: enum tree_code operator_plus::lhs_op1_relation (const irange &lhs, const irange &op1, - const irange &op2) const + const irange &op2, + relation_kind) const { if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ()) return VREL_NONE; @@ -1258,9 +1263,9 @@ operator_plus::lhs_op1_relation (const irange &lhs, enum tree_code operator_plus::lhs_op2_relation (const irange &lhs, const irange &op1, - const irange &op2) const + const irange &op2, relation_kind rel) const { - return lhs_op1_relation (lhs, op2, op1); + return lhs_op1_relation (lhs, op2, op1, rel); } void @@ -1310,6 +1315,10 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; + virtual enum tree_code lhs_op1_relation (const irange &lhs, + const irange &op1, + const irange &op2, + relation_kind rel) const; virtual bool op1_op2_relation_effect (irange &lhs_range, tree type, const irange &op1_range, @@ -1329,6 +1338,27 @@ operator_minus::wi_fold (irange &r, tree type, value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub); } + +// Return the relation between LHS and OP1 based on the relation between +// OP1 and OP2. + +enum tree_code +operator_minus::lhs_op1_relation (const irange &lhs, const irange &, + const irange &, relation_kind rel) const +{ + if (TYPE_SIGN (lhs.type ()) == UNSIGNED) + switch (rel) + { + case GT_EXPR: + return LT_EXPR; + case GE_EXPR: + return LE_EXPR; + default: + break; + } + return VREL_NONE; +} + // Check to see if the relation REL between OP1 and OP2 has any effect on the // LHS of the expression. If so, apply it to LHS_RANGE. This is a helper // function for both MINUS_EXPR and POINTER_DIFF_EXPR. @@ -1899,14 +1929,16 @@ public: relation_kind rel = VREL_NONE) const; virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1, - const irange &op2) const; + const irange &op2, + relation_kind rel) const; } op_rshift; enum tree_code operator_rshift::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, const irange &op1, - const irange &op2) const + const irange &op2, + relation_kind) const { // If both operands range are >= 0, then the LHS <= op1. if (!op1.undefined_p () && !op2.undefined_p () @@ -3532,7 +3564,8 @@ public: relation_kind rel = VREL_NONE) const; virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1, - const irange &op2) const; + const irange &op2, + relation_kind rel) const; } op_identity; // Determine if there is a relationship between LHS and OP1. @@ -3540,7 +3573,8 @@ public: enum tree_code operator_identity::lhs_op1_relation (const irange &lhs, const irange &op1 ATTRIBUTE_UNUSED, - const irange &op2 ATTRIBUTE_UNUSED) const + const irange &op2 ATTRIBUTE_UNUSED, + relation_kind) const { if (lhs.undefined_p ()) return VREL_NONE; @@ -4427,19 +4461,19 @@ range_relational_tests () int_range<2> op2 (UCHAR (20), UCHAR (20)); // Never wrapping additions mean LHS > OP1. - tree_code code = op_plus.lhs_op1_relation (lhs, op1, op2); + tree_code code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE); ASSERT_TRUE (code == GT_EXPR); // Most wrapping additions mean nothing... op1 = int_range<2> (UCHAR (8), UCHAR (10)); op2 = int_range<2> (UCHAR (0), UCHAR (255)); - code = op_plus.lhs_op1_relation (lhs, op1, op2); + code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE); ASSERT_TRUE (code == VREL_NONE); // However, always wrapping additions mean LHS < OP1. op1 = int_range<2> (UCHAR (1), UCHAR (255)); op2 = int_range<2> (UCHAR (255), UCHAR (255)); - code = op_plus.lhs_op1_relation (lhs, op1, op2); + code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE); ASSERT_TRUE (code == LT_EXPR); } diff --git a/gcc/range-op.h b/gcc/range-op.h index c93eb844547..a1f98cd5226 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -78,12 +78,15 @@ public: // The following routines are used to represent relations between the // various operations. If the caller knows where the symbolics are, // it can query for relationships between them given known ranges. + // the optional relation passed in is the relation between op1 and op2. virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1, - const irange &op2) const; + const irange &op2, + relation_kind rel = VREL_NONE) const; virtual enum tree_code lhs_op2_relation (const irange &lhs, const irange &op1, - const irange &op2) const; + const irange &op2, + relation_kind rel = VREL_NONE) const; virtual enum tree_code op1_op2_relation (const irange &lhs) const; protected: // Perform an integral operation between 2 sub-ranges and return it. diff --git a/gcc/testsuite/g++.dg/pr104547.C b/gcc/testsuite/g++.dg/pr104547.C new file mode 100644 index 00000000000..b6135ffe3a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr104547.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-O3 -fdump-tree-vrp2" } + +#include + +void shrink(std::vector& v, unsigned n) { + if (v.size() < n) + __builtin_unreachable(); + v.resize(v.size() - n); +} + +// Verify that std::vector::_M_default_append() has been removed by vrp2. +// { dg-final { scan-tree-dump-not "_M_default_append" vrp2 } }