| /* { dg-do run } */ |
| /* { dg-options "-O2 -fdump-tree-strlen" } */ |
| |
| #include "strlenopt.h" |
| |
| __attribute__((noinline, noclone)) char * |
| fn1 (int x, int y, int z) |
| { |
| static char buf[40]; |
| const char *p; |
| switch (x) |
| { |
| case 0: |
| p = "abcd"; |
| /* Prevent cswitch optimization. */ |
| asm volatile ("" : : : "memory"); |
| break; |
| case 1: |
| p = "efgh"; |
| break; |
| case 2: |
| p = "ijkl"; |
| break; |
| default: |
| p = "mnop"; |
| break; |
| } |
| if (y) |
| { |
| strcpy (buf, p); |
| if (z) |
| strcat (buf, "ABCDEFG"); |
| else |
| strcat (buf, "HIJKLMN"); |
| } |
| else |
| { |
| strcpy (buf, p + 1); |
| if (z) |
| strcat (buf, "OPQ"); |
| else |
| strcat (buf, "RST"); |
| } |
| return buf; |
| } |
| |
| int |
| main () |
| { |
| int i; |
| for (i = 0; i < 5; i++) |
| { |
| const char *p = "abcdefghijklmnop" + (i < 3 ? i : 3) * 4; |
| const char *q; |
| fn1 (i ? 0 : 1, 1, 1); |
| q = fn1 (i, 0, 0); |
| if (memcmp (q, p + 1, 3) != 0 || memcmp (q + 3, "RST", 4) != 0) |
| abort (); |
| fn1 (i ? 0 : 1, 0, 1); |
| q = fn1 (i, 1, 0); |
| if (memcmp (q, p, 4) != 0 || memcmp (q + 4, "HIJKLMN", 8) != 0) |
| abort (); |
| fn1 (i ? 0 : 1, 1, 0); |
| q = fn1 (i, 0, 1); |
| if (memcmp (q, p + 1, 3) != 0 || memcmp (q + 3, "OPQ", 4) != 0) |
| abort (); |
| fn1 (i ? 0 : 1, 0, 0); |
| q = fn1 (i, 1, 1); |
| if (memcmp (q, p, 4) != 0 || memcmp (q + 4, "ABCDEFG", 8) != 0) |
| abort (); |
| } |
| return 0; |
| } |
| |
| /* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ |
| /* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */ |
| /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ |
| /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ |
| /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ |
| /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ |