This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
set_mem_attributes_minus_bitpos vs. size
- From: "Ulrich Weigand" <Ulrich dot Weigand at de dot ibm dot com>
- To: rth at redhat dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 16 Sep 2002 19:19:31 +0200
- Subject: set_mem_attributes_minus_bitpos vs. size
- Sensitivity:
Hello Richard,
after updating to the latest tree I'm seeing failures of
struct-cpy-1.c on s390. This appears to be caused by
movstr being called with a destination MEM with incorrect
size attibute.
What happens is that when using these structures:
struct termios
{
unsigned int a;
unsigned int b;
unsigned int c;
unsigned int d;
unsigned char pad[28];
};
struct tty_driver
{
unsigned char pad1[38];
struct termios t __attribute__ ((aligned (8)));
};
static struct termios zero_t;
static struct tty_driver pty;
the assignment
pty.t = zero_t;
gets translated to
(insn 10 9 12 (nil) (parallel [
(set (mem/s:BLK (plus:SI (reg/f:SI 40)
(const_int 40 [0x28])) [5 pty.t+0 S4 A64])
(mem/s:BLK (reg/f:SI 41) [5 zero_t+0 S44 A32]))
(use (const_int 43 [0x2b]))
(clobber (scratch:SI))
]) -1 (nil)
(nil))
Note the dest size of 4 instead of 44. This incorrect size
leads to incorrect scheduling decisions later.
The reason for the incorrect size appears to be an unfortunate
interaction between set_mem_attributes_minus_bitpos_size as
called from expand_assignment and adjust_address as called from
store_field.
In expand_assignment, we start out with
(mem/s:BLK (reg/f:SI 40) [3 pty+0 S88 A64])
describing the whole pty struct.
expand_assignment then calls set_mem_attributes_minus_bitpos_size,
which adjusts this target MEM to
(mem/s:BLK (reg/f:SI 40) [5 pty.t+-40 S44 A64])
which has the size already reduced to the size of a struct termios.
This MEM is now passed to store_field together with a corresponding
bitpos of 320 (40 bytes). store_field now calls adjust_address
to add the bitpos to the starting offset. This results in
(mem/s:BLK (plus:SI (reg/f:SI 40)
(const_int 40 [0x28])) [5 pty.t+0 S4 A64])
which now has the correct address, but an incorrect size.
This is because adjust_address thinks it is accessing a memory
block of size 44 starting at offset 40 *within this block*,
so the remaining size is just 4 ...
I'm not sure how this is to be fixed; either
set_mem_attributes_minus_bitpos_size increments the size accordingly,
or else adjust_address should recognize this case somehow.
What do you think?
Mit freundlichen Gruessen / Best Regards
Ulrich Weigand
--
Dr. Ulrich Weigand
Linux for S/390 Design & Development
IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
Phone: +49-7031/16-3727 --- Email: Ulrich.Weigand@de.ibm.com