This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR optimization/11741: PRE multiple sets in a PARALLEL


The following patch fixes PR optimization/11741 which is an ICE on
legal.  The problem is that "-O2 -march=pentium4 -minline-all-stringops"
generates an RTL sequence containing the x86's movsb instruction.  The
i386.md represents this as a PARALLEL containing multiple sets; one for
the byte being moved, one for the increment of the source pointer, and
one for the increment of the destination pointer.  Unfortunately, GCSE
realizes that the result of one of these sets is "available", and tries
using it in PRE, by copying it to another pseudo.

Unfortunately there's a mismatch.  The code in hash_scan_insn that
places available expressions in the expr hash table is happy to deal
with parallels containg multiple sets.  Alas, the receiving code in
pre_insert_copy_insn assumes that available expressions are only
generated by "single_set" insns.  This then leads to the abort as
pre_insert_copy_insn doesn't know which of multiple sets (in movsb)
is the one of interest.

The patch below should fix the problem by replicating the relevant
logic from hash_scan_insn in pre_insert_copy_insn.  When handling
multiple sets is a PARALLEL we determine which set is the one we're
interested in by finding the one whose soure is expr_equiv_p to the
current expression (this is the same function used in GCSE to
determine suitable available expressions).

The following patch has been tested on i686-pc-linux-gnu with a complete
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.


Ok for mainline?


2003-09-02  Roger Sayle  <roger@eyesopen.com>

	PR optimization/11741
	* gcse.c (pre_insert_copy_insn): Tweak the logic for finding the
	appropriate set to match that in hash_scan_insn.

	* gcc.dg/20030902-1.c: New test case.


Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.270
diff -c -3 -p -r1.270 gcse.c
*** gcse.c	26 Aug 2003 08:38:59 -0000	1.270
--- gcse.c	2 Sep 2003 03:40:33 -0000
*************** pre_insert_copy_insn (struct expr *expr,
*** 5335,5347 ****
    rtx reg = expr->reaching_reg;
    int regno = REGNO (reg);
    int indx = expr->bitmap_index;
!   rtx set = single_set (insn);
!   rtx new_insn;

!   if (!set)
      abort ();

!   new_insn = emit_insn_after (gen_move_insn (reg, copy_rtx (SET_DEST (set))), insn);

    /* Keep register set table up to date.  */
    record_one_set (regno, new_insn);
--- 5335,5370 ----
    rtx reg = expr->reaching_reg;
    int regno = REGNO (reg);
    int indx = expr->bitmap_index;
!   rtx pat = PATTERN (insn);
!   rtx set, new_insn;
!   int i;

!   /* This block matches the logic in hash_scan_insn.  */
!   if (GET_CODE (pat) == SET)
!     set = pat;
!   else if (GET_CODE (pat) == PARALLEL)
!     {
!       /* Search through the parallel looking for the set whose
! 	 source was the expression that we're interested in.  */
!       set = NULL_RTX;
!       for (i = 0; i < XVECLEN (pat, 0); i++)
! 	{
! 	  rtx x = XVECEXP (pat, 0, i);
! 	  if (GET_CODE (x) == SET
! 	      && expr_equiv_p (SET_SRC (x), expr->expr))
! 	    {
! 	      set = x;
! 	      break;
! 	    }
! 	}
!       if (! set)
! 	abort ();
!     }
!   else
      abort ();

!   new_insn = gen_move_insn (reg, copy_rtx (SET_DEST (set)));
!   new_insn = emit_insn_after (new_insn, insn);

    /* Keep register set table up to date.  */
    record_one_set (regno, new_insn);



/* PR optimization/11741  */
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -minline-all-stringops -march=pentium4" } */

void
foo (char *p)
{
  for (;;)
    {
      memcpy (p, p + 1, strlen (p));
      p++;
    }
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]