From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id AEA6B3858D37; Thu, 6 Oct 2022 18:49:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AEA6B3858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1665082152; bh=Px2H+8fbzKw7KaIaMYrCRRGA5wfSNJztjg4HUnQc9eg=; h=From:To:Subject:Date:From; b=DHcmt45PZE81d9hVkiZExciKdozV8e7IBhv+cZKKG4mC7ROtJCVjwx7YLAu6Sr4Nr tGnUU6lfkHZj8jduXiPvkxXjyJ7bfkuC6pefQqXNe/l5LXoOaBcQtHOa0OAg0gOME9 KcIifNEEBLfdv95zO4/kwJv4wM6wHYo/3e6d0ubs= From: "rozne at pabich dot waw.pl" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/107174] New: [ARM] Wrong opcodes *.f64.s32 (signed) in conversion [unsigned ->double] with -O2 Date: Thu, 06 Oct 2022 18:49:12 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: 8.3.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rozne at pabich dot waw.pl X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: 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=3D107174 Bug ID: 107174 Summary: [ARM] Wrong opcodes *.f64.s32 (signed) in conversion [unsigned ->double] with -O2 Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: rozne at pabich dot waw.pl Target Milestone: --- When building for 32-bit ARMhf with optimization -O2 and higher sometimes w= rong conversion opcodes are generated - *.f64.s32 (signed conversion) instead of *.f64.u32 (unsigned). These are very rare cases, and are higly sensitive to code arrangement. The bug seems to be present at least since GCC 8.3. GCC 8.4 and 12 are affected. GCC 7.5 is not affected (and very old 4.4 also). It is not present on x86 architecture, seems to be ARM specific. Example cross-compiled on Ubuntu 18.04.6 (x86_64): arm-linux-gnueabihf-gcc-8 -Wall -Wextra -O2 -static GCC 8.4 version: arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-1ubuntu1~18.04) 8.4.0 Code: #include __attribute__((noinline)) double deltaToDouble(int a, int b) { if (a < b) { unsigned int delta =3D b - a; return -((double)delta); } else { unsigned int delta =3D a - b; return (double)delta; } } int main() { return (deltaToDouble( 2000000000, -1000000000) !=3D 3000000000.0 || deltaToDouble(-1000000000, 2000000000) !=3D -3000000000.0); } Disassembly: : cmp r0, r1 itete lt sublt r0, r1, r0 subge r0, r0, r1 vmovlt s15, r0 vmovge s15, r0 itte lt vcvtlt.f64.s32 d0, s15 vneglt.f64 d0, d0 vcvtge.f64.s32 d0, s15 bx lr It is easy to see that opcodes are for signed int32 conversion (vcvtlt.f64.= s32, vcvtge.f64.s32). Code generated by older GCC 7.5 is same except correct opc= odes for unsigned int32 (vcvtlt.f64.u32, vcvtge.f64.u32) were used.=