LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 39696 - Workaround "error: ‘(9.223372036854775807e+18 / 1.0e+9)’ is not a constant expression"
Summary: Workaround "error: ‘(9.223372036854775807e+18 / 1.0e+9)’ is not a constant ex...
Status: RESOLVED FIXED
Alias: None
Product: libc++
Classification: Unclassified
Component: All Bugs (show other bugs)
Version: 7.0
Hardware: Other Linux
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords: build-problem
: 40671 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-11-16 16:56 PST by Jeffrey Walton
Modified: 2020-06-10 10:36 PDT (History)
10 users (show)

See Also:
Fixed By Commit(s):


Attachments
Build clang-8.0.1 on linux shell script. (5.00 KB, application/x-shellscript)
2019-08-18 16:50 PDT, Elvis Dowson
Details
Patch for building llvm-8.0.1 on ppc64el. (718 bytes, patch)
2019-08-18 16:52 PDT, Elvis Dowson
Details
201908190440 clang-8.0.1 build log on ppc64le - power9 (566.27 KB, text/x-log)
2019-08-18 18:31 PDT, Elvis Dowson
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jeffrey Walton 2018-11-16 16:56:18 PST
I'm trying to build LLVM and components on GCC112 from the compiler farm. GCC112 is ppc64-le, and ships with GCC 4.8.5:

$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

LLVM configuration and build goes well for a while. Then it encounters https://bugzilla.redhat.com/show_bug.cgi?id=1538817:

[ 35%] Building CXX object projects/libcxx/lib/CMakeFiles/cxx_objects.dir/__/src/condition_variable.cpp.o
cd /home/noloader/llvm_build/projects/libcxx/lib && /usr/bin/c++  -DNDEBUG -D_DEBUG -D_GNU_SOURCE -D_LIBCPP_BUILDING_LIBRARY -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/noloader/llvm_build/projects/libcxx/lib -I/home/noloader/llvm_source/llvm/projects/libcxx/lib -I/home/noloader/llvm_build/include -I/home/noloader/llvm_source/llvm/include -I/home/noloader/llvm_build/projects/libcxx/include/c++build -I/home/noloader/llvm_source/llvm/projects/libcxx/include  -fPIC -fvisibility-inlines-hidden -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers  -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -g   -DLIBCXX_BUILDING_LIBCXXABI -std=c++11 -nostdinc++ -fvisibility-inlines-hidden -Wall -Wextra -W -Wwrite-strings -Wno-unused-parameter -Wno-long-long -Werror=return-type -Wno-literal-suffix -Wno-c++14-compat -Wno-noexcept-type -Wno-error -fPIC -o CMakeFiles/cxx_objects.dir/__/src/condition_variable.cpp.o -c /home/noloader/llvm_source/llvm/projects/libcxx/src/condition_variable.cpp
In file included from /home/noloader/llvm_source/llvm/projects/libcxx/src/condition_variable.cpp:15:0:
/home/noloader/llvm_source/llvm/projects/libcxx/include/thread: In function ‘void std::__1::this_thread::sleep_for(const std::__1::chrono::duration<_Rep, _Period>&)’:
/home/noloader/llvm_source/llvm/projects/libcxx/include/thread:438:73:   in constexpr expansion of ‘std::__1::chrono::duration<long double>((*(const std::__1::chrono::duration<long long int, std::__1::ratio<1l, 1000000000l> >*)(& std::__1::chrono::duration<_Rep, _Period>::max<long long int, std::__1::ratio<1l, 1000000000l> >())), 0u)’
/home/noloader/llvm_source/llvm/projects/libcxx/include/chrono:1055:68:   in constexpr expansion of ‘std::__1::chrono::duration_cast<std::__1::chrono::duration<long double>, long long int, std::__1::ratio<1l, 1000000000l> >((* & __d))’
/home/noloader/llvm_source/llvm/projects/libcxx/include/chrono:907:72:   in constexpr expansion of ‘std::__1::chrono::__duration_cast<std::__1::chrono::duration<long long int, std::__1::ratio<1l, 1000000000l> >, std::__1::chrono::duration<long double>, std::__1::ratio<1l, 1000000000l>, true, false>().std::__1::chrono::__duration_cast<_FromDuration, _ToDuration, _Period, true, false>::operator()<std::__1::chrono::duration<long long int, std::__1::ratio<1l, 1000000000l> >, std::__1::chrono::duration<long double>, std::__1::ratio<1l, 1000000000l> >((* & __fd))’
/home/noloader/llvm_source/llvm/projects/libcxx/include/thread:438:73: error: ‘(9.223372036854775807e+18 / 1.0e+9)’ is not a constant expression
         _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
                                                                         ^
