From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 282213851C31; Wed, 8 Sep 2021 08:24:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 282213851C31 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/89984] Extra register move Date: Wed, 08 Sep 2021 08:24:12 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: 9.0 X-Bugzilla-Keywords: easyhack, missed-optimization, ra X-Bugzilla-Severity: enhancement X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: REOPENED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc bug_status resolution 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 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Sep 2021 08:24:13 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D89984 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org Status|RESOLVED |REOPENED Resolution|FIXED |--- --- Comment #5 from Jakub Jelinek --- This patch is incorrect, it breaks e.g. float bar (float x, float y) { return x * __builtin_copysignf (1.0f, y); } On top of the PR102224 patch, I've tried: --- gcc/config/i386/i386.md.jj 2021-09-08 09:55:40.791551976 +0200 +++ gcc/config/i386/i386.md 2021-09-08 10:15:10.241011077 +0200 @@ -10919,18 +10919,19 @@ (define_expand "xorsign3" }) (define_insn_and_split "@xorsign3_1" - [(set (match_operand:MODEF 0 "register_operand" "=3D&Yv,&Yv,&Yv") + [(set (match_operand:MODEF 0 "register_operand" "=3D&Yv,Yv") (unspec:MODEF - [(match_operand:MODEF 1 "register_operand" "Yv,0,Yv") - (match_operand:MODEF 2 "register_operand" "0,Yv,Yv") - (match_operand: 3 "nonimmediate_operand" "Yvm,Yvm,Yv= m")] - UNSPEC_XORSIGN))] + [(match_operand:MODEF 1 "register_operand" "Yv,Yv") + (match_operand:MODEF 2 "register_operand" "0,Yv") + (match_operand: 3 "nonimmediate_operand" "Yvm,Yvm")] + UNSPEC_XORSIGN)) + (clobber (match_scratch:MODEF 4 "=3DX,Yv"))] "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH" "#" "&& reload_completed" [(const_int 0)] "ix86_split_xorsign (operands); DONE;" - [(set_attr "isa" "*,avx,avx")]) + [(set_attr "isa" "*,avx")]) ;; One complement instructions --- gcc/config/i386/i386-expand.c.jj 2021-09-08 09:55:40.000000000 +0200 +++ gcc/config/i386/i386-expand.c 2021-09-08 10:04:15.470268062 +0200 @@ -2296,23 +2296,25 @@ void ix86_split_xorsign (rtx operands[]) { machine_mode mode, vmode; - rtx dest, op0, op1, mask, x; + rtx dest, op0, op1, mask, x, temp; dest =3D operands[0]; op0 =3D operands[1]; op1 =3D operands[2]; mask =3D operands[3]; + temp =3D operands[4]; mode =3D GET_MODE (dest); vmode =3D GET_MODE (mask); - /* The constraints ensure that for non-AVX dest =3D=3D op1 is - different from op0, and for AVX that at most two of - dest, op0 and op1 are the same register but the third one - is different. */ + if (!reg_overlap_mentioned_p (dest, op0)) + temp =3D dest; + else + gcc_assert (TARGET_AVX); + if (rtx_equal_p (op0, op1)) { - gcc_assert (TARGET_AVX && !rtx_equal_p (op0, dest)); + gcc_assert (TARGET_AVX); if (vmode =3D=3D V4SFmode) vmode =3D V4SImode; else @@ -2323,9 +2325,9 @@ ix86_split_xorsign (rtx operands[]) mask =3D lowpart_subreg (vmode, mask, GET_MODE (mask)); if (MEM_P (mask)) { - rtx msk =3D lowpart_subreg (vmode, dest, mode); - emit_insn (gen_rtx_SET (msk, mask)); - mask =3D msk; + temp =3D lowpart_subreg (vmode, temp, mode); + emit_insn (gen_rtx_SET (temp, mask)); + mask =3D temp; } op0 =3D lowpart_subreg (vmode, op0, mode); x =3D gen_rtx_AND (vmode, gen_rtx_NOT (vmode, mask), op0); @@ -2334,10 +2336,11 @@ ix86_split_xorsign (rtx operands[]) { op1 =3D lowpart_subreg (vmode, op1, mode); x =3D gen_rtx_AND (vmode, op1, mask); - emit_insn (gen_rtx_SET (op1, x)); + temp =3D lowpart_subreg (vmode, temp, mode); + emit_insn (gen_rtx_SET (temp, x)); op0 =3D lowpart_subreg (vmode, op0, mode); - x =3D gen_rtx_XOR (vmode, op1, op0); + x =3D gen_rtx_XOR (vmode, temp, op0); } dest =3D lowpart_subreg (vmode, dest, mode); and also with additional &Yv <- Yv, Yv, Yvm, X alternative with various way= s to disparage it slightly (^s or $s), but never convinced RA that it should use= the alternative with the scratch. --- gcc/config/i386/i386.md.jj 2021-09-08 09:55:40.791551976 +0200 +++ gcc/config/i386/i386.md 2021-09-08 10:20:29.633498636 +0200 @@ -10919,18 +10919,19 @@ }) (define_insn_and_split "@xorsign3_1" - [(set (match_operand:MODEF 0 "register_operand" "=3D&Yv,&Yv,&Yv") + [(set (match_operand:MODEF 0 "register_operand" "=3D&Yv,Yv") (unspec:MODEF - [(match_operand:MODEF 1 "register_operand" "Yv,0,Yv") - (match_operand:MODEF 2 "register_operand" "0,Yv,Yv") - (match_operand: 3 "nonimmediate_operand" "Yvm,Yvm,Yv= m")] - UNSPEC_XORSIGN))] + [(match_operand:MODEF 1 "register_operand" "Yv,Yv") + (match_operand:MODEF 2 "register_operand" "0,Yv") + (match_operand: 3 "nonimmediate_operand" "Yvm,Yvm")] + UNSPEC_XORSIGN)) + (clobber (match_scratch:MODEF 4 "=3DX,&Yv"))] "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH" "#" "&& reload_completed" [(const_int 0)] "ix86_split_xorsign (operands); DONE;" - [(set_attr "isa" "*,avx,avx")]) + [(set_attr "isa" "noavx,avx")]) ;; One complement instructions with the same i386-expand.c changes does, but then it forces a scratch even= for the cases where it is not needed.=