> when expanding code for
 > struct a {short a,b,c,d;} *a;
 > a->c;
 > we first produce correct BLKmode MEM rtx representing the whole
 > structure *a,
 > then we use adjust_address to turn it into HImode MEM and finally
 > extract_bitfield is used to offset it by 32 bits to get correct value.

I tried to create a test case as follows and stepped thru the code.

cat test.c
struct a {short a,b,c,d;};
void foo (struct a *a)
   a->c = 1;

First I get a DImode MEM rtx not BLKmode:

(mem:DI (reg/f:DI 87) [2 *a_2(D)+0 S8 A16])

and adjust_address does not clear the MEM_EXPR

thus to_rtx = adjust_address (to_rtx, mode1, 0) returns:

(mem:HI (reg/f:DI 87) [2 *a_2(D)+0 S2 A16])

and then set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos) does:

(mem:HI (reg/f:DI 87) [3 a_2(D)->c+-4 S6 A16])

which looks perfectly OK.

But with your patch the RTX looks different:

(mem:DI (reg/f:DI 87) [3 a_2(D)->c+-4 S6 A16])

which looks inconsistent, and not like an improvement.

Especially when the mode of the target_rtx may be used
somewhere in store_field:

       /* If TEMP is not a PARALLEL (see below) and its mode and that of 
          are both BLKmode, both must be in memory and BITPOS must be 
          on a byte boundary.  If so, we simply do a block copy. 
Likewise for
          a BLKmode-like TARGET.  */
       if (GET_CODE (temp) != PARALLEL
           && GET_MODE (temp) == BLKmode
               || (MEM_P (target)
                   && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT

and I see store_fixed_bit_field also looks at the memory mode:
   if (MEM_P (op0))
       machine_mode mode = GET_MODE (op0);
       if (GET_MODE_BITSIZE (mode) == 0
           || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
         mode = word_mode;
       mode = get_best_mode (bitsize, bitnum, bitregion_start, 
                             MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));


Reply via email to