Hi, > 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 TARGET are both BLKmode, both must be in memory and BITPOS must be aligned 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, bitregion_end, MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0)); Bernd.