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

Fariborz Jahanian fjahanian@apple.com
Thu Sep 22 20:23:00 GMT 2005


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



More information about the Gcc mailing list