From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id ED5933890423; Tue, 11 Jan 2022 08:15:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ED5933890423 From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/103964] [9/10/11/12 Regression] OVS miscompilation since r0-92313-g5006671f1aaa63cd Date: Tue, 11 Jan 2022 08:15: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: rguenth at gcc dot gnu.org 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: 9.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 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: Tue, 11 Jan 2022 08:15:03 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D103964 --- Comment #3 from Richard Biener --- Yes, the oracle assumes that for MEM[(struct ovs_list *)pos_32 + 64B] pos_32 needs to still point to some valid object (even if it's not of type ovs_lis= t) and a pointer to 'start' cannot be constructed from this without invoking UB (and the pointer offsetting rules are not part of TBAA). The MEMs appear in forwprop: : _15 =3D &member_59->elem; _16 =3D &pos_32->elem; - _48 =3D _16->prev; - _15->prev =3D _48; - _15->next =3D _16; + _48 =3D MEM[(struct ovs_list *)pos_32 + 64B].prev; + MEM[(struct ovs_list *)member_59 + 64B].prev =3D _48; + MEM[(struct ovs_list *)member_59 + 64B].next =3D _16; but there it's already pointer arithmetic. In .original we have pos =3D 0B;, pos =3D (struct member *) ((long unsigned int) start.next + 18446744073709551552);; goto ; :; if (member->order > pos->order) { goto ; } pos =3D (struct member *) ((long unsigned int) pos->elem.next + 18446744073709551552); :; if (&pos->elem !=3D &start) goto ; else goto ; :; ovs_list_insert (&pos->elem, &member->elem); where I think passing &pos->elem and &member->elem to ovs_list_insert is already wrong since 'pos' doesn't point to a valid object if the ultimate written destination is 'start'. Doing the 'pos' initialization with uintptr_t isn't enough - you need to do this all the way up to the &pos->elem computation as you say: // TESTED: This works: //ovs_list_insert((void *)((uintptr_t)pos + __builtin_offsetof(stru= ct member,elem)), &member->elem); so yes, it's UB. And UB that's not sanctioned with -fno-strict-aliasing.=