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

[Bug tree-optimization/49079] New: [4.6/4.7 Regression] Bogus constant folding


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49079

           Summary: [4.6/4.7 Regression] Bogus constant folding
           Product: gcc
           Version: 4.6.1
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: rguenth@gcc.gnu.org


libustr testing fails because we constant fold the s2 initializer in the
following testcase despite the fact it can be modified by ustr_sc_ensure_owner.

extern void abort (void);

typedef long unsigned int size_t;

struct Ustr
{
  unsigned char data[1];
};

size_t ustr_xi__pow2(int, unsigned char);
int ustr_sized(const struct Ustr *);
int ustr_cmp_fast_buf(const struct Ustr*, const void*,size_t);
const char *ustr_cstr(const struct Ustr *);
int ustr_sc_ensure_owner(struct Ustr **);

extern inline __attribute__ ((__gnu_inline__))
size_t ustr_xi__embed_val_get(const unsigned char *data, size_t len)
{
  size_t ret = 0;

  switch (len)
    {
      case 0: return (-1);

      case 8:
              ret |= (((size_t)data[7]) << 56);
              ret |= (((size_t)data[6]) << 48);
              ret |= (((size_t)data[5]) << 40);
              ret |= (((size_t)data[4]) << 32);

      case 4:
              ret |= (((size_t)data[3]) << 24);
              ret |= (((size_t)data[2]) << 16);
      case 2:
              ret |= (((size_t)data[1]) << 8);
      case 1:
              ret |= (((size_t)data[0]) << 0);

              break;

      default: abort();
    }

  return (ret);
}

extern inline __attribute__ ((__gnu_inline__))
size_t ustr_len(const struct Ustr *s1)
{
  int usized;
  if (!s1->data[0])
    return (0);

  usized = ustr_sized(s1);
  return (ustr_xi__embed_val_get(s1->data + 1 + ustr_xi__pow2(usized,
(s1)->data[0] >> 2),
                                 ustr_xi__pow2(usized, (s1)->data[0])));
}

extern inline __attribute__ ((__gnu_inline__))
int ustr_cmp_fast(const struct Ustr *s1,const struct Ustr*s2)
{
  if (s1 == s2)
    return (0);


  return (ustr_cmp_fast_buf(s1, ustr_cstr(s2), ustr_len(s2)));
}


extern inline __attribute__ ((__gnu_inline__))
int ustr_cmp_eq(const struct Ustr *s1, const struct Ustr *s2)
{ return (!ustr_cmp_fast(s1, s2)); }

static struct Ustr *s2 = ((struct Ustr *) "\x01" "\x02" "s2"
"\0<ii-CONST_EOS-ii>");

int
main()
{
  ustr_sc_ensure_owner(&s2);

  if (!ustr_cmp_eq(s2, ((struct Ustr *) "\x01" "\x0002" "s2"
"\0<ii-CONST_EOS-ii>")))
    abort ();

  return 0;
}

It seems to need the several steps of inlining to reproduce, sofar
I wasn't successfull in making a very simple testcase.  The folding
happens when inlining ustr_cmp_eq to main.


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