[PATCH] Fix PR47968, extract_bit_field_1 oddness

Richard Guenther rguenther@suse.de
Thu Mar 3 15:48:00 GMT 2011


This fixes PR47968, we are trying to expand a bitfield extraction
through vec_extract but strip subregs making the inputs invalid.
We try to compensate for this searching for a more proper vector mode
but then we have a strange requirement that NUNITS should stay the
same when the most important thing is to have matching element mode.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok?

Thanks,
Richard.

2011-03-03  Richard Guenther  <rguenther@suse.de>

	PR middle-end/47968
	* expmed.c (extract_bit_field_1): Prefer vector modes that
	vec_extract patterns can handle.

	* gcc.dg/torture/pr47968.c: New testcase.

Index: gcc/expmed.c
===================================================================
*** gcc/expmed.c	(revision 170649)
--- gcc/expmed.c	(working copy)
*************** extract_bit_field_1 (rtx str_rtx, unsign
*** 1205,1211 ****
        && 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;
--- 1205,1210 ----
*************** extract_bit_field_1 (rtx str_rtx, unsign
*** 1221,1228 ****
  	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))
  	    && targetm.vector_mode_supported_p (new_mode))
  	  break;
        if (new_mode != VOIDmode)
--- 1220,1226 ----
  	new_mode = MIN_MODE_VECTOR_INT;
  
        for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode))
! 	if (GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0))
  	    && targetm.vector_mode_supported_p (new_mode))
  	  break;
        if (new_mode != VOIDmode)
Index: gcc/testsuite/gcc.dg/torture/pr47968.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr47968.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr47968.c	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile } */
+ 
+ typedef __attribute__ ((vector_size (16))) float float4;
+ typedef __attribute__ ((vector_size (16))) double double2;
+ 
+ float foo (double2 d2)
+ {
+   float4 f4 = (float4) d2;
+   return *(float *) &f4;
+ }
+ 



More information about the Gcc-patches mailing list