OSDN Git Service

Fix PR 34077
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Nov 2007 22:33:30 +0000 (22:33 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Nov 2007 22:33:30 +0000 (22:33 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130453 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr34077.c [new file with mode: 0644]

index 9a4b543..dbc652f 100644 (file)
@@ -1,3 +1,11 @@
+2007-11-26  Michael Meissner  <michael.meissner@amd.com>
+
+       PR target/34077
+       * config/i386/i386.c (ix86_expand_movmem): If the copy size is a
+       constant, avoid calling emit_cmp_and_jump_insns.  Use counter_mode
+       to get the mode for loading a pseudo register with a count rather
+       than duplicating code.
+
 2007-11-25  Eric B. Weddington  <eric.weddington@atmel.com>
 
        * config/avr/avr.c (avr_mcu_types): Add atmega1284p.
index b378aae..a81ee3d 100644 (file)
@@ -15366,12 +15366,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
 
   /* Alignment code needs count to be in register.  */
   if (CONST_INT_P (count_exp) && desired_align > align)
-    {
-      enum machine_mode mode = SImode;
-      if (TARGET_64BIT && (count & ~0xffffffff))
-       mode = DImode;
-      count_exp = force_reg (mode, count_exp);
-    }
+    count_exp = force_reg (counter_mode (count_exp), count_exp);
   gcc_assert (desired_align >= 1 && align >= 1);
 
   /* Ensure that alignment prologue won't copy past end of block.  */
@@ -15382,29 +15377,48 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
         Make sure it is power of 2.  */
       epilogue_size_needed = smallest_pow2_greater_than (epilogue_size_needed);
 
-      label = gen_label_rtx ();
-      emit_cmp_and_jump_insns (count_exp,
-                              GEN_INT (epilogue_size_needed),
-                              LTU, 0, counter_mode (count_exp), 1, label);
-      if (GET_CODE (count_exp) == CONST_INT)
-       ;
-      else if (expected_size == -1 || expected_size < epilogue_size_needed)
-       predict_jump (REG_BR_PROB_BASE * 60 / 100);
+      if (CONST_INT_P (count_exp))
+       {
+         if (UINTVAL (count_exp) < (unsigned HOST_WIDE_INT)epilogue_size_needed)
+           goto epilogue;
+       }
       else
-       predict_jump (REG_BR_PROB_BASE * 20 / 100);
+       {
+         label = gen_label_rtx ();
+         emit_cmp_and_jump_insns (count_exp,
+                                  GEN_INT (epilogue_size_needed),
+                                  LTU, 0, counter_mode (count_exp), 1, label);
+         if (expected_size == -1 || expected_size < epilogue_size_needed)
+           predict_jump (REG_BR_PROB_BASE * 60 / 100);
+         else
+           predict_jump (REG_BR_PROB_BASE * 20 / 100);
+       }
     }
+
   /* Emit code to decide on runtime whether library call or inline should be
      used.  */
   if (dynamic_check != -1)
     {
-      rtx hot_label = gen_label_rtx ();
-      jump_around_label = gen_label_rtx ();
-      emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
-                              LEU, 0, GET_MODE (count_exp), 1, hot_label);
-      predict_jump (REG_BR_PROB_BASE * 90 / 100);
-      emit_block_move_via_libcall (dst, src, count_exp, false);
-      emit_jump (jump_around_label);
-      emit_label (hot_label);
+      if (CONST_INT_P (count_exp))
+       {
+         if (UINTVAL (count_exp) >= (unsigned HOST_WIDE_INT)dynamic_check)
+           {
+             emit_block_move_via_libcall (dst, src, count_exp, false);
+             count_exp = const0_rtx;
+             goto epilogue;
+           }
+       }
+      else
+       {
+         rtx hot_label = gen_label_rtx ();
+         jump_around_label = gen_label_rtx ();
+         emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
+                                  LEU, 0, GET_MODE (count_exp), 1, hot_label);
+         predict_jump (REG_BR_PROB_BASE * 90 / 100);
+         emit_block_move_via_libcall (dst, src, count_exp, false);
+         emit_jump (jump_around_label);
+         emit_label (hot_label);
+       }
     }
 
   /* Step 2: Alignment prologue.  */
@@ -15477,7 +15491,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
     }
 
   /* Step 4: Epilogue to copy the remaining bytes.  */
-
+ epilogue:
   if (label)
     {
       /* When the main loop is done, COUNT_EXP might hold original count,
index 498593d..5363cf2 100644 (file)
@@ -1,3 +1,8 @@
+2007-11-13  Michael Meissner  <michael.meissner@amd.com>
+
+       PR target/34077
+       * gcc.target/i386/pr34077.c: New testcase.
+
 2007-11-26  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/34203
diff --git a/gcc/testsuite/gcc.target/i386/pr34077.c b/gcc/testsuite/gcc.target/i386/pr34077.c
new file mode 100644 (file)
index 0000000..a2ec5d1
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -minline-all-stringops -minline-stringops-dynamically" } */
+
+#include <string.h>
+
+extern double ran(void);
+
+struct spec_fd_t {
+  int limit;
+  int len;
+  int pos;
+  unsigned char *buf;
+} spec_fd[3];
+
+int spec_random_load (int fd) {
+  int i, j;
+  char random_text[(32)][(128*1024)];
+
+  for (j = 0; j < (128*1024); j++) {
+    random_text[i][j] = (int)(ran()*256);
+  }
+
+  for (i = 0 ; i < spec_fd[fd].limit; i+= (128*1024)) {
+    memcpy(spec_fd[fd].buf + i, random_text[(int)(ran()*(32))],
+          (128*1024));
+  }
+
+  spec_fd[fd].len = 1024*1024;
+  return 0;
+}