builtins.c (expand_builtin_mempcpy): New function.
authorJakub Jelinek <jakub@redhat.com>
Mon, 5 May 2003 19:31:35 +0000 (21:31 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 5 May 2003 19:31:35 +0000 (21:31 +0200)
* builtins.c (expand_builtin_mempcpy): New function.
(expand_builtin_stpcpy): Optimize stpcpy whose return value is
ignored into strcpy no matter what arguments it has.
(expand_builtin) <case BUILT_IN_MEMPCPY>: Call
expand_builtin_mempcpy.

* gcc.c-torture/execute/string-opt-18.c (main): Add 3 new tests.

From-SVN: r66498

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/string-opt-18.c

index a28796eb99f83eb6c6f27c445872aac7fba5eedf..0b57087b438417e99153edd5831bf22014d4c403 100644 (file)
@@ -1,3 +1,11 @@
+2003-05-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * builtins.c (expand_builtin_mempcpy): New function.
+       (expand_builtin_stpcpy): Optimize stpcpy whose return value is
+       ignored into strcpy no matter what arguments it has.
+       (expand_builtin) <case BUILT_IN_MEMPCPY>: Call
+       expand_builtin_mempcpy.
+
 2003-05-05  Aldy Hernandez  <aldyh@redhat.com>
 
         * testsuite/gcc.dg/20030505.c: New.
index e0a6dea3ce710ba2de5e6cc5ae39434f87ed953d..dfc17e569fdad06886b6589e3f05f790516d3c8c 100644 (file)
@@ -126,6 +126,8 @@ static rtx expand_builtin_strcspn   PARAMS ((tree, rtx,
                                                 enum machine_mode));
 static rtx expand_builtin_memcpy       PARAMS ((tree, rtx,
                                                 enum machine_mode, int));
+static rtx expand_builtin_mempcpy      PARAMS ((tree, rtx,
+                                                enum machine_mode));
 static rtx expand_builtin_memmove      PARAMS ((tree, rtx,
                                                 enum machine_mode));
 static rtx expand_builtin_bcopy                PARAMS ((tree));
@@ -2345,6 +2347,43 @@ expand_builtin_memcpy (arglist, target, mode, endp)
     }
 }
 
+/* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
+   Return 0 if we failed the caller should emit a normal call,
+   otherwise try to get the result in TARGET, if convenient (and in
+   mode MODE if that's convenient).  */
+
+static rtx
+expand_builtin_mempcpy (arglist, target, mode)
+     tree arglist;
+     rtx target;
+     enum machine_mode mode;
+{
+  if (!validate_arglist (arglist,
+                        POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+    return 0;
+  else
+    {
+      /* If return value is ignored, transform mempcpy into memcpy.  */
+      if (target == const0_rtx)
+       {
+         tree fn;
+         rtx ret = expand_builtin_memcpy (arglist, target, mode, /*endp=*/0);
+
+         if (ret)
+           return ret;
+
+         fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+         if (!fn)
+           return 0;
+
+         return expand_expr (build_function_call_expr (fn, arglist),
+                             target, mode, EXPAND_NORMAL);
+       }
+
+      return expand_builtin_memcpy (arglist, target, mode, /*endp=*/1);
+    }
+}
+
 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
    if we failed the caller should emit a normal call.  */
 
@@ -2469,7 +2508,26 @@ expand_builtin_stpcpy (arglist, target, mode)
   else
     {
       tree newarglist;
-      tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
+      tree len;
+
+      /* If return value is ignored, transform stpcpy into strcpy.  */
+      if (target == const0_rtx)
+       {
+         tree fn;
+         rtx ret = expand_builtin_strcpy (arglist, target, mode);
+
+         if (ret)
+           return ret;
+
+         fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+         if (!fn)
+           return 0;
+
+         return expand_expr (build_function_call_expr (fn, arglist),
+                             target, mode, EXPAND_NORMAL);
+       }
+
+      len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
       if (len == 0)
        return 0;
 
@@ -4586,7 +4644,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
       break;
 
     case BUILT_IN_MEMPCPY:
-      target = expand_builtin_memcpy (arglist, target, mode, /*endp=*/1);
+      target = expand_builtin_mempcpy (arglist, target, mode);
       if (target)
        return target;
       break;
index 92a767911e1b9fd157426f990d02c429275667ad..536043aba922ab6b59974ae4185cd47bbd1909f8 100644 (file)
@@ -1,3 +1,7 @@
+2003-05-05  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/string-opt-18.c (main): Add 3 new tests.
+
 2003-05-05  Geoffrey Keating  <geoffk@apple.com>
 
        * gcc.dg/unused-5.c: New test.
index 0ba2be6e62803a37fcf89cadb15d47b1282056c3..dfa5c169e2dd07a9ccd7219b82dc83f2861711c0 100644 (file)
@@ -15,6 +15,9 @@ extern int memcmp (const void *, const void *, size_t);
 
 const char s1[] = "123";
 char p[32] = "";
+char *s2 = "defg";
+char *s3 = "FGH";
+size_t l1 = 1;
 
 int main()
 {
@@ -60,6 +63,17 @@ int main()
   if (__builtin_mempcpy (p, "ABCDE", 6) != p + 6 || memcmp (p, "ABCDE", 6))
     abort ();
 
+  /* If the result of stpcpy/mempcpy is ignored, gcc should use
+     strcpy/memcpy.  */
+  stpcpy (p + 3, s2);
+  if (memcmp (p, "ABCdefg", 8))
+    abort ();
+  mempcpy (p + 5, s3, 1);
+  if (memcmp (p, "ABCdeFg", 8))
+    abort ();
+  mempcpy (p + 6, s3 + 1, l1);
+  if (memcmp (p, "ABCdeFG", 8))
+    abort ();
   return 0;
 }