[PATCH] Fix stpcpy and mempcpy expansion (PR middle-end/38343)

Jakub Jelinek jakub@redhat.com
Mon Dec 1 19:31:00 GMT 2008


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



More information about the Gcc-patches mailing list