From patchwork Wed Jul 19 11:06: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: 122549 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp2355231vqt; Wed, 19 Jul 2023 04:07:13 -0700 (PDT) X-Google-Smtp-Source: APBJJlG3MX0ecvEjr5biak1tTA7FOCEy2cyNaRmc6q3S+Y6pNfQNytkLN/TCJuuYODUF7Ll1bwy5 X-Received: by 2002:aa7:c902:0:b0:521:7417:1131 with SMTP id b2-20020aa7c902000000b0052174171131mr2009722edt.15.1689764833367; Wed, 19 Jul 2023 04:07:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689764833; cv=none; d=google.com; s=arc-20160816; b=krgyRaWTYNqE6Mie53alMzx7K9ztyVUHPXDBvuFNuPyxy2C5+JaU1WwLZ/uFtoDSA+ xwc5TbkeXpYT0CCxhL93k855FMa8+SKuNvhNhfqOQncbUOVRESAAYdjIN3EX7/rjPyRm 2UY1AEMKJ6EHAds7iA8Fskb8PUALMoeyw6zaqKjrBItAIctsypt9Hwr4IwAa8T1iWr9w qqgrN7Pq5/2PDETiXZuaUItAD3Tja90eoGvVOlssnHit9GJdL2OuRi3COrjzIBD+gYPj Xv4ZqkHDBZ03onOmpQmIUAKFaKAEeW5Fwej4cqNgmNIHFgNg0jEejg5Rwybott5hlpVg MiXg== 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:mime-version:message-id:subject:cc:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=2n8VB6hvjG+EUFzjOsxYltQkkdpQLiynuIDRxVhsikY=; fh=K+End6SolsxgDaQBCjxkuhWNc4ybCi+b82RYWbnC2Ss=; b=KNsBSt7zV+ZpkQmiY5Q0vGj5FmmbFrVoe5Rqe9cwTQAXjliuJ+xCG7wmi9RpG6rCiy yKAzQi+Chnmd7j+0uugN4S3xD6TJPhAhpsZ+DDNm3x8JRnX7sd21ftdzMPhncyFNc0z9 QpfX9LeBDdsj2jRle5DQRBhzk4CS54XaiYD1WUqeeSazWFqp9+kCT6tffvR1AqeVIGHN SYX+PszaSQwr8glaTb6B+q00bOtASqpS+UukB6ELie5JwHLSke2xGafBAGRtJgdVOPpU txgeHSTw3PZqIdaZYrEax6C6NZeK/iS18n0FlmexsX26USQOhHRzmWlKg4ZSJctDnlB5 PV8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=na+MWRK+; 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 (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id d23-20020a50fb17000000b0051dff4faa21si2827117edq.176.2023.07.19.04.07.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jul 2023 04:07:13 -0700 (PDT) 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=na+MWRK+; 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 149EF385770B for ; Wed, 19 Jul 2023 11:07:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 149EF385770B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1689764832; bh=2n8VB6hvjG+EUFzjOsxYltQkkdpQLiynuIDRxVhsikY=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=na+MWRK+WTs9iKAea7JOEwNPtYNGCOJIpUrLq7J3O3ko8FgoO41zmiFJm5IIMzYCY rwaomeU6hquaRHREII+bGcRJ1582LOlq2HuCkZhYGxuHzkZz4lQvS3SLdlumu4id93 fky4ayLQDyi/LOUJsQg5MEjr/7ssF1qLWzAkW6P4= 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 1441E3858C33 for ; Wed, 19 Jul 2023 11:06:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1441E3858C33 Received: from mimecast-mx02.redhat.com (66.187.233.73 [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-302-50tA73qwM0WyZ2rUjrGLDw-1; Wed, 19 Jul 2023 07:06:27 -0400 X-MC-Unique: 50tA73qwM0WyZ2rUjrGLDw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5485B299E753; Wed, 19 Jul 2023 11:06:27 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.226.176]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0532010E56; Wed, 19 Jul 2023 11:06: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 36JB6O6b2591242 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 19 Jul 2023 13:06:24 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 36JB6N6Q2591241; Wed, 19 Jul 2023 13:06:23 +0200 Date: Wed, 19 Jul 2023 13:06:23 +0200 To: Richard Biener , Richard Sandiford Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] wide-int: Fix up wi::divmod_internal [PR110731] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.7 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_H4, RCVD_IN_MSPIKE_WL, 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: 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: INBOX X-GMAIL-THRID: 1771846850069433795 X-GMAIL-MSGID: 1771846850069433795 Hi! As the following testcase shows, wi::divmod_internal doesn't handle correctly signed division with precision > 64 when the dividend (and likely divisor as well) is the type's minimum and the precision isn't divisible by 64. A few lines above what the patch hunk changes is: /* Make the divisor and dividend positive and remember what we did. */ if (sgn == SIGNED) { if (wi::neg_p (dividend)) { neg_dividend = -dividend; dividend = neg_dividend; dividend_neg = true; } if (wi::neg_p (divisor)) { neg_divisor = -divisor; divisor = neg_divisor; divisor_neg = true; } } i.e. we negate negative dividend or divisor and remember those. But, after we do that, when unpacking those values into b_dividend and b_divisor we need to always treat the wide_ints as UNSIGNED, because divmod_internal_2 performs an unsigned division only. Now, if precision <= 64, we don't reach here at all, earlier code handles it. If dividend or divisor aren't the most negative values, the negation clears their most significant bit, so it doesn't really matter if we unpack SIGNED or UNSIGNED. And if precision is multiple of HOST_BITS_PER_WIDE_INT, there is no difference in behavior, while -0x80000000000000000000000000000000 negates to -0x80000000000000000000000000000000 the unpacking of it as SIGNED or UNSIGNED works the same. In the testcase, we have signed precision 119 and the dividend is val = { 0, 0xffc0000000000000 }, len = 2, precision = 119 both before and after negation. Divisor is val = { 2 }, len = 1, precision = 119 But we really want to divide 0x400000000000000000000000000000 by 2 unsigned and then negate at the end. If it is unsigned precision 119 division 0x400000000000000000000000000000 by 2 dividend is val = { 0, 0xffc0000000000000 }, len = 2, precision = 119 but as we unpack it UNSIGNED, it is unpacked into 0, 0, 0, 0x00400000 The following patch fixes it by always using UNSIGNED unpacking because we've already negated negative values at that point if sgn == SIGNED and so most negative constants should be treated as positive. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk, 13.2 and later for older branches? 2023-07-19 Jakub Jelinek PR tree-optimization/110731 * wide-int.cc (wi::divmod_internal): Always unpack dividend and divisor as UNSIGNED regardless of sgn. * gcc.dg/pr110731.c: New test. Jakub --- gcc/wide-int.cc.jj 2023-06-12 15:47:22.461502821 +0200 +++ gcc/wide-int.cc 2023-07-19 09:52:40.241661869 +0200 @@ -1911,9 +1911,9 @@ wi::divmod_internal (HOST_WIDE_INT *quot } wi_unpack (b_dividend, dividend.get_val (), dividend.get_len (), - dividend_blocks_needed, dividend_prec, sgn); + dividend_blocks_needed, dividend_prec, UNSIGNED); wi_unpack (b_divisor, divisor.get_val (), divisor.get_len (), - divisor_blocks_needed, divisor_prec, sgn); + divisor_blocks_needed, divisor_prec, UNSIGNED); m = dividend_blocks_needed; b_dividend[m] = 0; --- gcc/testsuite/gcc.dg/pr110731.c.jj 2023-07-19 10:03:03.707986705 +0200 +++ gcc/testsuite/gcc.dg/pr110731.c 2023-07-19 10:04:34.857716862 +0200 @@ -0,0 +1,17 @@ +/* PR tree-optimization/110731 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-O2" } */ + +__int128 +foo (void) +{ + struct S { __int128 f : 119; } s = { ((__int128) -18014398509481984) << 64 }; + return s.f / 2; +} + +int +main () +{ + if (foo () != (((__int128) -9007199254740992) << 64)) + __builtin_abort (); +}