From patchwork Wed Nov 29 16:51:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 1869768 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=hfrfs6aR; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SgQND5593z1ySY for ; Thu, 30 Nov 2023 03:52:11 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AF0483875448 for ; Wed, 29 Nov 2023 16:52:08 +0000 (GMT) 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 C57B83870919 for ; Wed, 29 Nov 2023 16:51:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C57B83870919 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C57B83870919 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701276716; cv=none; b=faApxeUMNMUhMfn3dk8xAHJpUjWUr3sJ+XIHsNCiLl1Fedz6x4XnqycNbq6rt6iW2jSBB5bO1P9o546Fg1zOv2Xb9aBbnjLnRo5LM9KycMS4VxrSkFx7wfSfwQjnM/I/CEkHtNtFCvznZeFbWhRFP+eg7IPa2BhuXTDaY3c5tik= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701276716; c=relaxed/simple; bh=yKQSF42YNvY9lVia0Fb3bNjIfTqsZaookqmQL2HWn04=; h=DKIM-Signature:Message-ID:Date:MIME-Version:To:From:Subject; b=wuwDRJXKhxbGLc8ZIry+jWWZCYQRhL7oJLu613YDghVX/ngmKBeGvCefrfsxsQb4ou09NzjCKbWoDjZX9R0PRQDD5i0GynNr9hCfgl1+0faAo16SkE1vmrkxAmYawPbo12m1J911MckL13aNsFkH4yZ3nS/rig818JwwHQgQFd4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701276713; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=QY51bx0ZWbc3DJs21FtiRzvaxoHOuz8Aq1n4EBdUaoo=; b=hfrfs6aRjULBnTAJp7pdKRBTxzz+P+p/XUpGiPi6e6z9I4Qk5FQrYVmnZC2+dYp1phKK1h hgnyTJZgYh/38QH0pIS0Egz9GQV3jbmGycOjrx1EZr4z/sBonDj67WusNMvGUATLGKoJjC Aqw5yaXENQdSLiydcuidyvioqnAS1Qw= Received: from mail-oi1-f200.google.com (mail-oi1-f200.google.com [209.85.167.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-599-Yjs476KSP6uZr0lrcB5QBQ-1; Wed, 29 Nov 2023 11:51:51 -0500 X-MC-Unique: Yjs476KSP6uZr0lrcB5QBQ-1 Received: by mail-oi1-f200.google.com with SMTP id 5614622812f47-3b834429a33so7539722b6e.1 for ; Wed, 29 Nov 2023 08:51:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701276710; x=1701881510; h=cc:subject:from:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0dPjQv3ZTrwPFM5RloFAmJtEa8L/RxIruBmAFLAqO04=; b=QpqW6eP0hlvs1j03URSmOmDK4IL5TPhbduvC6LP89tgO99s/kzFa/pFSJtz5QzC13U K7VO/pFYpIbsXZIHsIMSoPQlSU7du2g7eGEKrF/p3XvUhDKgd2ssMBgDdszZZZaNUHUM 8Aaf/EZQ6m5jufc2Q74lKmm/zydRjZIa9BHkMKtMTWUFxfQyMx18lqZ656MIG9wYCiK+ HJofyk9RLLNFQhwlHqsnBOCl098PiWZ+JNeYX6k/ZHr2sesk1fJ9JeTZxfz7oXS2XhaQ S0sOIzkA+yjwAi3sT+pRVOk2gHjYjtilGvNZF/joJ7Gon19Tbdhd6eWHouZg15usklLZ wsCw== X-Gm-Message-State: AOJu0Yw+kzFuQMqUgrszIhBytUFcuuC5zYwnQgNk3+FWg1lG8M08gtpB ymmEi0F7rgvzjnl/8abgXIuVuRfVXFeGDQRoEMP8agQ+KG+1R+9ICC/jX/EntaasGEjASjqz40y H29dqgby3UXUcO2Wvej299mzZru5cnEbU5RXrV+pOyNa3RzmiKSbrkiXsCr6ukGEq+rhYCrWFXy XjZA== X-Received: by 2002:a05:6808:bcc:b0:3b6:d617:a719 with SMTP id o12-20020a0568080bcc00b003b6d617a719mr26234518oik.41.1701276710523; Wed, 29 Nov 2023 08:51:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IEpJpsH5V2ob3VtHj2pohRU1QipG3XuvV6zaYoMMkeks9/HRVS/zuZZnpgSxlc8ITzZVRBrQg== X-Received: by 2002:a05:6808:bcc:b0:3b6:d617:a719 with SMTP id o12-20020a0568080bcc00b003b6d617a719mr26234498oik.41.1701276710219; Wed, 29 Nov 2023 08:51:50 -0800 (PST) Received: from ?IPV6:2607:fea8:51dd:2b00::115f? ([2607:fea8:51dd:2b00::115f]) by smtp.gmail.com with ESMTPSA id m21-20020a05620a221500b0077dcaba6709sm863672qkh.135.2023.11.29.08.51.49 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Nov 2023 08:51:49 -0800 (PST) Message-ID: Date: Wed, 29 Nov 2023 11:51:48 -0500 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: gcc-patches From: Andrew MacLeod Subject: [COMMITTED 1/2] Add operand_check_p to range-ops. Cc: "hernandez, aldy" , Richard Biener X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-12.3 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_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_FILL_THIS_FORM_FRAUD_PHISH, T_FILL_THIS_FORM_SHORT, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org I've been going back and forth with this for the past week, and finally settled on a solution This patch adds an operand_check_p() (lhs_type, op1_type, op2_type) method to range_ops which will confirm whether the types of the operands being passed to fold_range, op1_range, and op2_range  are properly compatible.   For range-ops this basically means the precision matches. It was a bit tricky to do it any other way because various operations allow different precision or even different types in some operand positions. This patch sets up the operand_check_p to return true by default, which means there is no variation from what we do today.  However, I have gone in to all the integral/mixed range operators, and added checks for things like  X = Y + Z requiring the precision to be the same for all 3 operands.   however x = y && z only requires OP1 and OP2 to be the same precision, and  x = ~y only requires the LHS and OP1 to match. This call is utilized in a gcc_assert when CHECKING_P is on for fold_range(), op1_range() and op2_range() to provide compilation time verification while not costing anything for a release build. Bootstraps on x86_64-pc-linux-gnu with no regressions. committed. Andrew From 9f1149ef823b64ead6115f79f99ddf8eead1c2f4 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 28 Nov 2023 09:39:30 -0500 Subject: [PATCH 1/2] Add operand_check_p to range-ops. Add an optional method to verify operands are compatible, and check the operands before all range operations. * range-op-mixed.h (operator_equal::operand_check_p): New. (operator_not_equal::operand_check_p): New. (operator_lt::operand_check_p): New. (operator_le::operand_check_p): New. (operator_gt::operand_check_p): New. (operator_ge::operand_check_p): New. (operator_plus::operand_check_p): New. (operator_abs::operand_check_p): New. (operator_minus::operand_check_p): New. (operator_negate::operand_check_p): New. (operator_mult::operand_check_p): New. (operator_bitwise_not::operand_check_p): New. (operator_bitwise_xor::operand_check_p): New. (operator_bitwise_and::operand_check_p): New. (operator_bitwise_or::operand_check_p): New. (operator_min::operand_check_p): New. (operator_max::operand_check_p): New. * range-op.cc (range_op_handler::fold_range): Check operand parameter types. (range_op_handler::op1_range): Ditto. (range_op_handler::op2_range): Ditto. (range_op_handler::operand_check_p): New. (range_operator::operand_check_p): New. (operator_lshift::operand_check_p): New. (operator_rshift::operand_check_p): New. (operator_logical_and::operand_check_p): New. (operator_logical_or::operand_check_p): New. (operator_logical_not::operand_check_p): New. * range-op.h (range_operator::operand_check_p): New. (range_op_handler::operand_check_p): New. --- gcc/range-op-mixed.h | 63 +++++++++++++++++++++++++++++++++++++++++--- gcc/range-op.cc | 53 ++++++++++++++++++++++++++++++++++--- gcc/range-op.h | 5 ++++ 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index 45e11df57df..4386a68e946 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -138,6 +138,9 @@ public: const frange &) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check op1 and op2 for compatibility. + bool operand_check_p (tree, tree t1, tree t2) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; class operator_not_equal : public range_operator @@ -174,6 +177,9 @@ public: const frange &) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check op1 and op2 for compatibility. + bool operand_check_p (tree, tree t1, tree t2) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; class operator_lt : public range_operator @@ -207,6 +213,9 @@ public: const frange &) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check op1 and op2 for compatibility. + bool operand_check_p (tree, tree t1, tree t2) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; class operator_le : public range_operator @@ -243,6 +252,9 @@ public: const frange &) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check op1 and op2 for compatibility. + bool operand_check_p (tree, tree t1, tree t2) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; class operator_gt : public range_operator @@ -278,6 +290,9 @@ public: const frange &) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check op1 and op2 for compatibility. + bool operand_check_p (tree, tree t1, tree t2) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; class operator_ge : public range_operator @@ -314,6 +329,9 @@ public: const frange &) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check op1 and op2 for compatibility. + bool operand_check_p (tree, tree t1, tree t2) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; class operator_identity : public range_operator @@ -409,7 +427,10 @@ public: virtual bool overflow_free_p (const irange &lh, const irange &rh, relation_trio = TRIO_VARYING) const; - + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -436,6 +457,9 @@ class operator_abs : public range_operator relation_trio rel = TRIO_VARYING) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check compatibility of LHS and op1. + bool operand_check_p (tree t1, tree t2, tree) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -477,7 +501,10 @@ public: virtual bool overflow_free_p (const irange &lh, const irange &rh, relation_trio = TRIO_VARYING) const; - + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -506,6 +533,9 @@ class operator_negate : public range_operator bool op1_range (frange &r, tree type, const frange &lhs, const frange &op2, relation_trio rel = TRIO_VARYING) const final override; + // Check compatibility of LHS and op1. + bool operand_check_p (tree t1, tree t2, tree) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } }; @@ -557,7 +587,10 @@ public: relation_kind kind) const final override; virtual bool overflow_free_p (const irange &lh, const irange &rh, relation_trio = TRIO_VARYING) const; - + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } }; class operator_addr_expr : public range_operator @@ -586,6 +619,10 @@ public: relation_trio rel = TRIO_VARYING) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } }; class operator_bitwise_xor : public range_operator @@ -606,6 +643,10 @@ public: relation_kind rel) const final override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } private: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -629,6 +670,10 @@ public: relation_kind) const override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const override; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -651,6 +696,10 @@ public: relation_trio rel = TRIO_VARYING) const override; void update_bitmask (irange &r, const irange &lh, const irange &rh) const override; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -662,6 +711,10 @@ class operator_min : public range_operator public: void update_bitmask (irange &r, const irange &lh, const irange &rh) const override; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, @@ -673,6 +726,10 @@ class operator_max : public range_operator public: void update_bitmask (irange &r, const irange &lh, const irange &rh) const override; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } protected: void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 6137f2aeed3..a091815997d 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -201,6 +201,10 @@ range_op_handler::fold_range (vrange &r, tree type, relation_trio rel) const { gcc_checking_assert (m_operator); +#if CHECKING_P + if (!lh.undefined_p () && !rh.undefined_p ()) + gcc_assert (m_operator->operand_check_p (type, lh.type (), rh.type ())); +#endif switch (dispatch_kind (r, lh, rh)) { case RO_III: @@ -237,9 +241,12 @@ range_op_handler::op1_range (vrange &r, tree type, relation_trio rel) const { gcc_checking_assert (m_operator); - if (lhs.undefined_p ()) return false; +#if CHECKING_P + if (!op2.undefined_p ()) + gcc_assert (m_operator->operand_check_p (lhs.type (), type, op2.type ())); +#endif switch (dispatch_kind (r, lhs, op2)) { case RO_III: @@ -270,7 +277,10 @@ range_op_handler::op2_range (vrange &r, tree type, gcc_checking_assert (m_operator); if (lhs.undefined_p ()) return false; - +#if CHECKING_P + if (!op1.undefined_p ()) + gcc_assert (m_operator->operand_check_p (lhs.type (), op1.type (), type)); +#endif switch (dispatch_kind (r, lhs, op1)) { case RO_III: @@ -394,6 +404,13 @@ range_op_handler::overflow_free_p (const vrange &lh, } } +bool +range_op_handler::operand_check_p (tree t1, tree t2, tree t3) const +{ + gcc_checking_assert (m_operator); + return m_operator->operand_check_p (t1, t2, t3); +} + // Update the known bitmasks in R when applying the operation CODE to // LH and RH. @@ -737,6 +754,14 @@ range_operator::update_bitmask (irange &, const irange &, { } +// Check that operand types are OK. Default to always OK. + +bool +range_operator::operand_check_p (tree, tree, tree) const +{ + return true; +} + // Create and return a range from a pair of wide-ints that are known // to have overflowed (or underflowed). @@ -2466,6 +2491,9 @@ public: void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override { update_known_bitmask (r, LSHIFT_EXPR, lh, rh); } + // Check compatibility of LHS and op1. + bool operand_check_p (tree t1, tree t2, tree) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } } op_lshift; class operator_rshift : public cross_product_operator @@ -2495,6 +2523,9 @@ public: void update_bitmask (irange &r, const irange &lh, const irange &rh) const final override { update_known_bitmask (r, RSHIFT_EXPR, lh, rh); } + // Check compatibility of LHS and op1. + bool operand_check_p (tree t1, tree t2, tree) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } } op_rshift; @@ -3070,9 +3101,12 @@ public: const irange &lhs, const irange &op1, relation_trio rel = TRIO_VARYING) const; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } } op_logical_and; - bool operator_logical_and::fold_range (irange &r, tree type, const irange &lh, @@ -3082,6 +3116,11 @@ operator_logical_and::fold_range (irange &r, tree type, if (empty_range_varying (r, type, lh, rh)) return true; + // Precision of LHS and both operands must match. + if (TYPE_PRECISION (lh.type ()) != TYPE_PRECISION (type) + || TYPE_PRECISION (type) != TYPE_PRECISION (rh.type ())) + return false; + // 0 && anything is 0. if ((wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (lh.upper_bound (), 0)) || (wi::eq_p (lh.lower_bound (), 0) && wi::eq_p (rh.upper_bound (), 0))) @@ -3567,6 +3606,10 @@ public: const irange &lhs, const irange &op1, relation_trio rel = TRIO_VARYING) const; + // Check compatibility of all operands. + bool operand_check_p (tree t1, tree t2, tree t3) const final override + { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); } } op_logical_or; bool @@ -3993,6 +4036,9 @@ public: const irange &lhs, const irange &op2, relation_trio rel = TRIO_VARYING) const; + // Check compatibility of LHS and op1. + bool operand_check_p (tree t1, tree t2, tree) const final override + { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); } } op_logical_not; // Folding a logical NOT, oddly enough, involves doing nothing on the @@ -4036,7 +4082,6 @@ operator_logical_not::op1_range (irange &r, return fold_range (r, type, lhs, op2); } - bool operator_bitwise_not::fold_range (irange &r, tree type, const irange &lh, diff --git a/gcc/range-op.h b/gcc/range-op.h index 282ce386836..ab8f8a36fd5 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -157,6 +157,10 @@ public: virtual bool overflow_free_p (const irange &lh, const irange &rh, relation_trio = TRIO_VARYING) const; + + // Compatability check for operands. + virtual bool operand_check_p (tree, tree, tree) const; + protected: // Perform an integral operation between 2 sub-ranges and return it. virtual void wi_fold (irange &r, tree type, @@ -226,6 +230,7 @@ public: const vrange &op2) const; bool overflow_free_p (const vrange &lh, const vrange &rh, relation_trio = TRIO_VARYING) const; + bool operand_check_p (tree, tree, tree) const; protected: unsigned dispatch_kind (const vrange &lhs, const vrange &op1, const vrange& op2) const; -- 2.41.0