196 lines
4.1 KiB
C
196 lines
4.1 KiB
C
/* PR tree-optimization/91996 - fold non-constant strlen relational expressions
|
|
{ dg-do run }
|
|
{ dg-options "-O2 -Wall -Wno-unused-local-typedefs" } */
|
|
|
|
typedef __SIZE_TYPE__ size_t;
|
|
|
|
#define NOIPA __attribute__ ((noipa))
|
|
|
|
#define CONCAT(a, b) a ## b
|
|
#define CAT(a, b) CONCAT (a, b)
|
|
|
|
/* Used in tests where EXPR is expected to be folded to false. */
|
|
#define ELIM(expr) \
|
|
if (expr) { \
|
|
extern void \
|
|
CAT (CAT (test_on_line_, __LINE__), _not_eliminated)(void); \
|
|
CAT (CAT (test_on_line_, __LINE__), _not_eliminated)(); \
|
|
} typedef void dummy_type
|
|
|
|
|
|
/* Set the alignment for targets that depend on it in order to
|
|
optimize away the ELIM calls. See pr92128. */
|
|
__attribute__ ((aligned(4))) char a[32], b[32];
|
|
|
|
void init (void)
|
|
{
|
|
__builtin_strncpy (a, "abcdefgh", sizeof a);
|
|
__builtin_strncpy (b, "0123456789", sizeof b);
|
|
}
|
|
|
|
NOIPA void fail (const char *func)
|
|
{
|
|
__builtin_printf ("failure in %s\n", func);
|
|
__builtin_abort ();
|
|
}
|
|
|
|
NOIPA void test_global_cpy_4 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 4);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 8) // cannot be eliminated
|
|
fail ("test_global");
|
|
}
|
|
|
|
|
|
NOIPA void test_global_cpy_10 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 10);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 10) // cannot be eliminated
|
|
fail ("test_global_cpy_10");
|
|
}
|
|
|
|
NOIPA void test_global_cpy_11 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 11);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 10) // cannot be eliminated
|
|
fail ("test_global_cpy_11");
|
|
}
|
|
|
|
NOIPA void test_global_cpy_20 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 20);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 10) // cannot be eliminated
|
|
fail ("test_global_cpy_20");
|
|
}
|
|
|
|
NOIPA void test_local_cpy_4 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
/* Set the alignment for targets that depend on it in order to
|
|
optimize away the ELIM calls. See pr92128. */
|
|
__attribute__ ((aligned(4))) char a[10] = "abcdefgh";
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 4);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
ELIM (dlen != 8);
|
|
}
|
|
|
|
NOIPA void test_local_cpy_10 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char a[32] = "abcdefgh";
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 10);
|
|
|
|
/* B can be longer than 9 and A can initially be longer than 10
|
|
so the test below cannot be eliminated. */
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 10)
|
|
fail ("test_local_cpy_10");
|
|
}
|
|
|
|
NOIPA void test_local_cpy_11 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char a[32] = "abcdefgh";
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 11);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 10)
|
|
fail ("test_global_cpy_20");
|
|
}
|
|
|
|
NOIPA void test_local_cpy_20 (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
char a[32] = "abcdefgh";
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 20);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
if (dlen != 10)
|
|
fail ("test_global_cpy_20");
|
|
}
|
|
|
|
NOIPA void test_global_length_eq (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen != 10) return;
|
|
|
|
size_t alen = __builtin_strlen (a);
|
|
if (alen != 8) return;
|
|
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 4);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
ELIM (dlen != 8);
|
|
}
|
|
|
|
|
|
NOIPA void test_global_length_gt (void)
|
|
{
|
|
size_t blen = __builtin_strlen (b);
|
|
if (blen < 9) return;
|
|
|
|
size_t alen = __builtin_strlen (a);
|
|
if (alen < 8) return;
|
|
|
|
char *d = a;
|
|
__builtin_memcpy (d, b, 4);
|
|
|
|
size_t dlen = __builtin_strlen (d);
|
|
ELIM (dlen < 8);
|
|
}
|
|
|
|
#define TEST(name) do { init (); test_ ## name (); } while (0)
|
|
|
|
int main (void)
|
|
{
|
|
TEST (local_cpy_4);
|
|
TEST (local_cpy_10);
|
|
TEST (local_cpy_11);
|
|
TEST (local_cpy_20);
|
|
|
|
TEST (global_cpy_4);
|
|
TEST (global_cpy_10);
|
|
TEST (global_cpy_11);
|
|
TEST (global_cpy_20);
|
|
TEST (global_length_eq);
|
|
TEST (global_length_gt);
|
|
}
|