http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47968

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |pinskia at gcc dot gnu.org
         AssignedTo|unassigned at gcc dot       |rguenth at gcc dot gnu.org
                   |gnu.org                     |

--- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-03-03 
13:30:28 UTC ---
We call extract_bit_field SFmode [0, 32] on (subreg:V4SF (reg/v:V2DF 62 [ d2 ])
0) which then ends up using the vec_extract optabs, but those are obviously
not designed for a mode-changing extraction (and we stripped the subreg
before using it - whether that's a good idea is another question).

We try to find a "better" vector mode but end up with V2DF again because
we want to preserve NUNITS of the inner reg (for whatever reason again).

We can obviously guard the vec_extract optab use by GET_MODE_INNER (GET_MODE
(op0)) == tmode, but we can as well try to find a "better" mode that also
is going to work ...

Testing a patch, CCing Andrew who added this code.

Patch:

Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c        (revision 170649)
+++ gcc/expmed.c        (working copy)
@@ -1205,7 +1205,6 @@ extract_bit_field_1 (rtx str_rtx, unsign
       && GET_MODE_INNER (GET_MODE (op0)) != tmode)
     {
       enum machine_mode new_mode;
-      int nunits = GET_MODE_NUNITS (GET_MODE (op0));

       if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
        new_mode = MIN_MODE_VECTOR_FLOAT;
@@ -1221,8 +1220,7 @@ extract_bit_field_1 (rtx str_rtx, unsign
        new_mode = MIN_MODE_VECTOR_INT;

       for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode))
-       if (GET_MODE_NUNITS (new_mode) == nunits
-           && GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0))
+       if (GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0))
            && targetm.vector_mode_supported_p (new_mode))
          break;
       if (new_mode != VOIDmode)

Reply via email to