This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix stpcpy and mempcpy expansion (PR middle-end/38343)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 1 Dec 2008 20:30:57 +0100
- Subject: [PATCH] Fix stpcpy and mempcpy expansion (PR middle-end/38343)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
build_call_expr folds it and for memcpy (and strcpy) COMPOUND_EXPRs
(and for strcpy also NOP_EXPRs around it) can be returned. Many
other routines in builtins.c handle these, but expand_builtin_stpcpy
and expand_builtin_mempcpy_args do not.
This patch fixes it, as well as folds stpcpy early if the return value
is known to be ignored earlier than during expansion.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2008-12-01 Jakub Jelinek <jakub@redhat.com>
PR middle-end/38343
* builtins.c (expand_builtin_mempcpy_args): Handle COMPOUND_EXPRs
potentially returned from folding memcpy.
(expand_builtin_stpcpy_args): Similarly for folding strcpy.
(fold_builtin_2): Handle BUILT_IN_STPCPY if result is ignored.
* gcc.c-torture/compile/pr38343.c: New test.
--- gcc/builtins.c.jj 2008-12-01 18:09:52.000000000 +0100
+++ gcc/builtins.c 2008-12-01 18:34:24.000000000 +0100
@@ -3406,7 +3406,7 @@ expand_builtin_memcpy (tree exp, rtx tar
stpcpy. */
static rtx
-expand_builtin_mempcpy(tree exp, rtx target, enum machine_mode mode)
+expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
{
if (!validate_arglist (exp,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
@@ -3433,15 +3433,18 @@ expand_builtin_mempcpy_args (tree dest,
rtx target, enum machine_mode mode, int endp)
{
/* If return value is ignored, transform mempcpy into memcpy. */
- if (target == const0_rtx)
+ if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
{
tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ tree result = build_call_expr (fn, 3, dest, src, len);
- if (!fn)
- return NULL_RTX;
-
- return expand_expr (build_call_expr (fn, 3, dest, src, len),
- target, mode, EXPAND_NORMAL);
+ while (TREE_CODE (result) == COMPOUND_EXPR)
+ {
+ expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
+ EXPAND_NORMAL);
+ result = TREE_OPERAND (result, 1);
+ }
+ return expand_expr (result, target, mode, EXPAND_NORMAL);
}
else
{
@@ -3707,14 +3710,19 @@ expand_builtin_stpcpy (tree exp, rtx tar
src = CALL_EXPR_ARG (exp, 1);
/* If return value is ignored, transform stpcpy into strcpy. */
- if (target == const0_rtx)
+ if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
{
tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
- if (!fn)
- return NULL_RTX;
+ tree result = build_call_expr (fn, 2, dst, src);
- return expand_expr (build_call_expr (fn, 2, dst, src),
- target, mode, EXPAND_NORMAL);
+ STRIP_NOPS (result);
+ while (TREE_CODE (result) == COMPOUND_EXPR)
+ {
+ expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
+ EXPAND_NORMAL);
+ result = TREE_OPERAND (result, 1);
+ }
+ return expand_expr (result, target, mode, EXPAND_NORMAL);
}
else
{
@@ -10463,6 +10471,17 @@ fold_builtin_2 (tree fndecl, tree arg0,
case BUILT_IN_STRCPY:
return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
+ case BUILT_IN_STPCPY:
+ if (ignore)
+ {
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+ if (!fn)
+ break;
+
+ return build_call_expr (fn, 2, arg0, arg1);
+ }
+ break;
+
case BUILT_IN_STRCMP:
return fold_builtin_strcmp (arg0, arg1);
--- gcc/testsuite/gcc.c-torture/compile/pr38343.c.jj 2008-12-01 18:36:44.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr38343.c 2008-12-01 18:36:25.000000000 +0100
@@ -0,0 +1,12 @@
+/* PR middle-end/38343 */
+
+static struct A
+{
+ char f[6];
+} a[] = { {"01000"} };
+
+void
+foo (void)
+{
+ __builtin_stpcpy (a[0].f, "S0022");
+}
Jakub