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)