--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-march=rv32gc -save-temps -g0 -fno-lto" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc -save-temps -g0 -fno-lto" { target { rv64 } } } */
+/* { dg-additional-options "-DRUN_FRACTION=11" { target simulator } } */
+/* { dg-timeout-factor 2 } */
+
+#include "../../gcc.dg/memcmp-1.c"
+/* Yeah, this memcmp test exercises plenty of memcpy, more than any of the
+ memcpy tests. */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
+
+#include <stddef.h>
+#define aligned32 __attribute__ ((aligned (32)))
+
+const char myconst15[] aligned32 = { 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7 };
+const char myconst23[] aligned32 = { 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7 };
+const char myconst31[] aligned32 = { 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7 };
+
+/* No expansion (unknown alignment) */
+#define MY_MEM_CPY_N(N) \
+void my_mem_cpy_##N (char *b1, const char *b2) \
+{ \
+ __builtin_memcpy (b1, b2, N); \
+}
+
+/* No expansion (unknown alignment) */
+#define MY_MEM_CPY_CONST_N(N) \
+void my_mem_cpy_const_##N (char *b1) \
+{ \
+ __builtin_memcpy (b1, myconst##N, sizeof(myconst##N));\
+}
+
+MY_MEM_CPY_N(15)
+MY_MEM_CPY_CONST_N(15)
+
+MY_MEM_CPY_N(23)
+MY_MEM_CPY_CONST_N(23)
+
+MY_MEM_CPY_N(31)
+MY_MEM_CPY_CONST_N(31)
+
+/* { dg-final { scan-assembler-times "\t(call|tail)\tmemcpy" 6 } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
+
+#include <stddef.h>
+#define aligned32 __attribute__ ((aligned (32)))
+
+const char myconst15[] aligned32 = { 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7 };
+const char myconst23[] aligned32 = { 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7 };
+const char myconst31[] aligned32 = { 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1, 2, 3, 4, 5, 6, 7 };
+
+#define MY_MEM_CPY_ALIGNED_N(N) \
+void my_mem_cpy_aligned_##N(char *b1, const char *b2) \
+{ \
+ b1 = __builtin_assume_aligned (b1, 4096); \
+ b2 = __builtin_assume_aligned (b2, 4096); \
+ __builtin_memcpy (b1, b2, N); \
+}
+
+#define MY_MEM_CPY_ALIGNED_CONST_N(N) \
+void my_mem_cpy_aligned_const_##N(char *b1) \
+{ \
+ b1 = __builtin_assume_aligned (b1, 4096); \
+ __builtin_memcpy (b1, myconst##N, sizeof(myconst##N)); \
+}
+
+MY_MEM_CPY_ALIGNED_N(15)
+MY_MEM_CPY_ALIGNED_CONST_N(15)
+
+MY_MEM_CPY_ALIGNED_N(23)
+MY_MEM_CPY_ALIGNED_CONST_N(23)
+
+MY_MEM_CPY_ALIGNED_N(31)
+MY_MEM_CPY_ALIGNED_CONST_N(31)
+
+/* { dg-final { scan-assembler-not "\t(call|tail)\tmemcpy" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc" { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" "-Oz" } } */
+
+#include <stddef.h>
+
+/* No expansion (unknown size) */
+void my_mem_cpy_n(char *b1, const char *b2, size_t n)
+{
+ __builtin_memcpy (b1, b2, n);
+}
+
+/* No expansion (unknown size) */
+void my_mem_cpy_aligned(char *b1, const char *b2, size_t n)
+{
+ b1 = __builtin_assume_aligned (b1, 4096);
+ b2 = __builtin_assume_aligned (b2, 4096);
+ __builtin_memcpy (b1, b2, n);
+}
+
+/* { dg-final { scan-assembler-times "\t(call|tail)\tmemcpy" 2 } } */