From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id A7F863858C52; Fri, 12 Aug 2022 13:47:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A7F863858C52 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug rtl-optimization/106590] [12/13 Regression] x86-64 miscompilation starting with r12-8233-g1ceddd7497e15d w/ mtune=skylake Date: Fri, 12 Aug 2022 13:47:37 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: rtl-optimization X-Bugzilla-Version: 12.1.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: 12.2 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 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: Fri, 12 Aug 2022 13:47:37 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D106590 --- Comment #6 from Jakub Jelinek --- Cleaned up testcase: /* { dg-additional-options "-mtune=3Dskylake" { target { i?86-*-* x86_64-*-= * } } } */ typedef struct A { short a; } A; typedef A *B; typedef struct C { int c, d; } C; typedef C *D; B foo (void) { static A r =3D { .a =3D 1 }; return &r; } D bar (void) { static C r =3D { .c =3D 1, .d =3D 23 }; return &r; } static inline int __attribute__((always_inline)) baz (short a) { int e =3D 1, f; short g; D h; switch (a) { case 1: f =3D 23; g =3D 1; break; case 2: f =3D 20; g =3D 2; break; } h =3D bar (); if (h->d !=3D f || h->c !=3D g) __builtin_abort (); return e; } int qux (void) { B i =3D foo (); int e =3D 1; switch (i->a) { case 1: case 2: e =3D baz (i->a); break; case 3: e =3D 0; break; } return e; } int main () { qux (); return 0; } I think this is a latent bug in noce_convert_multiple_sets_1. For cond (eq (reg/v:HI 82 [ g ]) (const_int 1 [0x1])) and cc_cmp (eq (reg:CCZ 17 flags) (const_int 0 [0])) when we try_emit_cmove_seq for (insn 3 35 4 7 (set (reg/v:HI 82 [ g ]) (const_int 2 [0x2])) "pr106590.c":37:9 84 {*movhi_internal} (nil)) insn, we get seq1 (insn 65 0 66 (set (reg:CCZ 17 flags) (compare:CCZ (reg/v:HI 82 [ g ]) (const_int 1 [0x1]))) -1 (nil)) (insn 66 65 67 (set (reg:QI 96) (ne:QI (reg:CCZ 17 flags) (const_int 0 [0]))) -1 (nil)) (insn 67 66 68 (set (reg:HI 95) (zero_extend:HI (reg:QI 96))) -1 (nil)) (insn 68 67 0 (parallel [ (set (reg:HI 95) (plus:HI (reg:HI 95) (const_int 1 [0x1]))) (clobber (reg:CC 17 flags)) ]) -1 (nil)) and seq2 (insn 69 0 70 (set (reg:HI 97) (const_int 2 [0x2])) -1 (nil)) (insn 70 69 0 (set (reg:HI 95) (if_then_else:HI (eq (reg:CCZ 17 flags) (const_int 0 [0])) (reg/v:HI 82 [ g ]) (reg:HI 97))) -1 (nil)) and later for (insn 4 3 36 7 (set (reg/v:SI 84 [ f ]) (const_int 20 [0x14])) "pr106590.c":36:9 83 {*movsi_internal} (nil)) we get seq1 (insn 72 0 71 (set (reg:SI 98) (const_int 20 [0x14])) -1 (nil)) (insn 71 72 73 (set (reg:CCZ 17 flags) (compare:CCZ (reg/v:HI 82 [ g ]) (const_int 1 [0x1]))) -1 (nil)) (insn 73 71 0 (set (reg/v:SI 84 [ f ]) (if_then_else:SI (eq (reg:CCZ 17 flags) (const_int 0 [0])) (reg/v:SI 84 [ f ]) (reg:SI 98))) -1 (nil)) and seq2 (insn 74 0 75 (set (reg:SI 99) (const_int 20 [0x14])) -1 (nil)) (insn 75 74 0 (set (reg/v:SI 84 [ f ]) (if_then_else:SI (eq (reg:CCZ 17 flags) (const_int 0 [0])) (reg/v:SI 84 [ f ]) (reg:SI 99))) -1 (nil)) In the former case, cost1 =3D=3D cost2, in the latter case cost1 > cost2. So, we for the first insn choose seq1 and for the second seq2. That is wrong, because the first seq1 clobbers the (reg 17 flags) register which is used in cc_cmp/rev_cc_cmp. So, if we pick that seq1, we may not u= se any seq2 afterwards for the latter instructions, need to always select seq1 since then.=