This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/49079] New: [4.6/4.7 Regression] Bogus constant folding
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 20 May 2011 12:31:03 +0000
- Subject: [Bug tree-optimization/49079] New: [4.6/4.7 Regression] Bogus constant folding
- Auto-submitted: auto-generated
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.