From patchwork Thu Jan 12 20:31:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 42780 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp4091719wrt; Thu, 12 Jan 2023 12:32:13 -0800 (PST) X-Google-Smtp-Source: AMrXdXuAVgbBVpe5XPQt3kLMhfVUY6+I+K6Ssxu2yTlnxcRF1Dqpq+a4alxL4fIXgys+YcQ3OVMB X-Received: by 2002:aa7:d599:0:b0:496:b479:e437 with SMTP id r25-20020aa7d599000000b00496b479e437mr21205398edq.27.1673555533495; Thu, 12 Jan 2023 12:32:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673555533; cv=none; d=google.com; s=arc-20160816; b=mILupHxxWmLpL6lBAjH4yYqNqGQPGsxPSCAjAOlGlWYtC+WaU9bpOoDhprYMKGa2YM Q5jHjtxWPYZXUFRGewdcRVXo2crfsy1cUd01WbG055G+yZFX+2j5P744u+Xtf5owd1Eo v16TTftPir1TG8lZga7blRCM+SdBUVS1a3IOtV+T03z9KWfkBU+B/zegoI9dfZ48ZjJC z1YvDBB4LundPgSPWoarwhbxGN4qxFeKcBYICXkqPGKwtC1AgJ6E7kAFWskD2572ss/b cyKtTDD0p+3TcvANyYESCVIoZCU6xuZR6X/v+RC4icoR4ETWM2U4FREFQ1H/s6jZWepG XaSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:in-reply-to:mime-version:references:message-id :subject:to:date:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=vRY9NKvz3z08KZLWk0A2ldgLDh8sb8pSPu6atabYT+k=; b=cs+kNsxlpWPrWLMxRuKU20PFfT//zZ+jykTdzVD+9OIwlitgG8Ua0945GPlJcmeovR yVZzySFECYANDEOOiO514vc2qGwosH5ejwXETkS9gjQuKrHdnlm01g4M9KCIW9LBnJXI U6UXqlDoGYPj0wlVl3ug/cTv5uJCYv8+0Dn2KbK832yRLnQaAxlwSGYLf8FuPLPkiVGM bFAXauxXE5GIpwdqs0813FDgOU7xMcGfTss5KZH93z+ylkil7W9w0agIJaNmXOun1wPj kJqjPcK+jgYomGvnVmVihE9aiOU/ikgvqafJ9d0Bhbhdfc65LJ/5LAvWw4WwpNsXWhvw 69cg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=PIUd2aji; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id w13-20020a05640234cd00b0048ddbdac278si21996704edc.32.2023.01.12.12.32.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Jan 2023 12:32:13 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=PIUd2aji; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 52A0838543B4 for ; Thu, 12 Jan 2023 20:32:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 52A0838543B4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1673555532; bh=vRY9NKvz3z08KZLWk0A2ldgLDh8sb8pSPu6atabYT+k=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=PIUd2ajiwnPC8jBhUjeFcgDz3YWNQaCJMmWzG6hJtqGbN8AT/U+JgnjVVSxQqDdih whRqOi54YPjiZDNLJWx2sVWxyEaHZNZuTJnJmoBEzJYj+gM9nkKhRL6JB3+nn3zhV+ Qj6ffy0OeofaPrhSKLPe4v1JN1BEDR5yCS+ya4IQ= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 4E36D3858C66 for ; Thu, 12 Jan 2023 20:31:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4E36D3858C66 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-578-KSZd78hyPeabYlQGeE0UnQ-1; Thu, 12 Jan 2023 15:31:27 -0500 X-MC-Unique: KSZd78hyPeabYlQGeE0UnQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 323983C0D19F for ; Thu, 12 Jan 2023 20:31:27 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.223]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DEC5D2166B26; Thu, 12 Jan 2023 20:31:26 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 30CKVNVR3436774 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 12 Jan 2023 21:31:24 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 30CKVNks3436773; Thu, 12 Jan 2023 21:31:23 +0100 Date: Thu, 12 Jan 2023 21:31:23 +0100 To: Jason Merrill , gcc-patches@gcc.gnu.org Subject: [PATCH] c, c++, v2: Avoid incorrect shortening of divisions [PR108365] Message-ID: References: <643ddc0e-2a76-c601-e7f6-8b6bb2b3974e@redhat.com> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP 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: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1754850167417898848?= X-GMAIL-MSGID: =?utf-8?q?1754850167417898848?= On Thu, Jan 12, 2023 at 08:55:32PM +0100, Jakub Jelinek via Gcc-patches wrote: > > > So, the following patch for the NOP_EXPR cases checks just in case that > > > it is from integral type and more importantly checks it is a widening > > > conversion, and then next to it also allows op0 to be just unsigned, > > > promoted or not, as that is what the C FE will do for those cases too > > > and I believe it must work - either the division/modulo common type > > > will be that unsigned type, then we can shorten and don't need to worry > > > about UB, or it will be some wider signed type but then it can't be most > > > negative value of the wider type. > > > > Why not use the same condition in C and C++? > > I can test that. Do you mean change the C FE to match the patched C++ > or change C++ FE to just test TYPE_UNSIGNED (orig_op0)? > I think both should work, though what I wrote perhaps can shorten in more > cases. Can try to construct testcases where it differs... E.g. int f1 (int x, int y) { return (unsigned) x / y; } unsigned short f2 (unsigned short x, unsigned short y) { return (unsigned) x / y; } unsigned int f3 (unsigned int x, unsigned int y) { return (long long) x / y; } C++ FE before and after the patch shortens the division in f2 and f3, C FE shortens only in f2. So using the C FE condition would be a regression for C++. Therefore I'm going to test following patch: 2023-01-12 Jakub Jelinek PR c++/108365 * c-typeck.cc (build_binary_op): For integral division or modulo, shorten if type0 is unsigned, or op0 is cast from narrower unsigned integral type or op1 is INTEGER_CST other than -1. * typeck.cc (cp_build_binary_op): For integral division or modulo, shorten if type0 is unsigned, or op0 is cast from narrower unsigned integral type or stripped_op1 is INTEGER_CST other than -1. * c-c++-common/pr108365.c: New test. * g++.dg/opt/pr108365.C: New test. * g++.dg/warn/pr108365.C: New test. Jakub --- gcc/c/c-typeck.cc.jj 2022-11-13 12:29:08.197504249 +0100 +++ gcc/c/c-typeck.cc 2023-01-12 21:06:53.310875131 +0100 @@ -12431,7 +12431,14 @@ build_binary_op (location_t location, en undefined if the quotient can't be represented in the computation mode. We shorten only if unsigned or if dividing by something we know != -1. */ - shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0)) + shorten = (TYPE_UNSIGNED (type0) + || (TREE_CODE (op0) == NOP_EXPR + && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, + 0))) + && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))) + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, + 0))) + < TYPE_PRECISION (type0))) || (TREE_CODE (op1) == INTEGER_CST && !integer_all_onesp (op1))); common = 1; @@ -12467,7 +12474,12 @@ build_binary_op (location_t location, en on some targets, since the modulo instruction is undefined if the quotient can't be represented in the computation mode. We shorten only if unsigned or if dividing by something we know != -1. */ - shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0)) + shorten = (TYPE_UNSIGNED (type0) + || (TREE_CODE (op0) == NOP_EXPR + && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))) + && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))) + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))) + < TYPE_PRECISION (type0))) || (TREE_CODE (op1) == INTEGER_CST && !integer_all_onesp (op1))); common = 1; --- gcc/cp/typeck.cc.jj 2023-01-11 12:47:56.099672340 +0100 +++ gcc/cp/typeck.cc 2023-01-12 21:04:23.738022528 +0100 @@ -5455,8 +5455,15 @@ cp_build_binary_op (const op_location_t point, so we have to dig out the original type to find out if it was unsigned. */ tree stripped_op1 = tree_strip_any_location_wrapper (op1); - shorten = ((TREE_CODE (op0) == NOP_EXPR - && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) + shorten = (TYPE_UNSIGNED (type0) + || (TREE_CODE (op0) == NOP_EXPR + && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, + 0))) + && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, + 0))) + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, + 0))) + < TYPE_PRECISION (type0))) || (TREE_CODE (stripped_op1) == INTEGER_CST && ! integer_all_onesp (stripped_op1))); } @@ -5491,8 +5498,12 @@ cp_build_binary_op (const op_location_t quotient can't be represented in the computation mode. We shorten only if unsigned or if dividing by something we know != -1. */ tree stripped_op1 = tree_strip_any_location_wrapper (op1); - shorten = ((TREE_CODE (op0) == NOP_EXPR - && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) + shorten = (TYPE_UNSIGNED (type0) + || (TREE_CODE (op0) == NOP_EXPR + && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))) + && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))) + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))) + < TYPE_PRECISION (type0))) || (TREE_CODE (stripped_op1) == INTEGER_CST && ! integer_all_onesp (stripped_op1))); common = 1; --- gcc/testsuite/c-c++-common/pr108365.c.jj 2023-01-12 21:27:05.825467236 +0100 +++ gcc/testsuite/c-c++-common/pr108365.c 2023-01-12 21:26:44.095779209 +0100 @@ -0,0 +1,16 @@ +/* PR c++/108365 */ +/* { dg-do compile { target { { ilp32 || lp64 } || llp64 } } } */ +/* { dg-options "-O2 -fdump-tree-gimple" } */ +/* { dg-final { scan-tree-dump-not " \\\((int|unsigned short int|long long int|unsigned int)\\\) " "gimple" } } */ + +unsigned short +foo (unsigned short x, unsigned short y) +{ + return (unsigned) x / y; +} + +unsigned int +bar (unsigned int x, unsigned int y) +{ + return (long long) x / y; +} --- gcc/testsuite/g++.dg/opt/pr108365.C.jj 2023-01-12 21:04:23.738022528 +0100 +++ gcc/testsuite/g++.dg/opt/pr108365.C 2023-01-12 21:04:23.738022528 +0100 @@ -0,0 +1,13 @@ +// PR c++/108365 +// { dg-do run } + +char b = 1; + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_SHORT__ == 2 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + while ((short) ((long long) (unsigned long long) (-__INT_MAX__ - 1) / (long long) (b ? -1 : 0))) + ; +#endif +} --- gcc/testsuite/g++.dg/warn/pr108365.C.jj 2023-01-12 21:04:23.738022528 +0100 +++ gcc/testsuite/g++.dg/warn/pr108365.C 2023-01-12 21:04:23.738022528 +0100 @@ -0,0 +1,5 @@ +// PR c++/108365 +// { dg-do compile { target { { { ilp32 || lp64 } || llp64 } && c++11 } } } + +constexpr char b = 1; +long t = (short) ((long long) (unsigned long long) (-__INT_MAX__ - 1) / (long long) (b ? -1 : 0)); // { dg-bogus "integer overflow in expression of type" }