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

[PATCH] Fix PR37870, ICE in extract_bit_field_1


We try to expand

  return (unsigned int) VIEW_CONVERT_EXPR<struct
  {
    char dummy[8];
    <unnamed-unsigned:7> yyy;
  }>(arg).yyy;

which is SRAed from the gimplified memcpy

  copy = VIEW_CONVERT_EXPR<struct
  {
    char dummy[8];
    <unnamed-unsigned:7> yyy;
  }>(arg);

to

<bb 2>:
  copy$yyy_5 = 0;
  copy$dummy$7_6 = VIEW_CONVERT_EXPR<struct
  {
    char dummy[8];
    <unnamed-unsigned:7> yyy;
  }>(arg_4(D)).dummy[7];
...
  SR.9_14 = VIEW_CONVERT_EXPR<struct
  {
    char dummy[8];
    <unnamed-unsigned:7> yyy;
  }>(arg_4(D)).yyy;
  copy$yyy_15 = SR.9_14;
  SR.10_16 = copy$yyy_15;
  D.1204_1 = SR.10_16;
  D.1203_2 = (unsigned int) D.1204_1;
  return D.1203_2;


It seems extract_bitfield_1 doesn't have a fallback path going through 
memory:

1261      /* Make sure we are playing with integral modes.  Pun with 
subregs
1262         if we aren't.  */
1263      {
1264        enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
1265        if (imode != GET_MODE (op0))
(gdb) l
1266          {
1267            if (MEM_P (op0))
1268              op0 = adjust_address (op0, imode, 0);
1269            else
1270              {
1271                gcc_assert (imode != BLKmode);

obviously fails on i?86 with

(gdb) call debug_rtx (op0)
(reg/v:XF 59 [ arg ])

simply not going down this path and relying on the fallback seems to work.
In particular any assertion in extract_bit_field_1 looks suspicious as
the function comment says

   If FALLBACK_P is true, fall back to extract_fixed_bit_field
   if we can find no other means of implementing the operation.

I didn't expect the patch to cause any problems and it didn't - 
bootstrapped and tested on x86_64-unknown-linux-gnu.  Still somebody
may remember a reason for this assertion.  So, ok for trunk?

Thanks,
Richard.

2008-10-19  Richard Guenther  <rguenther@suse.de>

	PR middle-end/37870
	* expmed.c (extract_bit_field_1): Guard lowpart case with
	!BLKmode instead of asserting.

	* gcc.c-torture/compile/pr37870.c: New testcase.

Index: gcc/expmed.c
===================================================================
*** gcc/expmed.c	(revision 141220)
--- gcc/expmed.c	(working copy)
*************** extract_bit_field_1 (rtx str_rtx, unsign
*** 1266,1274 ****
        {
  	if (MEM_P (op0))
  	  op0 = adjust_address (op0, imode, 0);
! 	else
  	  {
- 	    gcc_assert (imode != BLKmode);
  	    op0 = gen_lowpart (imode, op0);
  
  	    /* If we got a SUBREG, force it into a register since we
--- 1266,1273 ----
        {
  	if (MEM_P (op0))
  	  op0 = adjust_address (op0, imode, 0);
! 	else if (imode != BLKmode)
  	  {
  	    op0 = gen_lowpart (imode, op0);
  
  	    /* If we got a SUBREG, force it into a register since we
Index: gcc/testsuite/gcc.c-torture/compile/pr37870.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/pr37870.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/compile/pr37870.c	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ extern void *memcpy (void *__restrict __dest,
+        __const void *__restrict __src, __SIZE_TYPE__ __n)
+      __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
+ 
+ unsigned xxx(long double arg)
+ {
+         struct
+         {
+                 char dummy[8];
+                 unsigned yyy:7;
+         } copy;
+         memcpy(&copy, &arg, sizeof(copy));
+         return copy.yyy;
+ }
+ 


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