From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 3C520385843E; Thu, 18 Nov 2021 13:28:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3C520385843E From: "aldyh at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/103226] [12 Regression] Recent change to copy-headers causes execution failure for gcc.dg/torture/pr80974 Date: Thu, 18 Nov 2021 13:28:02 +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: 12.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: aldyh at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.0 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: Thu, 18 Nov 2021 13:28:02 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D103226 --- Comment #19 from Aldy Hernandez --- This looks like a target or RTL problem. The .optimized dumps between x86-64 and bfin-elf look the same for: -O2 -fno-tree-vrp -fno-tree-vectorize -fno-thread-jumps -fno-ivopts -fno-tree-pre -fdisable-tree-pre -fdisable-tree-cunrolli -fdisable-tree-cun= roll -fdisable-tree-ivcanon=20 and yet bfin-elf hangs. The problem is this loop: e =3D !f && (n =3D 5); if (e) for (h =3D 0; h < 9; h++) for (i =3D 0; i < 6; i++) if (a) g[h] =3D 4; The register holding &g[h] overflows past the end and writes 4 to f, causin= g an infinite loop. Ultimately this boils down to: cc =3D (a =3D=3D 0) R1 =3D 4 (X); P5 =3D 9 (X); LSETUP (.L5, .L25) LC1 =3D P5; .L5: P2 =3D I0; ;; p2 =3D &g P0 =3D P2 + (P4 << 2); ;; p0 =3D &g[h] P2 =3D 6 (X); ;; i =3D 6 .L7: if cc jump .L6 (bp); ;; <<<< BOO HISS!!!!! <<<<< [P0] =3D R1; ;; *(p0) =3D 4 .L6: P2 +=3D -1; ;; i-- cc =3DP2=3D=3D0; if !cc jump .L7; ;; if (i=3D=3D0) goto .L7 .L25: P4 +=3D 1; The first time we check CC, it's the a=3D=3D0 gate skipping the write to g[= h].=20 Then we overwrite CC with the inner loop latch (i=3D=3D0) and jump back to = L7 where the check against CC is no longer related to "a", and false. So we overrwr= ite [P0] with 4. This write is incorrect, but it's the eventual overflow of P0 into &f that causes a write to 4, and an infinite loop because if(e) will always be false. My RTL knowledge is very old and probably incorrect, but by *.alignments we have: ;; THIS IS A CHECK FOR if(a) (code_label 41 143 29 8 7 (nil) [1 uses]) (jump_insn 31 29 32 8 (set (pc) (if_then_else (ne (reg:BI 34 CC [89]) (const_int 0 [0])) (label_ref:SI 38) (pc))) "j.c":19:10 124 {cbranchbi4} (int_list:REG_BR_PROB 536870916 (nil)) -> 38) ;; HERE WE SET PC BUT DONT CLOBBER CC (code_label 38 37 39 10 6 (nil) [1 uses]) (note 39 38 142 10 [bb 10] NOTE_INSN_BASIC_BLOCK) (jump_insn 142 39 46 10 (parallel [ (set (pc) (if_then_else (ne (reg:SI 10 P2 [98]) (const_int 1 [0x1])) (label_ref:SI 41) (pc))) (set (reg:SI 10 P2 [98]) (plus:SI (reg:SI 10 P2 [98]) (const_int -1 [0xffffffffffffffff]))) (unspec [ (const_int 0 [0]) ] 10) (clobber (scratch:SI)) ]) "j.c":18:19 96 {loop_end} (int_list:REG_BR_PROB 920304124 (nil)) -> 41) And in the *.reorg pass we clobber the CC and end up with the problematic sequence: (code_label 41 143 29 8 7 (nil) [1 uses]) (note 29 41 31 8 [bb 8] NOTE_INSN_BASIC_BLOCK) (jump_insn:TI 31 29 32 8 (set (pc) (if_then_else (ne (reg:BI 34 CC [89]) (const_int 0 [0])) (label_ref:SI 38) (pc))) "j.c":19:10 124 {cbranchbi4} (int_list:REG_BR_PROB 536870916 (nil)) -> 38) (note 32 31 37 9 [bb 9] NOTE_INSN_BASIC_BLOCK) (insn:TI 37 32 38 9 (set (mem:SI (reg/f:SI 8 P0 [92]) [1 g[h_33]+0 S4 A32]) (reg:SI 1 R1 [93])) "j.c":20:14 19 {*movsi_insn} (nil)) (code_label 38 37 39 10 6 (nil) [1 uses]) (note 39 38 218 10 [bb 10] NOTE_INSN_BASIC_BLOCK) (insn 218 39 219 10 (set (reg:SI 10 P2 [98]) (plus:SI (reg:SI 10 P2 [98]) (const_int -1 [0xffffffffffffffff]))) "j.c":18:19 50 {addsi3} (nil)) (insn 219 218 220 10 (set (reg:BI 34 CC) (eq:BI (reg:SI 10 P2 [98]) (const_int 0 [0]))) "j.c":18:19 118 {compare_eq} (nil)) (jump_insn 220 219 46 10 (set (pc) (if_then_else (eq (reg:BI 34 CC) (const_int 0 [0])) (label_ref 41) (pc))) "j.c":18:19 124 {cbranchbi4} (nil) -> 41)=