/* { dg-do run } */ /* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-details -mzarch -march=z13" } */ #include #include #include #include template __attribute__((noinline,noclone)) T* rawmemchr (T *s) { while (*s != pattern) ++s; return s; } template void doit() { T *buf = new T[4096 * 2]; assert (buf != NULL); memset (buf, 0xa, 4096 * 2); // ensure q is 4096-byte aligned T *q = buf + (4096 - ((uintptr_t)buf & 4095)); T *p; // unaligned + block boundary + 1st load p = (T *) ((uintptr_t)q - 8); p[2] = pattern; assert ((rawmemchr (&p[0]) == &p[2])); p[2] = (T) 0xaaaaaaaa; // unaligned + block boundary + 2nd load p = (T *) ((uintptr_t)q - 8); p[6] = pattern; assert ((rawmemchr (&p[0]) == &p[6])); p[6] = (T) 0xaaaaaaaa; // unaligned + 1st load q[5] = pattern; assert ((rawmemchr(&q[2]) == &q[5])); q[5] = (T) 0xaaaaaaaa; // unaligned + 2nd load q[14] = pattern; assert ((rawmemchr(&q[2]) == &q[14])); q[14] = (T) 0xaaaaaaaa; // unaligned + 3rd load q[19] = pattern; assert ((rawmemchr(&q[2]) == &q[19])); q[19] = (T) 0xaaaaaaaa; // unaligned + 4th load q[25] = pattern; assert ((rawmemchr(&q[2]) == &q[25])); q[25] = (T) 0xaaaaaaaa; // aligned + 1st load q[5] = pattern; assert ((rawmemchr(&q[0]) == &q[5])); q[5] = (T) 0xaaaaaaaa; // aligned + 2nd load q[14] = pattern; assert ((rawmemchr(&q[0]) == &q[14])); q[14] = (T) 0xaaaaaaaa; // aligned + 3rd load q[19] = pattern; assert ((rawmemchr(&q[0]) == &q[19])); q[19] = (T) 0xaaaaaaaa; // aligned + 4th load q[25] = pattern; assert ((rawmemchr(&q[0]) == &q[25])); q[25] = (T) 0xaaaaaaaa; delete buf; } int main(void) { doit (); doit (); doit (); doit (); doit (); doit (); return 0; } /* { dg-final { scan-tree-dump-times "generated rawmemchrqi" 2 "ldist" } } */ /* { dg-final { scan-tree-dump-times "generated rawmemchrhi" 2 "ldist" } } */ /* { dg-final { scan-tree-dump-times "generated rawmemchrsi" 2 "ldist" } } */