aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <michael.meissner@amd.com>2007-11-26 22:33:30 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2007-11-26 22:33:30 +0000
commit097f5e21e0c05070ea10fe7807cc9447ddae0831 (patch)
tree93e23afe50f52a02ca7b6cdaf528f19aa9cacef9 /gcc
parenta965fb5ef9bf848161dc96341b607129b023ba6b (diff)
downloadgcc-097f5e21e0c05070ea10fe7807cc9447ddae0831.zip
gcc-097f5e21e0c05070ea10fe7807cc9447ddae0831.tar.gz
gcc-097f5e21e0c05070ea10fe7807cc9447ddae0831.tar.bz2
Fix PR 34077
From-SVN: r130453
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.c62
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr34077.c30
4 files changed, 81 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a4b543..dbc652f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b378aae..a81ee3d0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 498593d..5363cf2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..a2ec5d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr34077.c
@@ -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;
+}