https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83674
Bug ID: 83674 Summary: strcpy folding of small strings defeats strlen optimization Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- Here's another test case showing the detrimental effect of early folding into MEM_REFs that the strlen pass isn't equipped to handle. The first dump that shows the MEM_REF is forwprop1. The interesting aspect of this test case is that whether or not the optimization takes place depends on both the size of the destination and the lengths of the source strings. $ cat z.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout z.c char d[8]; #define A1 "123456" #define A2 "654321" const char a1[] = A1; const char a2[] = A2; void f7 (int i) { __builtin_strcpy (d, i < 0 ? A1 : A2); if (__builtin_strlen (d) != sizeof A1 - 1) // optimized __builtin_abort (); } void g7 (int i) { __builtin_strcpy (d, i < 0 ? a1 : a2); if (__builtin_strlen (d) != sizeof a1 - 1) // optimized __builtin_abort (); } #define B1 "1234567" #define B2 "7654321" const char b1[] = B1; const char b2[] = B2; void f8 (int i) { __builtin_strcpy (d, i < 0 ? B1 : B2); if (__builtin_strlen (d) != sizeof B1 - 1) // not optimized __builtin_abort (); } void g8 (int i) { __builtin_strcpy (d, i < 0 ? B1 : B2); if (__builtin_strlen (d) != sizeof b1 - 1) // not optimized __builtin_abort (); } ;; Function f7 (f7, funcdef_no=0, decl_uid=1955, cgraph_uid=0, symbol_order=3) f7 (int i) { char[7] * iftmp.0_7; <bb 2> [local count: 1073741825]: if (i_3(D) < 0) goto <bb 4>; [36.00%] else goto <bb 3>; [64.00%] <bb 3> [local count: 687194769]: <bb 4> [local count: 1073312329]: # iftmp.0_7 = PHI <"123456"(2), "654321"(3)> __builtin_memcpy (&d, iftmp.0_7, 7); [tail call] return; } ;; Function g7 (g7, funcdef_no=1, decl_uid=1958, cgraph_uid=1, symbol_order=4) g7 (int i) { const char * iftmp.1_7; <bb 2> [local count: 1073741825]: if (i_3(D) < 0) goto <bb 4>; [36.00%] else goto <bb 3>; [64.00%] <bb 3> [local count: 687194769]: <bb 4> [local count: 1073312329]: # iftmp.1_7 = PHI <&a1(2), &a2(3)> __builtin_memcpy (&d, iftmp.1_7, 7); [tail call] return; } ;; Function f8 (f8, funcdef_no=2, decl_uid=1963, cgraph_uid=2, symbol_order=7) f8 (int i) { long unsigned int _1; long unsigned int _4; <bb 2> [local count: 1073741825]: if (i_3(D) < 0) goto <bb 3>; [36.00%] else goto <bb 4>; [64.00%] <bb 3> [local count: 386547056]: <bb 4> [local count: 1073741825]: # _4 = PHI <13847469359445559(2), 15540725856023089(3)> MEM[(char * {ref-all})&d] = _4; _1 = __builtin_strlen (&d); if (_1 != 7) goto <bb 5>; [0.00%] else goto <bb 6>; [99.96%] <bb 5> [count: 0]: __builtin_abort (); <bb 6> [local count: 1073312327]: return; } ;; Function g8 (g8, funcdef_no=5, decl_uid=1966, cgraph_uid=3, symbol_order=8) g8 (int i) { <bb 2> [local count: 1073741826]: f8 (i_2(D)); [tail call] return; }