(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-54.c
       1  /* PR tree-optimization/86042 - missing strlen optimization after second strcpy
       2     { dg-do compile }
       3     { dg-options "-O2 -Wall -fdump-tree-optimized" } */
       4  
       5  #include "strlenopt.h"
       6  
       7  #define CAT(x, y) x ## y
       8  #define CONCAT(x, y) CAT (x, y)
       9  #define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
      10  
      11  #define FAIL(name) do {				\
      12      extern void FAILNAME (name) (void);		\
      13      FAILNAME (name)();				\
      14    } while (0)
      15  
      16  /* Macro to emit a call to function named
      17     call_in_true_branch_not_eliminated_on_line_NNN()
      18     for each call that's expected to be eliminated.  The dg-final
      19     scan-tree-dump-time directive at the bottom of the test verifies
      20     that no such call appears in output.  */
      21  #define ELIM(expr)							\
      22    if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
      23  
      24  void elim_after_duplicate_strcpy (void)
      25  {
      26  #define T(N, assign, off, str, r0, r1)		\
      27    do {						\
      28      char a[N];					\
      29      strcpy (a, assign);				\
      30      unsigned n0 = strlen (a);			\
      31      strcpy (a + off, str);			\
      32      unsigned n1 = strlen (a);			\
      33      ELIM (n0 == r0 && n1 == r1);		\
      34    } while (0)
      35  
      36    T (2, "",   0, "1",   0, 1);
      37  
      38    T (2, "1",  0, "2",   1, 1);
      39    T (2, "1",  1, "",    1, 1);
      40  
      41    T (3, "\0", 0, "1",   0, 1);
      42    T (3, "1",  1, "2",   1, 2);
      43  
      44    T (3, "12", 0, "23",  2, 2);
      45    T (3, "12", 1, "3",   2, 2);
      46    T (3, "12", 2, "",    2, 2);
      47  
      48    T (4, "1",   1, "23",  1, 3);
      49    T (4, "12",  1, "23",  2, 3);
      50  
      51    T (4, "123", 0, "234", 3, 3);
      52    T (4, "123", 1, "34",  3, 3);
      53    T (4, "123", 2, "4",   3, 3);
      54    T (4, "123", 3, "",    3, 3);
      55  
      56    T (5, "1234", 0, "1",    4, 1);
      57    T (5, "1234", 0, "12",   4, 2);
      58    T (5, "1234", 0, "123",  4, 3);
      59    T (5, "1234", 0, "1234", 4, 4);
      60  
      61    T (5, "123",  1, "234", 3, 4);
      62    T (6, "123",  2, "234", 3, 5);
      63  }
      64  
      65  void elim_after_init_memcpy (void)
      66  {
      67  #undef T
      68  #define T(init, off, str, n, res)		\
      69    do {						\
      70      char a[] = init;				\
      71      memcpy (a + off, str, n);			\
      72      ELIM (strlen (a) == res);			\
      73    } while (0)
      74  
      75    T ("\0",   0, "1",    2, 1);
      76    T ("\0\0", 0, "12",   3, 2);
      77  
      78  #define INIT { '1', '2', '3', '4' }
      79    T (INIT,   0, "",     1, 0);
      80    T (INIT,   0, "1",    2, 1);
      81    T (INIT,   0, "12",   3, 2);
      82    T (INIT,   0, "123",  4, 3);
      83  
      84    T ("1234", 0, "2",    1, 4);
      85    T ("1234", 0, "23",   2, 4);
      86    T ("1234", 0, "234",  3, 4);
      87    T ("1234", 0, "2345", 4, 4);
      88    T ("1234", 0, "2345", 5, 4);
      89  
      90    T ("1234", 1, "2",    1, 4);
      91    T ("1234", 1, "23",   2, 4);
      92    T ("1234", 1, "234",  3, 4);
      93    T ("1234", 1, "234",  4, 4);
      94  
      95    T ("1234", 2, "3",    1, 4);
      96    T ("1234", 2, "3",    2, 3);
      97    T ("1234", 2, "34",   2, 4);
      98    T ("1234", 2, "34",   3, 4);
      99  
     100    T ("12\00034", 0, "1", 1, 2);
     101    T ("12\00034", 0, "1", 2, 1);
     102  
     103    T ("AB\000CD", 0, "ab", 2, 2);
     104    T ("AB\000CD", 0, "ab", 3, 2);
     105    T ("AB\000CD", 0, "ab\000c", 4, 2);
     106  }
     107  
     108  /* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } }
     109     { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */