On Fri, Jan 22, 2016 at 7:55 PM, H.J. Lu <hongjiu...@intel.com> wrote: > Without the fix for PR 65656, g++ miscompiles __builtin_constant_p in > wi::lrshift in wide-int.h. Add a check with PR 65656 testcase to verify > that C++ __builtin_constant_p works properly. > > Tested on x86-64 with working GCC: > > gcc/auto-host.h:/* #undef HAVE_WORKING_CXX_BUILTIN_CONSTANT_P */ > prev-gcc/auto-host.h:/* #undef HAVE_WORKING_CXX_BUILTIN_CONSTANT_P */ > stage1-gcc/auto-host.h:#define HAVE_WORKING_CXX_BUILTIN_CONSTANT_P 1 > > and broken GCC: > > gcc/auto-host.h:/* #undef HAVE_WORKING_CXX_BUILTIN_CONSTANT_P */ > prev-gcc/auto-host.h:/* #undef HAVE_WORKING_CXX_BUILTIN_CONSTANT_P */ > stage1-gcc/auto-host.h:/* #undef HAVE_WORKING_CXX_BUILTIN_CONSTANT_P */ > > Ok for trunk?
I have a hard time seeing how we are "miscompiling" if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT) ? xi.len == 1 && xi.val[0] >= 0 : xi.precision <= HOST_BITS_PER_WIDE_INT) anything that relies on __builtin_constant_p () for sematics is fishy so why is this not simply an lrshfit implementation bug? Richard. > Thanks. > > H.J. > --- > gcc/ > > PR c++/69399 > * configure.ac: Check if C++ __builtin_constant_p works > properly. > (HAVE_WORKING_CXX_BUILTIN_CONSTANT_P): AC_DEFINE. > * system.h (STATIC_CONSTANT_P): Use __builtin_constant_p only > if HAVE_WORKING_CXX_BUILTIN_CONSTANT_P is defined. > * config.in: Regenerated. > * configure: Likewise. > > gcc/testsuite/ > > PR c++/69399 > * gcc.dg/torture/pr69399.c: New test. > --- > gcc/config.in | 10 ++++++++- > gcc/configure | 41 > ++++++++++++++++++++++++++++++++-- > gcc/configure.ac | 27 ++++++++++++++++++++++ > gcc/system.h | 2 +- > gcc/testsuite/gcc.dg/torture/pr69399.c | 21 +++++++++++++++++ > 5 files changed, 97 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr69399.c > > diff --git a/gcc/config.in b/gcc/config.in > index 1796e1d..11ebf5c 100644 > --- a/gcc/config.in > +++ b/gcc/config.in > @@ -1846,6 +1846,13 @@ > #endif > > > +/* Define this macro if C++ __builtin_constant_p with constexpr does not > crash > + with a variable. */ > +#ifndef USED_FOR_TARGET > +#undef HAVE_WORKING_CXX_BUILTIN_CONSTANT_P > +#endif > + > + > /* Define to 1 if `fork' works. */ > #ifndef USED_FOR_TARGET > #undef HAVE_WORKING_FORK > @@ -1865,7 +1872,8 @@ > #endif > > > -/* Define if your assembler supports .dwsect 0xB0000 */ > +/* Define if your assembler supports AIX debug frame section label reference. > + */ > #ifndef USED_FOR_TARGET > #undef HAVE_XCOFF_DWARF_EXTRAS > #endif > diff --git a/gcc/configure b/gcc/configure > index ff646e8..2798231 100755 > --- a/gcc/configure > +++ b/gcc/configure > @@ -6534,6 +6534,43 @@ fi > rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext > fi > > +# Check if C++ __builtin_constant_p works properly. Without the fix > +# for PR 65656, g++ miscompiles __builtin_constant_p in wi::lrshift in > +# wide-int.h. Add a check with PR 65656 testcase to verify that C++ > +# __builtin_constant_p works properly. > +if test "$GCC" = yes; then > + saved_CFLAGS="$CFLAGS" > + saved_CXXFLAGS="$CXXFLAGS" > + CFLAGS="$CFLAGS -O -x c++ -std=c++11" > + CXXFLAGS="$CXXFLAGS -O -x c++ -std=c++11" > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX > __builtin_constant_p works with constexpr" >&5 > +$as_echo_n "checking whether $CXX __builtin_constant_p works with > constexpr... " >&6; } > + cat confdefs.h - <<_ACEOF >conftest.$ac_ext > +/* end confdefs.h. */ > + > +int > +foo (int argc) > +{ > + constexpr bool x = __builtin_constant_p(argc); > + return x ? 1 : 0; > +} > + > +_ACEOF > +if ac_fn_cxx_try_compile "$LINENO"; then : > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 > +$as_echo "yes" >&6; } > + > +$as_echo "#define HAVE_WORKING_CXX_BUILTIN_CONSTANT_P 1" >>confdefs.h > + > +else > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 > +$as_echo "no" >&6; } > +fi > +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext > + CFLAGS="$saved_CFLAGS" > + CXXFLAGS="$saved_CXXFLAGS" > +fi > + > # Check whether compiler is affected by placement new aliasing bug (PR > 29286). > # If the host compiler is affected by the bug, and we build with optimization > # enabled (which happens e.g. when cross-compiling), the pool allocator may > @@ -18419,7 +18456,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 18422 "configure" > +#line 18459 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -18525,7 +18562,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 18528 "configure" > +#line 18565 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > diff --git a/gcc/configure.ac b/gcc/configure.ac > index 4dc7c10..9791a96 100644 > --- a/gcc/configure.ac > +++ b/gcc/configure.ac > @@ -416,6 +416,33 @@ struct X<long long> { typedef long long t; }; > ]], [[X<int64_t>::t x;]])],[],[AC_MSG_ERROR([error verifying int64_t uses > long long])]) > fi > > +# Check if C++ __builtin_constant_p works properly. Without the fix > +# for PR 65656, g++ miscompiles __builtin_constant_p in wi::lrshift in > +# wide-int.h. Add a check with PR 65656 testcase to verify that C++ > +# __builtin_constant_p works properly. > +if test "$GCC" = yes; then > + saved_CFLAGS="$CFLAGS" > + saved_CXXFLAGS="$CXXFLAGS" > + CFLAGS="$CFLAGS -O -x c++ -std=c++11" > + CXXFLAGS="$CXXFLAGS -O -x c++ -std=c++11" > + AC_MSG_CHECKING(whether $CXX __builtin_constant_p works with constexpr) > + AC_COMPILE_IFELSE([ > +int > +foo (int argc) > +{ > + constexpr bool x = __builtin_constant_p(argc); > + return x ? 1 : 0; > +} > +], > + [AC_MSG_RESULT([yes]) > + AC_DEFINE(HAVE_WORKING_CXX_BUILTIN_CONSTANT_P, 1, > +[Define this macro if C++ __builtin_constant_p with constexpr does not > + crash with a variable.])], > + [AC_MSG_RESULT([no])]) > + CFLAGS="$saved_CFLAGS" > + CXXFLAGS="$saved_CXXFLAGS" > +fi > + > # Check whether compiler is affected by placement new aliasing bug (PR > 29286). > # If the host compiler is affected by the bug, and we build with optimization > # enabled (which happens e.g. when cross-compiling), the pool allocator may > diff --git a/gcc/system.h b/gcc/system.h > index ba2e963..e57787b 100644 > --- a/gcc/system.h > +++ b/gcc/system.h > @@ -729,7 +729,7 @@ extern void fancy_abort (const char *, int, const char *) > ATTRIBUTE_NORETURN; > #define gcc_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__)) > #endif > > -#if GCC_VERSION >= 3001 > +#if GCC_VERSION >= 3001 && defined HAVE_WORKING_CXX_BUILTIN_CONSTANT_P > #define STATIC_CONSTANT_P(X) (__builtin_constant_p (X) && (X)) > #else > #define STATIC_CONSTANT_P(X) (false && (X)) > diff --git a/gcc/testsuite/gcc.dg/torture/pr69399.c > b/gcc/testsuite/gcc.dg/torture/pr69399.c > new file mode 100644 > index 0000000..3e17169 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr69399.c > @@ -0,0 +1,21 @@ > +/* { dg-do run { target int128 } } */ > + > +typedef __UINT64_TYPE__ u64; > +typedef unsigned __int128 u128; > + > +static unsigned __attribute__((noinline, noclone)) > +foo(u64 u) > +{ > + u128 v = u | 0xffffff81; > + v >>= 64; > + return v; > +} > + > +int > +main() > +{ > + unsigned x = foo(27); > + if (x != 0) > + __builtin_abort(); > + return 0; > +} > -- > 2.5.0 >