From f8e8f7ae14523db3b58c104098125e7bccb626fa Mon Sep 17 00:00:00 2001 From: Sayan Date: Tue, 27 Oct 2026 16:18:49 -0400 Subject: [PATCH] Use a single-alternative operand for the PowerPC long double force_rounding --- .../numeric/interval/detail/ppc_rounding_control.hpp | 11 +++++++---- test/rounding_mode.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/boost/numeric/interval/detail/ppc_rounding_control.hpp b/include/boost/numeric/interval/detail/ppc_rounding_control.hpp index 670e456..f7e6781 100644 --- a/include/boost/numeric/interval/detail/ppc_rounding_control.hpp +++ b/include/boost/numeric/interval/detail/ppc_rounding_control.hpp @@ -103,11 +103,14 @@ struct rounding_control: #if __SIZEOF_LONG_DOUBLE__ == 8 // Same format as double. __asm__ __volatile__ ("" : "+d"(r_)); +#elif defined(__clang__) + // Clang has no register constraint that works for both 128-bit ABIs. + __asm__ __volatile__ ("" : "+m"(r_)); #else - // Which register can hold a 128-bit long double depends on the ABI: FPRs - // for IBM double-double, a VSX register for IEEE 128-bit. Clang accepts - // neither in all cases, hence the memory fallback. - __asm__ __volatile__ ("" : "+wa,d,m"(r_)); + // FPRs for IBM double-double, a VSX register for IEEE 128-bit. A single + // alternative, as GCC rejects a "+" operand with several when the value + // is a constant. + __asm__ __volatile__ ("" : "+wadm"(r_)); #endif return r_; } diff --git a/test/rounding_mode.cpp b/test/rounding_mode.cpp index 5a9d701..40e3704 100644 --- a/test/rounding_mode.cpp +++ b/test/rounding_mode.cpp @@ -45,9 +45,21 @@ void test() { BOOST_TEST(div_down(one, three) < div_up(one, three)); } +// Exact constants reach force_rounding once the division is folded; GCC +// used to reject the PowerPC long double asm then. +template +void test_constant() { + typedef boost::numeric::interval I; + I q = I(6) / I(2); + BOOST_TEST(q.lower() == 3 && q.upper() == 3); +} + int main() { test(); test(); test(); + test_constant(); + test_constant(); + test_constant(); return boost::report_errors(); }