At global scope:
cc1plus: warning: unrecognized command line option "-Wno-noexcept-type" [enabled by default]
cc1plus: warning: unrecognized command line option "-Wno-c++14-compat" [enabledby default]
make[2]: *** [projects/libcxx/lib/CMakeFiles/cxx_objects.dir/__/src/condition_variable.cpp.o] Error 1
make[2]: Leaving directory `/home/noloader/llvm_build'
make[1]: *** [projects/libcxx/lib/CMakeFiles/cxx_objects.dir/all] Error 2
make[1]: Leaving directory `/home/noloader/llvm_build'
make: *** [all] Error 2
Failed to make LLVM sources

It would be nice if LLVM could work around the issue.
Comment 1 Marshall Clow (home) 2018-11-19 16:19:53 PST
The code is like it is because of https://bugs.llvm.org/show_bug.cgi?id=13721; so read that before attempting a fix.
Comment 2 Ken Cunningham 2018-12-20 22:53:00 PST
This worked for me to fix this. It is quite a minor change. 

<https://gist.githubusercontent.com/iains/3b2e074d65263cd4be456c36839823d1/raw/5fdd16b2284d0bfd5d628333b80eeb49b8cbbe43/gistfile1.txt>
Comment 3 Marshall Clow (home) 2019-02-08 21:11:22 PST
*** Bug 40671 has been marked as a duplicate of this bug. ***
Comment 4 Itaru Kitayama 2019-02-08 23:26:13 PST
Is the proper fix being worked on?
I’d like a heads-up so I got pull from
llvm-project repo.
Comment 5 Marshall Clow (home) 2019-02-09 06:59:32 PST
The "proper fix" is for GCC to fix their PPC floating point codegen, because '(9.223372036854775807e+18 / 1.0e+9)' certainly *is* a constant expression.
Comment 6 Itaru Kitayama 2019-02-09 13:56:02 PST
So we either use the latest GCC version which has the fix or we apply the patch on
the GCC of preference? In my environment using GCC 7.2.0 seems to be required by the CUDA toolkit.
Comment 7 Eric Fiselier 2019-02-09 17:47:54 PST
Here's a minimal reproducer on godbolt: https://godbolt.org/z/xFkZTR

What confuses me is that the same expression that breaks with `long double` works with `double` and `float.
Comment 8 Eric Fiselier 2019-02-09 17:53:19 PST
Also see:
https://bugzilla.redhat.com/show_bug.cgi?id=1538817
Comment 9 Ken Cunningham 2019-02-10 08:58:54 PST
Here's my understanding:

It's a very old deficiency in gcc's handling of a unique IBM format for long long floating point values.

<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26374>

A patch years ago was put it to indicate this type of folding could not be done:

<https://gcc.gnu.org/ml/gcc-patches/2005-01/msg01966.html>

And that code is more or less still in gcc8 in fold-const.c

      /* Don't constant fold this floating point operation if the
	 result may dependent upon the run-time rounding mode and
	 flag_rounding_math is set, or if GCC's software emulation
	 is unable to accurately represent the result.  */
      if ((flag_rounding_math
	   || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
	  && (inexact || !real_identical (&result, &value)))
	return NULL_TREE;


There is some work being done to change things for PPCLE but not for PPCBE:

<https://fedoraproject.org/wiki/Changes/PPC64LE_Float128_Transition>


There is nobody I know of who knows more about gcc and PowerPC than Iain Sandoe, and his workaround was in the patch I referenced above.
Comment 10 Jeffrey Walton 2019-02-10 09:31:50 PST
For what it is worth I patch-out the constexpr part (https://github.com/noloader/build-llvm/blob/master/build-llvm.sh#L566):

THIS_FILE=include/thread
sed -i "s/_LIBCPP_CONSTEXPR duration<long double> _Max/const duration<long double> _Max/g" "$THIS_FILE" > "$THIS_FILE.patched"
mv "$THIS_FILE.patched" "$THIS_FILE"

I patch it out because my two choices are (1) broken compile an no compiler, or (2) lose constexpr on a function I probably won't use. The value still works, its just not constexpr.

Patching-out the constexpr is a no brainer for me because I need a working compiler.
Comment 11 Ken Cunningham 2019-02-10 09:40:22 PST
The way I understand Iain's patch, it changes the thread to sleep from thousands of years to just hundreds of years.

:>
Comment 12 Eric Fiselier 2019-02-10 10:14:16 PST
I'm wondering if replacing `long double` with `double` isn't the better fix here.
std::chrono::nanoseconds::max() should be representable as a double.


My understanding is that the GCC bug is only triggered when using the IBM long double ABI, and that other long double ABI's are available. Is these a GCC macro we can use to detect IBM's long double specifically?
Comment 13 Eric Fiselier 2019-02-10 10:14:16 PST
I'm wondering if replacing `long double` with `double` isn't the better fix here.
std::chrono::nanoseconds::max() should be representable as a double.


My understanding is that the GCC bug is only triggered when using the IBM long double ABI, and that other long double ABI's are available. Is these a GCC macro we can use to detect IBM's long double specifically?
Comment 14 Ken Cunningham 2019-02-10 11:58:11 PST
As far as I can tell from <https://github.com/llvm-mirror/libcxx/blob/master/src/condition_variable.cpp#L56> whatever superlong number we pass in here gets shortened down to "0x59682F000000E941" anyway.

So Iain's 592 years is long enough to saturate the system.
Comment 15 Itaru Kitayama 2019-02-13 12:54:12 PST
Am I correct this doesn’t happen when building LLVM
with self bootstrapped LLVM?
Comment 16 Marshall Clow (home) 2019-02-13 14:22:04 PST
(In reply to Itaru Kitayama from comment #15)
> Am I correct this doesn’t happen when building LLVM
> with self bootstrapped LLVM?

That is my understanding. Building with LLVM is fine.
Also note that this is not "building LLVM", but building libc++.
Comment 17 Itaru Kitayama 2019-02-13 16:10:38 PST
By fully bootstrapped LLVM, it means that the linker also needs to be
lld, not ld nor gold?

(In reply to Marshall Clow (home) from comment #16)
> (In reply to Itaru Kitayama from comment #15)
> > Am I correct this doesn’t happen when building LLVM
> > with self bootstrapped LLVM?
> 
> That is my understanding. Building with LLVM is fine.
> Also note that this is not "building LLVM", but building libc++.
Comment 18 Marshall Clow (home) 2019-02-13 16:49:10 PST
(In reply to Itaru Kitayama from comment #17)
> By fully bootstrapped LLVM, it means that the linker also needs to be
> lld, not ld nor gold?

This is a compile-time error; it hasn't gotten to the linker yet.
Comment 19 Ken Cunningham 2019-02-17 09:22:01 PST
A similar issue recently came up in gcc’s bug tracker <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88204> on their test suite, and the resolution was to disable the test. 

After 14 years, it would not seem very likely that gcc is going to fix this any time soon.

Although it is undesirable to have one system working differently than all the others, for bootstrapping libc++ with gcc on powerpc there would not appear to be a lot of other available options than a patch something like Iain’s. 

Is there something about that patch (other than the systems test, which needs to be broadened out a bit) that I am missing that makes it unusable?
Comment 20 Marshall Clow (home) 2019-04-02 07:46:53 PDT
Fixed in r357478.
Comment 21 Itaru Kitayama 2019-04-02 16:15:56 PDT
(In reply to Marshall Clow (home) from comment #20)
> Fixed in r357478.

I don't see the Fix is in the llvm-project repo on GitHub, should I try
the svn in the meantime?
Comment 22 Marshall Clow (home) 2019-04-02 17:04:17 PDT
And fixed correctly in https://llvm.org/r357540
Comment 23 Itaru Kitayama 2019-04-02 17:58:25 PDT
(In reply to Marshall Clow (home) from comment #22)
> And fixed correctly in https://llvm.org/r357540

On ppc64le, the code base which has the Fix doen's get build:

$ cmake -G Ninja -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=TRUE -DCMAKE_C_COMPILER=/gpfs/software/opt/gcc/5.4.0/bin/gcc -DCMAKE_CXX_COMPILER=/gpfs/software/opt/gcc/5.4.0/bin/g++ ../llvm
Comment 24 Itaru Kitayama 2019-04-02 22:34:43 PDT
BTW, it builds fine on x86.
Comment 25 Ken Cunningham 2019-07-08 18:27:02 PDT
I must be cross-eyed.

To me the original commit looks correct, and the corrected fix now looks backwards.

When building with gcc, on powerpc, don't we want to use 

 _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;


Because if so, we have that backwards now, don't we?
Comment 26 Elvis Dowson 2019-08-18 11:09:11 PDT
This is the correct patch for ppc64el. I've tested this on a Raptor System Talos II Power9 workstation.

diff --git a/libcxx/include/thread b/libcxx/include/thread
index 8c0115f87..e439f60b9 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -435,7 +435,12 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
     using namespace chrono;
     if (__d > duration<_Rep, _Period>::zero())
     {
+#if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
+        //  GCC's long double const folding is incomplete for IBM128 long doubles.
+        _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL);
+#else
         _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+#endif
         nanoseconds __ns;
         if (__d < _Max)
         {
Comment 27 Itaru Kitayama 2019-08-18 13:44:01 PDT
Has this been landed on Trunk yet?
Comment 28 Itaru Kitayama 2019-08-18 14:14:11 PDT
And note that C++14 now that is a requirement.
Comment 29 Itaru Kitayama 2019-08-18 15:44:48 PDT
I confirm that I am able to build one of the LLVM projects, libcxx and libcxxabi on PowerPC natively for the first time ever. Time for changing the doc to Supported on Linux and PowerPC combination?
Comment 30 Elvis Dowson 2019-08-18 16:50:52 PDT
Created attachment 22388 [details]
Build clang-8.0.1 on linux shell script.

Test on IBM Power9 Ubuntu-18.04 for ppc64le.
Comment 31 Elvis Dowson 2019-08-18 16:52:55 PDT
Created attachment 22389 [details]
Patch for building llvm-8.0.1 on ppc64el.
Comment 32 Elvis Dowson 2019-08-18 16:54:13 PDT
I've attached a shell script for building clang-8.0.1 on linux. It's been test on a Power9 ppc64le system.
Comment 33 Itaru Kitayama 2019-08-18 16:54:29 PDT
(In reply to Elvis Dowson from comment #30)
> Created attachment 22388 [details]
> Build clang-8.0.1 on linux shell script.
> 
> Test on IBM Power9 Ubuntu-18.04 for ppc64le.

Do you have build logs carried out on POWER9?
Comment 34 Elvis Dowson 2019-08-18 17:48:38 PDT
I'll rebuild it again and attach the logs in an hour or so. What do you hope to see in the logs?
Comment 35 Itaru Kitayama 2019-08-18 17:52:13 PDT
I'd like to see the nightly build logs as I am on POWER8 and do build LLVM routinely by myself, when failture occurs I'd like to cross-check against it.
Comment 36 Elvis Dowson 2019-08-18 18:31:47 PDT
Created attachment 22390 [details]
201908190440 clang-8.0.1 build log on ppc64le - power9

I've attached the build log. I deleted the install messages, since I can only post attachments upto 1MB here.
Comment 37 Dan Lipsa 2019-08-20 07:59:43 PDT
I can confirm that as of now (SHA cda334ba5417d7702be755adc2f8414c877f0482) this fix is still reversed on master. Adding a NOT for the if condition (or switching the bodies for if and else) would fix it
Comment 38 Galen Shipman 2019-12-04 10:34:38 PST
I can also confirm that this is an issue in current master / trunk (llvm 10) 
Here is my patch which I have incorporated in an spack package. 
diff --git a/libcxx/include/thread b/libcxx/include/thread
index 02da703..d1677a1 100644
--- a/projects/libcxx/include/thread
+++ b/projects/libcxx/include/thread
@@ -368,9 +368,9 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
     {
 #if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
     //  GCC's long double const folding is incomplete for IBM128 long doubles.
-        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
-#else
         _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
+#else
+        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
 #endif
         nanoseconds __ns;
         if (__d < _Max)
Comment 39 Joel E. Denny 2020-04-10 11:02:21 PDT
We have recently encountered this bug and have found that the patch in https://bugs.llvm.org/show_bug.cgi?id=39696#c38 fixes it.  What stands in the way of this being pushed?  Would it help if I created a phab review for it?
Comment 40 Joel E. Denny 2020-04-20 06:15:07 PDT
(In reply to Joel E. Denny from comment #39)
> We have recently encountered this bug and have found that the patch in
> https://bugs.llvm.org/show_bug.cgi?id=39696#c38 fixes it.  What stands in
> the way of this being pushed?  Would it help if I created a phab review for
> it?

Ping.
Comment 41 Joel E. Denny 2020-04-28 06:40:16 PDT
Ping.  What's the best way to move this forward?
Comment 42 Joel E. Denny 2020-05-04 10:40:32 PDT
Ping.I suppose I should just take the patch to phabricator.
Comment 43 Joel E. Denny 2020-06-10 10:36:53 PDT
Fixed: https://reviews.llvm.org/D81438