(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-14g.c
       1  /* This test needs runtime that provides stpcpy and mempcpy functions.  */
       2  /* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */
       3  /* { dg-options "-O2 -fdump-tree-strlen" } */
       4  /* Bionic targets don't have mempcpy */
       5  /* { dg-require-effective-target non_bionic } */
       6  
       7  #define USE_GNU
       8  #include "strlenopt.h"
       9  
      10  __attribute__((noinline, noclone)) char *
      11  fn1 (char *p, size_t *l1, size_t *l2)
      12  {
      13    char *a = mempcpy (p, "abcde", 6);
      14    /* This strlen needs to stay.  */
      15    size_t la = strlen (a);
      16    /* This strlen can be optimized into 5.  */
      17    size_t lp = strlen (p);
      18    *l1 = la;
      19    *l2 = lp;
      20    return a;
      21  }
      22  
      23  __attribute__((noinline, noclone)) char *
      24  fn2 (char *p, const char *q, size_t *l1, size_t *l2, size_t *l3)
      25  {
      26    /* This strlen needs to stay.  */
      27    size_t lq = strlen (q);
      28    char *a = mempcpy (p, q, lq + 1);
      29    /* This strlen needs to stay.  */
      30    size_t la = strlen (a);
      31    /* This strlen can be optimized into lq.  */
      32    size_t lp = strlen (p);
      33    *l1 = lq;
      34    *l2 = la;
      35    *l3 = lp;
      36    return a;
      37  }
      38  
      39  __attribute__((noinline, noclone)) char *
      40  fn3 (char *p, size_t *l1, size_t *l2)
      41  {
      42    char *a = stpcpy (p, "abcde");
      43    /* This strlen can be optimized into 0.  */
      44    size_t la = strlen (a);
      45    /* This strlen can be optimized into 5.  */
      46    size_t lp = strlen (p);
      47    *l1 = la;
      48    *l2 = lp;
      49    return a;
      50  }
      51  
      52  __attribute__((noinline, noclone)) char *
      53  fn4 (char *p, const char *q, size_t *l1, size_t *l2, size_t *l3)
      54  {
      55    /* This strlen needs to stay.  */
      56    size_t lq = strlen (q);
      57    char *a = stpcpy (p, q);
      58    /* This strlen can be optimized into 0.  */
      59    size_t la = strlen (a);
      60    /* This strlen can be optimized into lq.  */
      61    size_t lp = strlen (p);
      62    *l1 = lq;
      63    *l2 = la;
      64    *l3 = lp;
      65    return a;
      66  }
      67  
      68  __attribute__((noinline, noclone)) char *
      69  fn5 (char *p, const char *q, size_t *l1, size_t *l2)
      70  {
      71    char *a = stpcpy (p, q);
      72    /* This strlen can be optimized into 0.  */
      73    size_t la = strlen (a);
      74    /* This strlen can be optimized into a - p.  */
      75    size_t lp = strlen (p);
      76    *l1 = la;
      77    *l2 = lp;
      78    return a;
      79  }
      80  
      81  int
      82  main ()
      83  {
      84    char buf[64];
      85    const char *volatile q = "ABCDEFGH";
      86    size_t l1, l2, l3;
      87    memset (buf, '\0', sizeof buf);
      88    memset (buf + 6, 'z', 7);
      89    if (fn1 (buf, &l1, &l2) != buf + 6 || l1 != 7 || l2 != 5
      90        || memcmp (buf, "abcde\0zzzzzzz", 14) != 0)
      91      abort ();
      92    if (fn2 (buf, q, &l1, &l2, &l3) != buf + 9 || l1 != 8 || l2 != 4 || l3 != 8
      93        || memcmp (buf, "ABCDEFGH\0zzzz", 14) != 0)
      94      abort ();
      95    if (fn3 (buf, &l1, &l2) != buf + 5 || l1 != 0 || l2 != 5
      96        || memcmp (buf, "abcde\0GH\0zzzz", 14) != 0)
      97      abort ();
      98    l3 = 0;
      99    memset (buf, 'n', 9);
     100    if (fn4 (buf, q, &l1, &l2, &l3) != buf + 8 || l1 != 8 || l2 != 0 || l3 != 8
     101        || memcmp (buf, "ABCDEFGH\0zzzz", 14) != 0)
     102      abort ();
     103    memset (buf, 'm', 9);
     104    if (fn5 (buf, q, &l1, &l2) != buf + 8 || l1 != 0 || l2 != 8
     105        || memcmp (buf, "ABCDEFGH\0zzzz", 14) != 0)
     106      abort ();
     107    return 0;
     108  }
     109  
     110  /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
     111  /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
     112  /* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */
     113  /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
     114  /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
     115  /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
     116  /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */