From c2a5e65712d986de8f5d24ff9dd453f03f90bdef Mon Sep 17 00:00:00 2001 From: meissner Date: Mon, 26 Nov 2007 22:33:30 +0000 Subject: [PATCH] Fix PR 34077 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130453 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 +++++ gcc/config/i386/i386.c | 62 ++++++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr34077.c | 30 ++++++++++++++++ 4 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr34077.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a4b5437186..dbc652fc824 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-11-26 Michael Meissner + + 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 * config/avr/avr.c (avr_mcu_types): Add atmega1284p. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b378aaec8dd..a81ee3d0929 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 498593dde2c..5363cf2b648 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-11-13 Michael Meissner + + PR target/34077 + * gcc.target/i386/pr34077.c: New testcase. + 2007-11-26 Tobias Burnus 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 00000000000..a2ec5d12b75 --- /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 + +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; +} -- 2.11.4.GIT