Message ID | 20101124230038.GA23379@intel.com |
---|---|
State | New |
Headers | show |
On Thu, Nov 25, 2010 at 12:00 AM, H.J. Lu <hongjiu.lu@intel.com> wrote: > target_char_cast doesn't properly hanle cast integer constant, whose > highest bit is set, to char. When an integer constant is casted to char, > we only care about lower bits. This patch fixes it. OK for trunk if it > passes bootstrap on Linux/x86-64 with 32bit/64bit tests? Ok. Thanks, Richard. > Thanks. > > > H.J. > --- > gcc/ > > 2010-11-24 H.J. Lu <hongjiu.lu@intel.com> > > PR middle-end/46647 > * builtins.c (target_char_cast): Check INTEGER_CST instead of > host_integerp. Replace tree_low_cst with TREE_INT_CST_LOW. > > gcc/testsuite/ > > 2010-11-24 H.J. Lu <hongjiu.lu@intel.com> > > PR middle-end/46647 > * gcc.target/i386/pr46647.c: New. > > diff --git a/gcc/builtins.c b/gcc/builtins.c > index c9e8e68..a90bf2f 100644 > --- a/gcc/builtins.c > +++ b/gcc/builtins.c > @@ -630,11 +630,11 @@ target_char_cast (tree cst, char *p) > { > unsigned HOST_WIDE_INT val, hostval; > > - if (!host_integerp (cst, 1) > + if (TREE_CODE (cst) != INTEGER_CST > || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT) > return 1; > > - val = tree_low_cst (cst, 1); > + val = TREE_INT_CST_LOW (cst); > if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT) > val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1; > > --- /dev/null 2010-11-15 09:06:16.517000001 -0800 > +++ gcc/gcc/testsuite/gcc.target/i386/pr46647.c 2010-11-24 14:17:04.885208046 -0800 > @@ -0,0 +1,44 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mtune=generic" } */ > + > +char a[5]; > +int > +func1 (void) > +{ > + __builtin_memset (a,-1,sizeof (a)); > + return 0; > +} > + > +int a2[5]; > +int > +func2 (void) > +{ > + __builtin_memset (a2,-1,sizeof (a2)); > + return 0; > +} > + > +char a3[5]; > +int > +func3 (void) > +{ > + __builtin_memset (a3,0x8fffffff,sizeof (a3)); > + return 0; > +} > + > +char a4[5]; > +int > +func4 (void) > +{ > + __builtin_memset (a4,0x8fffff00,sizeof (a4)); > + return 0; > +} > + > +int a5[5]; > +int > +func5 (void) > +{ > + __builtin_memset (a5,0x8fffffff,sizeof (a5)); > + return 0; > +} > + > +/* { dg-final { scan-assembler-not "call\[\\t \]*_?memset" } } */ >
diff --git a/gcc/builtins.c b/gcc/builtins.c index c9e8e68..a90bf2f 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -630,11 +630,11 @@ target_char_cast (tree cst, char *p) { unsigned HOST_WIDE_INT val, hostval; - if (!host_integerp (cst, 1) + if (TREE_CODE (cst) != INTEGER_CST || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT) return 1; - val = tree_low_cst (cst, 1); + val = TREE_INT_CST_LOW (cst); if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT) val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1; --- /dev/null 2010-11-15 09:06:16.517000001 -0800 +++ gcc/gcc/testsuite/gcc.target/i386/pr46647.c 2010-11-24 14:17:04.885208046 -0800 @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ + +char a[5]; +int +func1 (void) +{ + __builtin_memset (a,-1,sizeof (a)); + return 0; +} + +int a2[5]; +int +func2 (void) +{ + __builtin_memset (a2,-1,sizeof (a2)); + return 0; +} + +char a3[5]; +int +func3 (void) +{ + __builtin_memset (a3,0x8fffffff,sizeof (a3)); + return 0; +} + +char a4[5]; +int +func4 (void) +{ + __builtin_memset (a4,0x8fffff00,sizeof (a4)); + return 0; +} + +int a5[5]; +int +func5 (void) +{ + __builtin_memset (a5,0x8fffffff,sizeof (a5)); + return 0; +} + +/* { dg-final { scan-assembler-not "call\[\\t \]*_?memset" } } */