1 /* PR tree-optimization/91183 - strlen of a strcpy result with a conditional
3 Test to verify that strlen can determine string lengths from wider stores
4 than narrow characters. This matters because on targets that can handle
5 unaligned stores and where GCC lowers multi-character stores into smaller
6 numbers of wider stores.
8 { dg-options "-O2 -fdump-tree-optimized" }
9 On strictly aligned targets the consecutive char assignments used
10 by the test aren't merged. When they involve multiple trailing nuls
11 these assignments then defeat the strlen optimization as a result of
12 pr83821. When the bug is resolved the directive below can be removed.
13 { dg-require-effective-target non_strict_align } */
15 #include "strlenopt.h"
17 #define CAT(x, y) x ## y
18 #define CONCAT(x, y) CAT (x, y)
19 #define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
21 #define FAIL(name) do { \
22 extern void FAILNAME (name) (void); \
26 /* Macros to emit a call to function named
27 call_failed_to_be_eliminated_on_line_NNN()
28 for each call that's expected to be eliminated. The dg-final
29 scan-tree-dump-time directive at the bottom of the test verifies
30 that no such call appears in output. */
32 if ((expr)) FAIL (not_eliminated); else (void)0
35 #define T(N, ncpy, expect, assign) do { \
38 memcpy (b, a, ncpy); \
39 ELIM (!(expect == strlen (b))); \
44 T (2, 1, 0, (a
[0] = 0));
45 T (2, 2, 0, (a
[0] = 0, a
[1] = 0));
46 T (2, 2, 1, (a
[0] = '1', a
[1] = 0));
47 T (4, 3, 2, (a
[0] = '1', a
[1] = '2', a
[2] = 0));
48 // Not handled due to pr83821:
49 // T (4, 3, 1, (a[0] = '1', a[1] = 0, a[2] = '2'));
50 T (4, 2, 1, (a
[0] = '1', a
[1] = 0, a
[2] = 0, a
[3] = 0));
51 // Not handled due to pr83821:
52 // T (4, 3, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0));
53 T (4, 4, 1, (a
[0] = '1', a
[1] = 0, a
[2] = 0, a
[3] = 0));
54 T (4, 3, 2, (a
[0] = '1', a
[1] = '2', a
[2] = 0, a
[3] = 0));
55 T (4, 4, 2, (a
[0] = '1', a
[1] = '2', a
[2] = 0, a
[3] = 0));
56 T (4, 4, 3, (a
[0] = '1', a
[1] = '2', a
[2] = '3', a
[3] = 0));
57 T (5, 4, 1, (a
[0] = '1', a
[1] = 0, a
[2] = 0, a
[3] = 0));
58 T (5, 4, 2, (a
[0] = '1', a
[1] = '2', a
[2] = 0, a
[3] = 0));
59 T (5, 4, 3, (a
[0] = '1', a
[1] = '2', a
[2] = '3', a
[3] = 0));
61 // T (5, 5, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0));
62 // T (5, 5, 2, (a[0] = '1', a[1] = '2', a[2] = 0, a[3] = 0, a[4] = 0));
63 // T (5, 5, 3, (a[0] = '1', a[1] = '2', a[2] = '3', a[3] = 0, a[4] = 0));
64 T (5, 5, 4, (a
[0] = '1', a
[1] = '2', a
[2] = '3', a
[3] = '4', a
[4] = 0));
68 /* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
69 { dg-final { scan-tree-dump-times "_not_eliminated_" 0 "optimized" } } */