The following demonstrates a bug in combine
(x86 -mtune=pentiumpro -O2):

    struct Flags {
 int filler[18];
 unsigned int a:14;
 unsigned int b:14;
 unsigned int c:1;
 unsigned int d:1;
 unsigned int e:1;
 unsigned int f:1;
    };
extern int bar(int), baz();
int foo (struct Flags *f) {
  if (f->b > 0)
    return bar(f->d);
  return baz();
}


The test of f->b comes out as

  testl  $1048512, 73(%eax)

This is wrong, because 4 bytes starting at 73 goes outside the original object and can cause a page fault. The change from referencing a word at offset 72 to offset 73
happens in make_extraction in combine, and I propose to fix it thus:

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.502
diff -u -b -c -3 -p -r1.502 combine.c
cvs diff: conflicting specifications of output style
*** combine.c   8 Aug 2005 18:30:09 -0000       1.502
--- combine.c   25 Aug 2005 17:57:21 -0000
*************** make_extraction (enum machine_mode mode,
*** 6484,6491 ****
          && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
        offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
  
!       /* If this is a constant position, we can move to the desired byte.  */
!       if (pos_rtx == 0)
        {
          offset += pos / BITS_PER_UNIT;
          pos %= GET_MODE_BITSIZE (wanted_inner_mode);
--- 6484,6493 ----
          && GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
        offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
  
!       /* If this is a constant position, we can move to the desired byte.
!        This is unsafe for memory objects; it might result in accesses
!        outside the original object.  */
!       if (pos_rtx == 0 && !MEM_P (inner))
        {
          offset += pos / BITS_PER_UNIT;
          pos %= GET_MODE_BITSIZE (wanted_inner_mode);


Still testing, but I'm a bit concerned this is overkill. Are there targets/situations where
this transformation is useful or even necessary?  Comments?

Reply via email to