This is the mail archive of the gcc@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]

[RFC] patch to fix an ICE involving sign-extract of mmx expression


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 (fjahanian@apple.com)



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);


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