https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80811
Bug ID: 80811 Summary: out-of-line string members less efficient than they could be Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- Consider the following contrived example and the optimized dump of the two functions. The first overload of cmp is optimized into a no-op, while the second, equivalent overload contains a pair of identical calls to string::compare along with a dutiful comparison of their return values. The difference is likely thanks to the first overload of string::compare being defined inline and GCC being able to determine that it has no side-effects, while the second overload of string::compare being defined out-of-line and GCC apparently not being able to make the same determination. But when the second overload is decorated with attribute pure, GCC is able to optimize both functions the same way. I would expect it to be possible to make GCC recognize this and perform the optimization regardless, but until it does, it seems that there may be an opportunity to help GCC optimize many libstdc++ functions by making use of this attribute (and perhaps others as well). $ cat t.C && g++ -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout t.ii #include <string> void cmp (const std::string &str, const char *s) { int c1 = str.compare (s); int c2 = str.compare (s); if (c1 != c2) __builtin_abort (); } void cmp (const std::string &s1, const std::string &s2) { int c1 = s1.compare (s2; int c2 = s2.compare (s1); if (c1 != c2) __builtin_abort (); } ;; Function void cmp(const string&, const string&) (_Z3cmpRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_, funcdef_no=1005, decl_uid=24124, cgraph_uid=293, symbol_order=295) void cmp(const string&, const string&) (const struct string & s1, const struct string & s2) { <bb 2> [100.00%]: return; } ;; Function void cmp(const string&, const char*) (_Z3cmpRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKc, funcdef_no=1006, decl_uid=24130, cgraph_uid=294, symbol_order=296) void cmp(const string&, const char*) (const struct string & str, const char * s) { int c2; int c1; <bb 2> [100.00%]: c1_5 = std::__cxx11::basic_string<char>::compare (str_2(D), s_3(D)); c2_7 = std::__cxx11::basic_string<char>::compare (str_2(D), s_3(D)); if (c1_5 != c2_7) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [0.04%]: __builtin_abort (); <bb 4> [99.96%]: return; }