In a given test case with 128 bit mmx intrinsics, routine make_compound_operation (in combine.c) attempts to do a sign-extract of the middle 64bit of the 128 bit (TImode) register. Pattern we have is:

(lshiftrt:TI (ashift:TI (subreg:TI (reg/v:V2DI 75 [ vu16YPrediction3 ]) 0) (const_int 32 [0x20]))
    (const_int 64 [0x40]))

And here is the code which attempts to do this:
    case LSHIFTRT:
       ....

      /* ... fall through ...  */

    case ASHIFTRT:
      lhs = XEXP (x, 0);
      rhs = XEXP (x, 1);

      /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
         this is a SIGN_EXTRACT.  */
=>    if (GET_CODE (rhs) == CONST_INT
          && GET_CODE (lhs) == ASHIFT
          && GET_CODE (XEXP (lhs, 1)) == CONST_INT
          && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
        {
          new = make_compound_operation (XEXP (lhs, 0), next_code);
          new = make_extraction (mode, new,
                                 INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
                                 NULL_RTX, mode_width - INTVAL (rhs),
code == LSHIFTRT, 0, in_code == COMPARE);
....


This results in gen_rtx_SUBREG asserting. We can't really do this extraction when the extraction mode (DImode in this case) is not properly aligned within its original mode. In other words, gen_rtx_SUBREG attempts to generate an illegal rtl; such as:

(subreg:DI (reg/v:V2DI 75 [ vu16YPrediction3 ]) 4)

and asserts. Following patch avoids this problem. If this is OK, I will submit a patch when fsf mainline is unfrozen.

- fariborz ([EMAIL PROTECTED])



Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.475.2.5
diff -c -p -r1.475.2.5 combine.c
*** combine.c   26 Aug 2005 22:36:52 -0000      1.475.2.5
--- combine.c   22 Sep 2005 19:52:02 -0000
*************** make_extraction (enum machine_mode mode,
*** 6197,6203 ****

                  /* Avoid creating invalid subregs, for example when
                     simplifying (x>>32)&255.  */
!                 if (final_word >= GET_MODE_SIZE (inner_mode))
                    return NULL_RTX;

                  new = gen_rtx_SUBREG (tmode, inner, final_word);
--- 6197,6204 ----

                  /* Avoid creating invalid subregs, for example when
                     simplifying (x>>32)&255.  */
!                 if (final_word >= GET_MODE_SIZE (inner_mode)
!                     || (final_word % GET_MODE_SIZE (tmode)) != 0)
                    return NULL_RTX;

                  new = gen_rtx_SUBREG (tmode, inner, final_word);

Reply via email to