re PR middle-end/81657 (FAIL: gcc.dg/20050503-1.c scan-assembler-not call)
authorMartin Liska <mliska@suse.cz>
Fri, 13 Apr 2018 08:35:32 +0000 (10:35 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 13 Apr 2018 08:35:32 +0000 (10:35 +0200)
PR middle-end/81657
* expr.h (enum block_op_methods): Add BLOCK_OP_NO_LIBCALL_RET.
* expr.c (emit_block_move_hints): Handle BLOCK_OP_NO_LIBCALL_RET.
* builtins.c (expand_builtin_memory_copy_args): Use
BLOCK_OP_NO_LIBCALL_RET method for mempcpy with non-ignored target,
handle dest_addr == pc_rtx.

* gcc.dg/string-opt-1.c: Remove bogus comment.  Expect a mempcpy
call.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r259366

gcc/ChangeLog
gcc/builtins.c
gcc/expr.c
gcc/expr.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/string-opt-1.c

index b934cc17a1d439f031c84c4f80581ee0131053bd..4a3f07f9713cf160e1a1ca67250f7f51c5304fb0 100644 (file)
@@ -1,3 +1,13 @@
+2018-04-13  Martin Liska  <mliska@suse.cz>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/81657
+       * expr.h (enum block_op_methods): Add BLOCK_OP_NO_LIBCALL_RET.
+       * expr.c (emit_block_move_hints): Handle BLOCK_OP_NO_LIBCALL_RET.
+       * builtins.c (expand_builtin_memory_copy_args): Use
+       BLOCK_OP_NO_LIBCALL_RET method for mempcpy with non-ignored target,
+       handle dest_addr == pc_rtx.
+
 2018-04-12  Segher Boessenkool  <segher@kernel.crashing.org>
 
        PR target/85291
index ababee5db16fd4e6110363be825969d992df3601..93c617e81ff6f26c500e3e85531892e4ca649167 100644 (file)
@@ -3650,12 +3650,16 @@ expand_builtin_memory_copy_args (tree dest, tree src, tree len,
   set_mem_align (src_mem, src_align);
 
   /* Copy word part most expediently.  */
-  dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
-                                    CALL_EXPR_TAILCALL (exp)
-                                    && (endp == 0 || target == const0_rtx)
-                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
+  enum block_op_methods method = BLOCK_OP_NORMAL;
+  if (CALL_EXPR_TAILCALL (exp) && (endp == 0 || target == const0_rtx))
+    method = BLOCK_OP_TAILCALL;
+  if (endp == 1 && target != const0_rtx)
+    method = BLOCK_OP_NO_LIBCALL_RET;
+  dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method,
                                     expected_align, expected_size,
                                     min_size, max_size, probable_max_size);
+  if (dest_addr == pc_rtx)
+    return NULL_RTX;
 
   if (dest_addr == 0)
     {
index 5e3d9a5bdfb696c50ee38ec1b155d5a9091e026e..cf5b63172f1cddcb0c1ea4ba6bd488c2e3b817df 100644 (file)
@@ -1565,7 +1565,7 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
                       unsigned HOST_WIDE_INT max_size,
                       unsigned HOST_WIDE_INT probable_max_size)
 {
-  bool may_use_call;
+  int may_use_call;
   rtx retval = 0;
   unsigned int align;
 
@@ -1577,7 +1577,7 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
     {
     case BLOCK_OP_NORMAL:
     case BLOCK_OP_TAILCALL:
-      may_use_call = true;
+      may_use_call = 1;
       break;
 
     case BLOCK_OP_CALL_PARM:
@@ -1589,7 +1589,11 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
       break;
 
     case BLOCK_OP_NO_LIBCALL:
-      may_use_call = false;
+      may_use_call = 0;
+      break;
+
+    case BLOCK_OP_NO_LIBCALL_RET:
+      may_use_call = -1;
       break;
 
     default:
@@ -1625,6 +1629,9 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
           && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
           && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
     {
+      if (may_use_call < 0)
+       return pc_rtx;
+
       /* Since x and y are passed to a libcall, mark the corresponding
         tree EXPR as addressable.  */
       tree y_expr = MEM_EXPR (y);
index b3d523bcb24f8e4af6cc13e61690b38e32561764..52a26e7c2a3e1be48ee09909782b7045715dbec2 100644 (file)
@@ -100,7 +100,11 @@ enum block_op_methods
   BLOCK_OP_NO_LIBCALL,
   BLOCK_OP_CALL_PARM,
   /* Like BLOCK_OP_NORMAL, but the libcall can be tail call optimized.  */
-  BLOCK_OP_TAILCALL
+  BLOCK_OP_TAILCALL,
+  /* Like BLOCK_OP_NO_LIBCALL, but instead of emitting a libcall return
+     pc_rtx to indicate nothing has been emitted and let the caller handle
+     it.  */
+  BLOCK_OP_NO_LIBCALL_RET
 };
 
 typedef rtx (*by_pieces_constfn) (void *, HOST_WIDE_INT, scalar_int_mode);
index ce924a3ae5cc5bcf5fed034cb7dbd17a67a75ebf..665a3d85152535e7f03909393964f299d7a95222 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-13  Martin Liska  <mliska@suse.cz>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/81657
+       * gcc.dg/string-opt-1.c: Remove bogus comment.  Expect a mempcpy
+       call.
+
 2018-04-12  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/85385
index 2f060732bf042e7083dfef0824ffc3c84b6e65a4..7945ef39c57725956031eb668f2de122fecf2ad8 100644 (file)
@@ -1,4 +1,3 @@
-/* Ensure mempcpy is "optimized" into memcpy followed by addition.  */
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 
@@ -48,5 +47,5 @@ main (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler-not "\<mempcpy\>" } } */
+/* { dg-final { scan-assembler "mempcpy" } } */
 /* { dg-final { scan-assembler "memcpy" } } */