From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 9B2A8386C5BD; Sat, 16 Dec 2023 00:37:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B2A8386C5BD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1702687053; bh=cNv6kYSaDIXTNqTz/8TB0KI/yc+sY4ktGRMy563vk+k=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mHGVabqmSE4hOZKpMWEQMoMTaizv10PgwbBkUKgbHMHBcXFqxskaEVpR+NwMLGvSg kb1pu6BBtPYT3ujizOFR3VSh1SkANHgOO/oHy7sEX2uKoVlXAuSPx+8MLk60ZLt4nB DvOA5hpNHY7TXQVpgSPNIsGk6ZjZPfh/pdInPWPw= From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/110731] [11/12 Regression] Wrong-code because of wide-int division since r5-424 Date: Sat, 16 Dec 2023 00:37:32 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: jakub at gcc dot gnu.org X-Bugzilla-Target-Milestone: 11.5 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D110731 --- Comment #6 from GCC Commits --- The releases/gcc-12 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:9a93c334865af18ce2fd50cd77a9e90939f3c231 commit r12-10046-g9a93c334865af18ce2fd50cd77a9e90939f3c231 Author: Jakub Jelinek Date: Wed Jul 19 13:48:53 2023 +0200 wide-int: Fix up wi::divmod_internal [PR110731] As the following testcase shows, wi::divmod_internal doesn't handle correctly signed division with precision > 64 when the dividend (and li= kely 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 =3D=3D SIGNED) { if (wi::neg_p (dividend)) { neg_dividend =3D -dividend; dividend =3D neg_dividend; dividend_neg =3D true; } if (wi::neg_p (divisor)) { neg_divisor =3D -divisor; divisor =3D neg_divisor; divisor_neg =3D 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 <=3D 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 =3D { 0, 0xffc0000000000000 }, len =3D 2, precision =3D 119 both before and after negation. Divisor is val =3D { 2 }, len =3D 1, precision =3D 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 =3D { 0, 0xffc0000000000000 }, len =3D 2, precision =3D 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 =3D=3D SIGNED and so most negative constants should be treated as positive. 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. (cherry picked from commit ece799607c841676f4e00c2fea98bbec6976da3f)=