From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 428E23858D32; Wed, 19 Jul 2023 07:56:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 428E23858D32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1689753400; bh=/tb6cS/NhsPgSMJ+meo1s6xIH8dE11XQ3zk1VoByCNw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=uZgDnFo6PXuSfGxDnVTsYn+0yjl7jx/i1aNyZOi6E/jBgOtfwhp5lY8N+YKdDc3Fq WDKV90/NniwJ2puBbns3VKJBSIQLrjPwetddWp/uTmLqZFY3lScF2sVyvwg1fOZQfr Qk0agkCSfCXHRjt5X1BfysM9Kag7ArUctbjMkmdI= From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/110731] [11/12/13/14 Regression] Wrong-code because of wide-int division since r5-424 Date: Wed, 19 Jul 2023 07:56:40 +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: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned 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 #2 from Jakub Jelinek --- I think the problem is earlier. If I divide the same values unsigned, while the representation of the wide_= int values is the same, i.e. val =3D {0, -18014398509481984}, len =3D 2, precision =3D 119 for x, when divmod_internal_2 is called, in the signed case it sees x/4wx b_dividend 0x7fffffffc0b0: 0x00000000 0x00000000 0x00000000 0xffc00000 while in the unsigned one x/4wx b_dividend 0x7fffffffc0b0: 0x00000000 0x00000000 0x00000000 0x00400000 and I think the latter is what should be used in both cases, divmod_interna= l_2 performs unsigned division. So, I think the right fix is: --- 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 =3D dividend_blocks_needed; b_dividend[m] =3D 0; because at this point we are after the /* 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; } } hunk. Of course, this makes a difference only if either the dividend or divisor are the smallest negative value of a type.=