summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/i386/pr81502.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.target/i386/pr81502.c')
-rw-r--r--gcc/testsuite/gcc.target/i386/pr81502.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/i386/pr81502.c b/gcc/testsuite/gcc.target/i386/pr81502.c
new file mode 100644
index 00000000000..d28791aacd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81502.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -msse2" } */
+
+#include <emmintrin.h>
+
+#define SIZE (sizeof (void *))
+
+static int foo(unsigned char (*foo)[SIZE])
+{
+ __m128i acc = _mm_set_epi32(0, 0, 0, 0);
+ size_t i = 0;
+ for(; i + sizeof(__m128i) <= SIZE; i += sizeof(__m128i)) {
+ __m128i word;
+ __builtin_memcpy(&word, foo + i, sizeof(__m128i));
+ acc = _mm_add_epi32(word, acc);
+ }
+ if (i != SIZE) {
+ __m128i word = _mm_set_epi32(0, 0, 0, 0);
+ __builtin_memcpy(&word, foo + i, SIZE - i); // (1)
+ acc = _mm_add_epi32(word, acc);
+ }
+ int res;
+ __builtin_memcpy(&res, &acc, sizeof(res));
+ return res;
+}
+
+int bar(void *ptr)
+{
+ unsigned char buf[SIZE];
+ __builtin_memcpy(buf, &ptr, SIZE);
+ return foo((unsigned char(*)[SIZE])buf);
+}
+
+/* { dg-final { scan-assembler-times "mov" 1 } } */