blob: df6b594946aa60d4989762fb5f6a6fa346655473 [file] [log] [blame]
/* { dg-do run } */
/* { dg-options "-O2 -fno-code-hoisting -fdump-tree-strlen -fdump-tree-optimized" } */
#include "strlenopt.h"
__attribute__((noinline, noclone)) char *
fn1 (int r)
{
char *p = r ? "a" : "bc";
/* String length for p varies, therefore strchr below isn't
optimized away. */
return strchr (p, '\0');
}
__attribute__((noinline, noclone)) size_t
fn2 (int r)
{
char *p, q[10];
strcpy (q, "abc");
p = r ? "a" : q;
/* String length is constant for both alternatives, and strlen is
optimized away. */
return strlen (p);
}
__attribute__((noinline, noclone)) size_t
fn3 (char *p, int n)
{
int i;
p = strchr (p, '\0');
/* strcat here can be optimized into memcpy. */
strcat (p, "abcd");
for (i = 0; i < n; i++)
if ((i % 123) == 53)
/* strcat here is optimized into strlen and memcpy. */
strcat (p, "efg");
/* The strlen here can't be optimized away, as in the loop string
length of p might change. */
return strlen (p);
}
char buf[64];
__attribute__((noinline, noclone)) size_t
fn4 (char *x, int n)
{
int i;
size_t l;
char a[64];
char *p = strchr (x, '\0');
/* strcpy here is optimized into memcpy, length computed as p - x + 1. */
strcpy (a, x);
/* strcat here is optimized into memcpy. */
strcat (p, "abcd");
for (i = 0; i < n; i++)
if ((i % 123) == 53)
/* strcat here is optimized into strlen and memcpy. */
strcat (a, "efg");
/* The strlen should be optimized here into 4. */
l = strlen (p);
/* This stays strcpy. */
strcpy (buf, a);
return l;
}
int
main ()
{
volatile int l = 1;
char b[64];
if (memcmp (fn1 (l) - 1, "a", 2) != 0)
abort ();
if (memcmp (fn1 (!l) - 2, "bc", 3) != 0)
abort ();
if (fn2 (l) != 1 || fn2 (!l) != 3)
abort ();
memset (b, '\0', sizeof b);
memset (b, 'a', 3);
if (fn3 (b, 10) != 4 || memcmp (b, "aaaabcd", 8) != 0)
abort ();
if (fn3 (b, 128) != 7 || memcmp (b, "aaaabcdabcdefg", 15) != 0)
abort ();
if (fn3 (b, 256) != 10 || memcmp (b, "aaaabcdabcdefgabcdefgefg", 25) != 0)
abort ();
if (fn4 (b, 10) != 4
|| memcmp (b, "aaaabcdabcdefgabcdefgefgabcd", 29) != 0
|| memcmp (buf, "aaaabcdabcdefgabcdefgefg", 25) != 0)
abort ();
if (fn4 (b, 128) != 4
|| memcmp (b, "aaaabcdabcdefgabcdefgefgabcdabcd", 33) != 0
|| memcmp (buf, "aaaabcdabcdefgabcdefgefgabcdefg", 32) != 0)
abort ();
if (fn4 (b, 256) != 4
|| memcmp (b, "aaaabcdabcdefgabcdefgefgabcdabcdabcd", 37) != 0
|| memcmp (buf, "aaaabcdabcdefgabcdefgefgabcdabcdefgefg", 39) != 0)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "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" } } */
/* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */