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]

Re: [IA-64 PATCH] PR rtl-opt/14261: ifcvt.c vs emit_move_insn.


On Mon, 27 Feb 2006, James E Wilson wrote:
> Looking at this again, I see two possible solutions that don't look very
> hard....
> The second one is to note that we already have special purpose code for
> the case where the destination is a STRICT_LOW_PART, in which case we
> call store_bit_field.  We can do the same thing for the case where the
> destination is a ZERO_EXTRACT.  The code needs to be a little different
> for this case.  A STRICT_LOW_PART always contains a SUBREG, and the code
> is stripping off the SUBREG.  This part doesn't apply when we have a
> ZERO_EXTRACT.  Otherwise, the two cases should be pretty similar.

Ah, yes.  I'd overlooked that we already handle STRICT_LOW_PART
specially, and it makes sense to treat ZERO_EXTRACT similarly.
The following patch implements this suggestion.  Even though this
is middle-end, its good to get a second pair of eyes to look over
it, just in case I've missed anything.  This fixes the ICE, and
it looks like there are no endian issues, but I'm not certain.

The following patch has been tested on ia64-unknown-linux-gnu with a
full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.

Ok for mainline?



2006-02-27  Roger Sayle  <roger@eyesopen.com>
	    James E Wilson  <wilson@specifix.com>

	PR rtl-optimization/14261
	* ifcvt.c (noce_emit_move_insn): Handle ZERO_EXTRACT destinations
	using store_bit_field, like we do for STRICT_LOW_PART.

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


Index: ifcvt.c
===================================================================
*** ifcvt.c	(revision 110686)
--- ifcvt.c	(working copy)
*************** noce_emit_move_insn (rtx x, rtx y)
*** 687,693 ****
    rtx outer, inner;
    int bitpos;

!   if (GET_CODE (x) != STRICT_LOW_PART)
      {
        rtx seq, insn, target;
        optab ot;
--- 687,709 ----
    rtx outer, inner;
    int bitpos;

!   if (GET_CODE (x) == STRICT_LOW_PART)
!     {
!       outer = XEXP (x, 0);
!       inner = XEXP (outer, 0);
!       outmode = GET_MODE (outer);
!       bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
!       store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos, outmode, y);
!     }
!   else if (GET_CODE (x) == ZERO_EXTRACT)
!     {
!       outer = x;
!       inner = XEXP (outer, 0);
!       outmode = GET_MODE (outer);
!       bitpos = INTVAL (XEXP (x, 2));
!       store_bit_field (inner, INTVAL (XEXP (x, 1)), bitpos, outmode, y);
!     }
!   else
      {
        rtx seq, insn, target;
        optab ot;
*************** noce_emit_move_insn (rtx x, rtx y)
*** 744,757 ****
  	  }

        emit_insn (seq);
-       return;
      }
-
-   outer = XEXP (x, 0);
-   inner = XEXP (outer, 0);
-   outmode = GET_MODE (outer);
-   bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
-   store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos, outmode, y);
  }

  /* Return sequence of instructions generated by if conversion.  This
--- 760,766 ----



/* PR rtl-optimization/14261  */
/* { dg-do compile } */
/* { dg-options "-O2" } */

typedef union YYSTYPE {
    double dval;
    int intval;
} YYSTYPE;

YYSTYPE *x;

void
knparse (void)
{
  YYSTYPE yyvsa[200];
  register YYSTYPE *yyvsp;
  YYSTYPE yyval, *x;
  yyvsp = &yyvsa[100];
  if (yyvsp[3].intval > yyvsp[0].intval)
     yyval.intval = yyvsp[3].intval;
  else
     yyval.intval = yyvsp[0].intval;
  *x = yyval;
}


Roger
--


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