This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Stop looping in move_by_pieces loops when there's no more data to process
- From: Tom de Vries <Tom_deVries at mentor dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 16 Oct 2012 08:40:21 +0200
- Subject: [PATCH] Stop looping in move_by_pieces loops when there's no more data to process
Jakub,
I've noticed that the move_by_pieces loops keep iterating after there's no more
data to process.
I've added this assert to trigger an example in a gcc build:
...
Index: src/gcc/expr.c
===================================================================
--- src/gcc/expr.c (revision 191792)
+++ src/gcc/expr.c (working copy)
@@ -1031,6 +1031,8 @@ move_by_pieces_ninsns (unsigned HOST_WID
enum machine_mode mode;
enum insn_code icode;
+ gcc_assert (l > 0);
+
mode = widest_int_mode_for_size (max_size);
if (mode == VOIDmode)
...
It triggers while compiling __gcov_execle. After l is 0, we still enter the loop
until we run out of modes to try:
...
Breakpoint 2, move_by_pieces_ninsns (l=24, align=64, max_size=9) at expr.c:1025
1025 unsigned HOST_WIDE_INT n_insns = 0;
(gdb) n
1027 align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
(gdb)
1029 while (max_size > 1)
(gdb)
1034 gcc_assert (l > 0);
(gdb)
1036 mode = widest_int_mode_for_size (max_size);
(gdb)
1038 if (mode == VOIDmode)
(gdb)
1041 icode = optab_handler (mov_optab, mode);
(gdb)
1042 if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
(gdb)
1043 n_insns += l / GET_MODE_SIZE (mode), l %= GET_MODE_SIZE (mode);
(gdb)
1045 max_size = GET_MODE_SIZE (mode);
(gdb)
1029 while (max_size > 1)
(gdb) p l
$3 = 0
(gdb) p max_size
$4 = 8
(gdb) n
1034 gcc_assert (l > 0);
(gdb)
...
This patch fixes that in this loop, and other move_by_pieces loops.
Bootstrapped and reg-tested on x86_64.
OK for trunk?
Thanks,
- Tom
2012-10-16 Tom de Vries <tom@codesourcery.com>
* expr.c (move_by_pieces, move_by_pieces_ninsns, can_store_by_pieces)
(store_by_pieces_1): Don't enter loop when no more data is left.
Index: gcc/expr.c
===================================================================
--- gcc/expr.c (revision 191792)
+++ gcc/expr.c (working copy)
@@ -966,7 +966,7 @@ move_by_pieces (rtx to, rtx from, unsign
/* First move what we can in the largest integer mode, then go to
successively smaller modes. */
- while (max_size > 1)
+ while (max_size > 1 && data.len > 0)
{
enum machine_mode mode = widest_int_mode_for_size (max_size);
@@ -1026,7 +1026,7 @@ move_by_pieces_ninsns (unsigned HOST_WID
align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
- while (max_size > 1)
+ while (max_size > 1 && l > 0)
{
enum machine_mode mode;
enum insn_code icode;
@@ -2417,7 +2417,7 @@ can_store_by_pieces (unsigned HOST_WIDE_
{
l = len;
max_size = STORE_MAX_PIECES + 1;
- while (max_size > 1)
+ while (max_size > 1 && l > 0)
{
mode = widest_int_mode_for_size (max_size);
@@ -2612,7 +2612,7 @@ store_by_pieces_1 (struct store_by_piece
/* First store what we can in the largest integer mode, then go to
successively smaller modes. */
- while (max_size > 1)
+ while (max_size > 1 && data->len > 0)
{
enum machine_mode mode = widest_int_mode_for_size (max_size);