From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 563113858C52; Mon, 2 May 2022 13:58:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 563113858C52 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/105329] [12/13 Regression] Bogus restrict warning when assigning 1-char string literal to std::string since r12-3347-g8af8abfbbace49e6 Date: Mon, 02 May 2022 13:58:50 +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: diagnostic, missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW 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 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: Mon, 02 May 2022 13:58:50 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D105329 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #14 from Jakub Jelinek --- Here is an untested patch for the cold part of the function: --- libstdc++-v3/include/bits/basic_string.h.jj 2022-01-21 22:48:42.2202616= 54 +0100 +++ libstdc++-v3/include/bits/basic_string.h 2022-05-02 15:51:42.3819239= 62 +0200 @@ -2504,6 +2504,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c); + __attribute__((__noinline__, __noclone__, __cold__)) void + _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s, + const size_type __len2, const size_type __how_much); + _GLIBCXX20_CONSTEXPR basic_string& _M_replace(size_type __pos, size_type __len1, const _CharT* __s, --- libstdc++-v3/include/bits/basic_string.tcc.jj 2022-01-11 22:31:41.482757256 +0100 +++ libstdc++-v3/include/bits/basic_string.tcc 2022-05-02 15:51:38.6309753= 48 +0200 @@ -471,6 +471,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template + __attribute__((__noinline__, __noclone__, __cold__)) void + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_cold(pointer __p, size_type __len1, const _CharT* __s, + const size_type __len2, const size_type __how_much) + { + // Work in-place. + if (__len2 && __len2 <=3D __len1) + this->_S_move(__p, __s, __len2); + if (__how_much && __len1 !=3D __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2 > __len1) + { + if (__s + __len2 <=3D __p + __len1) + this->_S_move(__p, __s, __len2); + else if (__s >=3D __p + __len1) + { + // Hint to middle end that __p and __s overlap + // (PR 98465). + const size_type __poff =3D (__s - __p) + (__len2 - __len1); + this->_S_copy(__p, __p + __poff, __len2); + } + else + { + const size_type __nleft =3D (__p + __len1) - __s; + this->_S_move(__p, __s, __nleft); + this->_S_copy(__p + __nleft, __p + __len2, __len2 - __nleft); + } + } + } + + template _GLIBCXX20_CONSTEXPR basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: @@ -500,7 +531,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else #endif - if (_M_disjunct(__s)) + if (__builtin_expect(_M_disjunct(__s),true)) { if (__how_much && __len1 !=3D __len2) this->_S_move(__p + __len2, __p + __len1, __how_much); @@ -508,32 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->_S_copy(__p, __s, __len2); } else - { - // Work in-place. - if (__len2 && __len2 <=3D __len1) - this->_S_move(__p, __s, __len2); - if (__how_much && __len1 !=3D __len2) - this->_S_move(__p + __len2, __p + __len1, __how_much); - if (__len2 > __len1) - { - if (__s + __len2 <=3D __p + __len1) - this->_S_move(__p, __s, __len2); - else if (__s >=3D __p + __len1) - { - // Hint to middle end that __p and __s overlap - // (PR 98465). - const size_type __poff =3D (__s - __p) + (__len2 - __= len1); - this->_S_copy(__p, __p + __poff, __len2); - } - else - { - const size_type __nleft =3D (__p + __len1) - __s; - this->_S_move(__p, __s, __nleft); - this->_S_copy(__p + __nleft, __p + __len2, - __len2 - __nleft); - } - } - } + _M_replace_cold(__p, __len1, __s, __len2, __how_much); } else this->_M_mutate(__pos, __len1, __s, __len2); Note, on the #c0 testcase alone it actually results in larger generated code (unless we arrange for it to be exported from libstdc++, for which it is qu= ite late for 12.1 right now), but say on: #include void f (std::string& s) { s =3D "5"; } void g (std::string& s) { s =3D "56"; } void h (std::string& s) { s =3D "6"; } it is already smaller (note, obviously it doesn't need to be in the same TU= ).=