From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id BC17C3857804; Wed, 25 Nov 2020 04:40:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BC17C3857804 From: "peter at int19h dot net" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/97976] Optimization regression in 10.1 for lambda passed as template argument Date: Wed, 25 Nov 2020 04:40:48 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 10.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: peter at int19h dot net 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: resolution bug_status 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, 25 Nov 2020 04:40:48 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D97976 Peter Bisroev changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|INVALID |--- Status|RESOLVED |UNCONFIRMED --- Comment #3 from Peter Bisroev --- Hi Andrew, I was thinking about this a bit more and decided to try the loop in reverse= in a more simplified test case. I know this test case demonstrates a corner ca= se that no one will probably implement. However I still think it merits some further investigation just in case this affects some other parts of the optimizer. You can see this code below: //////////////////// int containsBackwards(const uint8_t* p, uint8_t target) { for (; p; --p) { if (*p =3D=3D target) { return 1; } } return 0; } const uint8_t* findBackwards(const uint8_t* p, uint8_t target) { for (; p; --p) { if (*p =3D=3D target) { break; } } return p; } //////////////////// Function containsBackwards(), while searching backwards, should return 1 if target byte is found and 0 if it was not and p points to address 0. Function findBackwards() is similar but returns the address of the first byte that matched the target or pointer to address 0 if a match was not found. Unless= I am mistaken, the sample code above is not hitting any undefined behavior su= ch as dereferencing a NULL pointer and there is a well defined loop terminating condition. This is the code that is generated with gcc trunk and gcc 9.1: //////////////////// containsBackwards(unsigned char const*, unsigned char): xor eax, eax test rdi, rdi setne al ret findBackwards(unsigned char const*, unsigned char): test rdi, rdi jne .L5 jmp .L6 .L8: sub rdi, 1 .L5: cmp BYTE PTR [rdi], sil jne .L8 mov rax, rdi ret .L6: xor eax, eax ret //////////////////// I would have expected both functions to be compiled to nearly the same code, but the looping is missing in containsBackwards() function. And unless I am mistaken gcc 8.3 generates the output that we would expect to see here. You can see this example in Compiler Explorer here: https://godbolt.org/z/hWE4xs What is also interesting, if we replace uint8_t by uint32_t in containsBackwards() function it will work with gcc 9.3 but with gcc 10.1 it will behave in exactly the same way as above returning the result based on = the validity of the p pointer. Additionally, thinking about my first test case. I know it was technically = in the undefined territory, but just for my personal understanding, is the compiler allowed to assume that pi can never become null like you have suggested? In theory it can overflow and become 0 and the loop will termina= te but unfortunately I am not 100% certain of what the standard's view on this= is. In addition, can the compiler assume that callback(*pi) will never return t= rue? What are your thoughts? Thank you! --peter=