GCC manual says:
'-minline-stringops-dynamically'
For string operations of unknown size, use run-time checks with
inline code for small blocks and a library call for large blocks.
we get
Breakpoint 5, decide_alg (count=0, expected_size=-1, min_size=0,
max_size=2147483647, memset=false, zero_memset=false,
dynamic_check=0x7fffffffc924, noalign=0x7fffffffc923)
at /export/gnu/import/git/gcc/gcc/config/i386/i386.c:24510
24510 if (TARGET_INLINE_STRINGOPS_DYNAMICALLY)
(gdb) p alg
$1 = libcall
(gdb)
libcall is a valid choice here for -minline-stringops-dynamically. This
patch avoids assert "alg != libcall" for
TARGET_INLINE_STRINGOPS_DYNAMICALLY. OK for trunk and 4.9 branch?
Thanks.
H.J.
---
gcc/
2014-12-05 H.J. Lu <[email protected]>
PR target/64200
* config/i386/i386.c (decide_alg): Don't assert "alg != libcall"
for TARGET_INLINE_STRINGOPS_DYNAMICALLY.
gcc/testsuite/
2014-12-05 H.J. Lu <[email protected]>
PR target/64200
* gcc.target/i386/memcpy-strategy-4.c: New test.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4f1a18b..aaf0b38 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -24507,9 +24507,10 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT
expected_size,
alg = decide_alg (count, max / 2, min_size, max_size, memset,
zero_memset, dynamic_check, noalign);
gcc_assert (*dynamic_check == -1);
- gcc_assert (alg != libcall);
if (TARGET_INLINE_STRINGOPS_DYNAMICALLY)
*dynamic_check = max;
+ else
+ gcc_assert (alg != libcall);
return alg;
}
return (alg_usable_p (algs->unknown_size, memset)
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-4.c
b/gcc/testsuite/gcc.target/i386/memcpy-strategy-4.c
new file mode 100644
index 0000000..5c51248
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-4.c
@@ -0,0 +1,21 @@
+/* PR target/64200 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=atom -mmemcpy-strategy=libcall:-1:align
-minline-stringops-dynamically" } */
+
+#include <stdarg.h>
+
+extern void bar(char *x);
+
+void foo (int size, ...)
+{
+ struct
+ {
+ char x[size];
+ } d;
+
+ va_list ap;
+ va_start(ap, size);
+ d = va_arg(ap, typeof (d));
+ va_end(ap);
+ bar(d.x);
+}