1 /* PR middle-end/78257 - missing memcmp optimization with constant arrays
2    { dg-do compile }
3    { dg-options "-O -Wall -fdump-tree-optimized" } */
4 
5 #define assert(e) ((e) ? (void)0 : __builtin_abort ())
6 
7 typedef __INT32_TYPE__ int32_t;
8 
9 extern int memcmp (const void*, const void*, __SIZE_TYPE__);
10 
11 const int32_t i_0 = 0;
12 const int32_t j_0 = 0;
13 
eq_i0_j0(void)14 void eq_i0_j0 (void)
15 {
16   const char *pi = (char*)&i_0, *pj = (char*)&j_0;
17   int n = 0;
18 
19   n += 0 == memcmp (pi,     pj,     sizeof (int32_t));
20   n += 0 == memcmp (pi + 1, pj + 1, sizeof (int32_t) - 1);
21   n += 0 == memcmp (pi + 2, pj + 2, sizeof (int32_t) - 2);
22   n += 0 == memcmp (pi + 3, pj + 3, sizeof (int32_t) - 3);
23   n += 0 == memcmp (pi + 4, pj + 4, sizeof (int32_t) - 4);
24 
25   assert (n == 5);
26 }
27 
28 
29 const int32_t i1234 = 1234;
30 const int32_t j1234 = 1234;
31 
eq_i1234_j1245(void)32 void eq_i1234_j1245 (void)
33 {
34   const char *pi = (char*)&i1234, *pj = (char*)&j1234;
35   int n = 0;
36 
37   n += 0 == memcmp (pi,     pj,     sizeof (int32_t));
38   n += 0 == memcmp (pi + 1, pj + 1, sizeof (int32_t) - 1);
39   n += 0 == memcmp (pi + 2, pj + 2, sizeof (int32_t) - 2);
40   n += 0 == memcmp (pi + 3, pj + 3, sizeof (int32_t) - 3);
41   n += 0 == memcmp (pi + 4, pj + 4, sizeof (int32_t) - 4);
42 
43   assert (n == 5);
44 }
45 
46 
47 const int32_t a1[2] = { 1234 };
48 const int32_t b1[2] = { 1234 };
49 
eq_a1_b1(void)50 void eq_a1_b1 (void)
51 {
52   const char *pi = (char*)&a1, *pj = (char*)&b1;
53   int n = 0, nb = sizeof a1;
54 
55   n += 0 == memcmp (pi,     pj,     nb);
56   n += 0 == memcmp (pi + 1, pj + 1, nb - 1);
57   n += 0 == memcmp (pi + 2, pj + 2, nb - 2);
58   n += 0 == memcmp (pi + 3, pj + 3, nb - 3);
59   n += 0 == memcmp (pi + 4, pj + 4, nb - 4);
60   n += 0 == memcmp (pi + 5, pj + 5, nb - 5);
61   n += 0 == memcmp (pi + 6, pj + 6, nb - 6);
62   n += 0 == memcmp (pi + 7, pj + 7, nb - 7);
63   n += 0 == memcmp (pi + 8, pj + 8, nb - 8);
64 
65   assert (n == 9);
66 }
67 
68 const int32_t a2[2] = { 1234 };
69 const int32_t b2[2] = { 1234, 0 };
70 
eq_a2_b2(void)71 void eq_a2_b2 (void)
72 {
73   const char *pi = (char*)&a2, *pj = (char*)&b2;
74   int n = 0, nb = sizeof a2;
75 
76   n += 0 == memcmp (pi,     pj,     nb);
77   n += 0 == memcmp (pi + 1, pj + 1, nb - 1);
78   n += 0 == memcmp (pi + 2, pj + 2, nb - 2);
79   n += 0 == memcmp (pi + 3, pj + 3, nb - 3);
80   n += 0 == memcmp (pi + 4, pj + 4, nb - 4);
81   n += 0 == memcmp (pi + 5, pj + 5, nb - 5);
82   n += 0 == memcmp (pi + 6, pj + 6, nb - 6);
83   n += 0 == memcmp (pi + 7, pj + 7, nb - 7);
84   n += 0 == memcmp (pi + 8, pj + 8, nb - 8);
85 
86   assert (n == 9);
87 }
88 
89 
90 const int32_t a5[5] = { [3] = 1234, [1] = 0 };
91 const int32_t b5[5] = { 0, 0, 0, 1234 };
92 
eq_a5_b5(void)93 void eq_a5_b5 (void)
94 {
95   int n = 0, b = sizeof a5;
96   const char *pi = (char*)a5, *pj = (char*)b5;
97 
98   n += 0 == memcmp (pi, pj, b);
99   n += 0 == memcmp (pi + 1, pj + 1, b - 1);
100   n += 0 == memcmp (pi + 2, pj + 2, b - 2);
101   n += 0 == memcmp (pi + 3, pj + 3, b - 3);
102 
103   n += 0 == memcmp (pi + 4, pj + 4, b - 4);
104   n += 0 == memcmp (pi + 5, pj + 5, b - 5);
105   n += 0 == memcmp (pi + 6, pj + 6, b - 6);
106   n += 0 == memcmp (pi + 7, pj + 7, b - 7);
107 
108   n += 0 == memcmp (pi + 8, pj + 8, b - 8);
109   n += 0 == memcmp (pi + 9, pj + 9, b - 9);
110   n += 0 == memcmp (pi + 10, pj + 10, b - 10);
111   n += 0 == memcmp (pi + 11, pj + 11, b - 11);
112 
113   n += 0 == memcmp (pi + 12, pj + 12, b - 12);
114   n += 0 == memcmp (pi + 13, pj + 13, b - 13);
115   n += 0 == memcmp (pi + 14, pj + 14, b - 14);
116   n += 0 == memcmp (pi + 15, pj + 15, b - 15);
117 
118   n += 0 == memcmp (pi + 16, pj + 16, b - 16);
119   n += 0 == memcmp (pi + 17, pj + 17, b - 17);
120   n += 0 == memcmp (pi + 18, pj + 18, b - 18);
121   n += 0 == memcmp (pi + 19, pj + 19, b - 19);
122 
123   assert (n == 20);
124 }
125 
126 
127 const int32_t a19[19] = { [13] = 13, [8] = 8, [4] = 4, [1] = 1  };
128 const int32_t b19[19] = { 0, 1, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 13 };
129 
eq_a19_b19(void)130 void eq_a19_b19 (void)
131 {
132   int n = 0, b = sizeof a19;
133   const char *pi = (char*)a19, *pj = (char*)b19;
134 
135   n += 0 == memcmp (pi,     pj,     b);
136   n += 0 == memcmp (pi + 1, pj + 1, b - 1);
137   n += 0 == memcmp (pi + 2, pj + 2, b - 2);
138   n += 0 == memcmp (pi + 3, pj + 3, b - 3);
139 
140   n += 0 == memcmp (pi + 14, pj + 14, b - 14);
141   n += 0 == memcmp (pi + 15, pj + 15, b - 15);
142   n += 0 == memcmp (pi + 16, pj + 16, b - 16);
143   n += 0 == memcmp (pi + 17, pj + 17, b - 17);
144 
145   n += 0 == memcmp (pi + 28, pj + 28, b - 28);
146   n += 0 == memcmp (pi + 29, pj + 29, b - 29);
147   n += 0 == memcmp (pi + 30, pj + 30, b - 30);
148   n += 0 == memcmp (pi + 31, pj + 31, b - 31);
149 
150   n += 0 == memcmp (pi + 42, pj + 42, b - 42);
151   n += 0 == memcmp (pi + 43, pj + 43, b - 43);
152   n += 0 == memcmp (pi + 44, pj + 44, b - 44);
153   n += 0 == memcmp (pi + 45, pj + 45, b - 45);
154 
155   n += 0 == memcmp (pi + 56, pj + 56, b - 56);
156   n += 0 == memcmp (pi + 57, pj + 57, b - 57);
157   n += 0 == memcmp (pi + 58, pj + 58, b - 58);
158   n += 0 == memcmp (pi + 59, pj + 59, b - 59);
159 
160   assert (n == 20);
161 }
162 
163 
164 const int32_t A20[20] = { [13] = 14, [8] = 8, [4] = 4, [1] = 1  };
165 const int32_t b20[20] = { 0, 1, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 13 };
166 
gt_A20_b20(void)167 void gt_A20_b20 (void)
168 {
169   int n = memcmp (A20, b20, sizeof A20) > 0;
170   assert (n == 1);
171 }
172 
173 const int32_t a21[21] = { [13] = 12, [8] = 8, [4] = 4, [1] = 1  };
174 const int32_t B21[21] = { 0, 1, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 13 };
175 
lt_a21_B21(void)176 void lt_a21_B21 (void)
177 {
178   int n = memcmp (a21, B21, sizeof a21) < 0;
179   assert (n == 1);
180 }
181 
182 
183 /* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
184