From 55a1546b73b60d2601f35671ba9e8f12a52a7b77 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 25 Jun 2021 09:20:56 +0200 Subject: tree-optimization/101202 - fix ICE with failed backedge SLP nodes This fixes an ICE with failed backedge SLP nodes still in the graph while doing permute optimization by explicitely handling those. 2021-06-25 Richard Biener PR tree-optimization/101202 * tree-vect-slp.c (vect_optimize_slp): Explicitely handle failed nodes. * gcc.dg/torture/pr101202.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr101202.c | 33 ++++++++++++++++++++++ gcc/tree-vect-slp.c | 49 +++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101202.c diff --git a/gcc/testsuite/gcc.dg/torture/pr101202.c b/gcc/testsuite/gcc.dg/torture/pr101202.c new file mode 100644 index 0000000..e76c908 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101202.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +int printf(const char *, ...); +unsigned a, b, d; +int c, e, f; +int main() +{ + while (a) + if (b) + { + f = a; + while (e) + { + int h, i; + if (d) + { + h = a; + i = d; +L: + d = a | d && c; + if (a) + { + printf("%d", a); + goto L; + } + } + a = h; + d = i; + } + } + return 0; +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 227d6aa..17fe5f2 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -3689,26 +3689,33 @@ vect_optimize_slp (vec_info *vinfo) vertices[idx].visited = 1; - /* We do not handle stores with a permutation. */ - stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node); - if (STMT_VINFO_DATA_REF (rep) - && DR_IS_WRITE (STMT_VINFO_DATA_REF (rep))) - continue; - /* We cannot move a permute across an operation that is - not independent on lanes. Note this is an explicit - negative list since that's much shorter than the respective - positive one but it's critical to keep maintaining it. */ - if (is_gimple_call (STMT_VINFO_STMT (rep))) - switch (gimple_call_combined_fn (STMT_VINFO_STMT (rep))) - { - case CFN_COMPLEX_ADD_ROT90: - case CFN_COMPLEX_ADD_ROT270: - case CFN_COMPLEX_MUL: - case CFN_COMPLEX_MUL_CONJ: - case CFN_VEC_ADDSUB: + /* We still eventually have failed backedge SLP nodes in the + graph, those are only cancelled when analyzing operations. + Simply treat them as transparent ops, propagating permutes + through them. */ + if (SLP_TREE_DEF_TYPE (node) == vect_internal_def) + { + /* We do not handle stores with a permutation. */ + stmt_vec_info rep = SLP_TREE_REPRESENTATIVE (node); + if (STMT_VINFO_DATA_REF (rep) + && DR_IS_WRITE (STMT_VINFO_DATA_REF (rep))) continue; - default:; - } + /* We cannot move a permute across an operation that is + not independent on lanes. Note this is an explicit + negative list since that's much shorter than the respective + positive one but it's critical to keep maintaining it. */ + if (is_gimple_call (STMT_VINFO_STMT (rep))) + switch (gimple_call_combined_fn (STMT_VINFO_STMT (rep))) + { + case CFN_COMPLEX_ADD_ROT90: + case CFN_COMPLEX_ADD_ROT270: + case CFN_COMPLEX_MUL: + case CFN_COMPLEX_MUL_CONJ: + case CFN_VEC_ADDSUB: + continue; + default:; + } + } int perm = -1; for (graph_edge *succ = slpg->vertices[idx].succ; @@ -3812,7 +3819,9 @@ vect_optimize_slp (vec_info *vinfo) slp_tree child; FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) { - if (!child || SLP_TREE_DEF_TYPE (child) == vect_internal_def) + if (!child + || (SLP_TREE_DEF_TYPE (child) != vect_constant_def + && SLP_TREE_DEF_TYPE (child) != vect_external_def)) continue; /* If the vector is uniform there's nothing to do. */ -- cgit v1.1 From 3a50aed09edc5e69080a0e49851acdb874227256 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 25 Jun 2021 09:22:28 -0400 Subject: Use right shifts to eliminate redundant test/compare insns on the H8 gcc/ * config/h8300/h8300.c (select_cc_mode): Handle ASHIFTRT and LSHIFTRT. --- gcc/config/h8300/h8300.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 511c2b2..d8b4bfc 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1947,9 +1947,10 @@ h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1) if (op1 == const0_rtx && (cond == EQ || cond == NE || cond == LT || cond == GE) && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS - || GET_CODE (op0) == NEG || GET_CODE (op0) == AND - || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR - || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT + || GET_CODE (op0) == NEG || GET_CODE (op0) == AND + || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR + || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT + || GET_CODE (op0) == ASHIFTRT || GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == MULT || GET_CODE (op0) == SYMBOL_REF || GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND || REG_P (op0) || MEM_P (op0))) -- cgit v1.1 From 3c3474679419707710a899a03151cbe79a91c360 Mon Sep 17 00:00:00 2001 From: Matthias Kretz Date: Fri, 25 Jun 2021 14:40:26 +0200 Subject: MAINTAINERS: Add myself for write after approval and DCO Signed-off-by: Matthias Kretz ChangeLog: * MAINTAINERS: Add myself for write after approval and DCO --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b4c50a9..aac08e6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -474,6 +474,7 @@ Dave Korn Julia Koval Matt Kraai Jan Kratochvil +Matthias Kretz Louis Krupp Prathamesh Kulkarni Venkataramanan Kumar @@ -697,5 +698,6 @@ Certificate of Origin Version 1.1. See https://gcc.gnu.org/dco.html for more information. + Matthias Kretz Jeff Law Jeff Law -- cgit v1.1 From 74ebd1297e9cfa9f7d05bfcac5510d4968cc6ba8 Mon Sep 17 00:00:00 2001 From: Matthias Kretz Date: Thu, 28 Jan 2021 21:04:03 +0100 Subject: libstdc++: Make use of __builtin_bit_cast for simd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The __bit_cast function was a hack to achieve what __builtin_bit_cast can do, therefore use __builtin_bit_cast if possible. However, __builtin_bit_cast cannot be used to cast from/to fixed_size_simd, since it isn't trivially copyable (in the language sense — in principle it is). Therefore add __proposed::simd_bit_cast to enable the use case required in the test framework. Signed-off-by: Matthias Kretz libstdc++-v3/ChangeLog: * include/experimental/bits/simd.h (__bit_cast): Implement via __builtin_bit_cast #if available. (__proposed::simd_bit_cast): Add overloads for simd and simd_mask, which use __builtin_bit_cast (or __bit_cast #if not available), which return an object of the requested type with the same bits as the argument. * include/experimental/bits/simd_math.h: Use simd_bit_cast instead of __bit_cast to allow casts to fixed_size_simd. (copysign): Remove branch that was only required if __bit_cast cannot be constexpr. * testsuite/experimental/simd/tests/bits/test_values.h: Switch from __bit_cast to __proposed::simd_bit_cast since the former will not cast fixed_size objects anymore. --- libstdc++-v3/include/experimental/bits/simd.h | 57 +++++++++++++++++++++- libstdc++-v3/include/experimental/bits/simd_math.h | 37 ++++++-------- .../experimental/simd/tests/bits/test_values.h | 8 +-- 3 files changed, 76 insertions(+), 26 deletions(-) diff --git a/libstdc++-v3/include/experimental/bits/simd.h b/libstdc++-v3/include/experimental/bits/simd.h index c396ebd..ed2645b 100644 --- a/libstdc++-v3/include/experimental/bits/simd.h +++ b/libstdc++-v3/include/experimental/bits/simd.h @@ -1602,7 +1602,9 @@ template _GLIBCXX_SIMD_INTRINSIC constexpr _To __bit_cast(const _From __x) { - // TODO: implement with / replace by __builtin_bit_cast ASAP +#if __has_builtin(__builtin_bit_cast) + return __builtin_bit_cast(_To, __x); +#else static_assert(sizeof(_To) == sizeof(_From)); constexpr bool __to_is_vectorizable = is_arithmetic_v<_To> || is_enum_v<_To>; @@ -1633,6 +1635,7 @@ template reinterpret_cast(&__x), sizeof(_To)); return __r; } +#endif } // }}} @@ -2904,6 +2907,58 @@ template (__x)}; } + +template + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR + _To + simd_bit_cast(const simd<_Up, _Abi>& __x) + { + using _Tp = typename _To::value_type; + using _ToMember = typename _SimdTraits<_Tp, typename _To::abi_type>::_SimdMember; + using _From = simd<_Up, _Abi>; + using _FromMember = typename _SimdTraits<_Up, _Abi>::_SimdMember; + // with concepts, the following should be constraints + static_assert(sizeof(_To) == sizeof(_From)); + static_assert(is_trivially_copyable_v<_Tp> && is_trivially_copyable_v<_Up>); + static_assert(is_trivially_copyable_v<_ToMember> && is_trivially_copyable_v<_FromMember>); +#if __has_builtin(__builtin_bit_cast) + return {__private_init, __builtin_bit_cast(_ToMember, __data(__x))}; +#else + return {__private_init, __bit_cast<_ToMember>(__data(__x))}; +#endif + } + +template + _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_SIMD_CONSTEXPR + _To + simd_bit_cast(const simd_mask<_Up, _Abi>& __x) + { + using _From = simd_mask<_Up, _Abi>; + static_assert(sizeof(_To) == sizeof(_From)); + static_assert(is_trivially_copyable_v<_From>); + // _To can be simd, specifically simd> in which case _To is not trivially + // copyable. + if constexpr (is_simd_v<_To>) + { + using _Tp = typename _To::value_type; + using _ToMember = typename _SimdTraits<_Tp, typename _To::abi_type>::_SimdMember; + static_assert(is_trivially_copyable_v<_ToMember>); +#if __has_builtin(__builtin_bit_cast) + return {__private_init, __builtin_bit_cast(_ToMember, __x)}; +#else + return {__private_init, __bit_cast<_ToMember>(__x)}; +#endif + } + else + { + static_assert(is_trivially_copyable_v<_To>); +#if __has_builtin(__builtin_bit_cast) + return __builtin_bit_cast(_To, __x); +#else + return __bit_cast<_To>(__x); +#endif + } + } } // namespace __proposed // simd_cast {{{2 diff --git a/libstdc++-v3/include/experimental/bits/simd_math.h b/libstdc++-v3/include/experimental/bits/simd_math.h index dd9aaa3..c81ad7c 100644 --- a/libstdc++-v3/include/experimental/bits/simd_math.h +++ b/libstdc++-v3/include/experimental/bits/simd_math.h @@ -405,10 +405,11 @@ template using _Vp = simd<_Tp, _Abi>; using _Up = make_unsigned_t<__int_for_sizeof_t<_Tp>>; using namespace std::experimental::__float_bitwise_operators; + using namespace std::experimental::__proposed; const _Vp __exponent_mask = __infinity_v<_Tp>; // 0x7f800000 or 0x7ff0000000000000 return static_simd_cast>( - __bit_cast>(__v & __exponent_mask) + simd_bit_cast>(__v & __exponent_mask) >> (__digits_v<_Tp> - 1)); } @@ -697,11 +698,9 @@ template // (inf and NaN are excluded by -ffinite-math-only) const auto __iszero_inf_nan = __x == 0; #else - const auto __as_int - = __bit_cast, _V>>(abs(__x)); - const auto __inf - = __bit_cast, _V>>( - _V(__infinity_v<_Tp>)); + using _Ip = __int_for_sizeof_t<_Tp>; + const auto __as_int = simd_bit_cast>(abs(__x)); + const auto __inf = simd_bit_cast>(_V(__infinity_v<_Tp>)); const auto __iszero_inf_nan = static_simd_cast( __as_int == 0 || __as_int >= __inf); #endif @@ -719,10 +718,10 @@ template where(__value_isnormal.__cvt(), __e) = __exponent_bits; static_assert(sizeof(_IV) == sizeof(__value_isnormal)); const _IV __offset - = (__bit_cast<_IV>(__value_isnormal) & _IV(__exp_adjust)) - | (__bit_cast<_IV>(static_simd_cast<_MaskType>(__exponent_bits == 0) - & static_simd_cast<_MaskType>(__x != 0)) - & _IV(__exp_adjust + __exp_offset)); + = (simd_bit_cast<_IV>(__value_isnormal) & _IV(__exp_adjust)) + | (simd_bit_cast<_IV>(static_simd_cast<_MaskType>(__exponent_bits == 0) + & static_simd_cast<_MaskType>(__x != 0)) + & _IV(__exp_adjust + __exp_offset)); *__exp = simd_cast<_Samesize>(__e - __offset); return __mant; } @@ -786,7 +785,7 @@ template using namespace std::experimental::__proposed; using _IV = rebind_simd_t< conditional_t, _V>; - return (__bit_cast<_IV>(__v) >> (__digits_v<_Tp> - 1)) + return (simd_bit_cast<_IV>(__v) >> (__digits_v<_Tp> - 1)) - (__max_exponent_v<_Tp> - 1); }; _V __r = static_simd_cast<_V>(__exponent(abs_x)); @@ -953,6 +952,7 @@ template // Skylake-AVX512 (not even for SSE and AVX vectors, and really bad for // AVX-512). using namespace __float_bitwise_operators; + using namespace __proposed; _V __absx = abs(__x); // no error _V __absy = abs(__y); // no error _V __hi = max(__absx, __absy); // no error @@ -1000,9 +1000,9 @@ template #ifdef __FAST_MATH__ using _Ip = __int_for_sizeof_t<_Tp>; using _IV = rebind_simd_t<_Ip, _V>; - const auto __as_int = __bit_cast<_IV>(__hi_exp); + const auto __as_int = simd_bit_cast<_IV>(__hi_exp); const _V __scale - = __bit_cast<_V>(2 * __bit_cast<_Ip>(_Tp(1)) - __as_int); + = simd_bit_cast<_V>(2 * simd_bit_cast<_Ip>(_Tp(1)) - __as_int); #else const _V __scale = (__hi_exp ^ __inf) * _Tp(.5); #endif @@ -1090,6 +1090,7 @@ _GLIBCXX_SIMD_CVTING2(hypot) else { using namespace __float_bitwise_operators; + using namespace __proposed; const _V __absx = abs(__x); // no error const _V __absy = abs(__y); // no error const _V __absz = abs(__z); // no error @@ -1169,9 +1170,9 @@ _GLIBCXX_SIMD_CVTING2(hypot) #ifdef __FAST_MATH__ using _Ip = __int_for_sizeof_t<_Tp>; using _IV = rebind_simd_t<_Ip, _V>; - const auto __as_int = __bit_cast<_IV>(__hi_exp); + const auto __as_int = simd_bit_cast<_IV>(__hi_exp); const _V __scale - = __bit_cast<_V>(2 * __bit_cast<_Ip>(_Tp(1)) - __as_int); + = simd_bit_cast<_V>(2 * simd_bit_cast<_Ip>(_Tp(1)) - __as_int); #else const _V __scale = (__hi_exp ^ __inf) * _Tp(.5); #endif @@ -1278,12 +1279,6 @@ template return std::copysign(__x[0], __y[0]); else if constexpr (__is_fixed_size_abi_v<_Abi>) return {__private_init, _Abi::_SimdImpl::_S_copysign(__data(__x), __data(__y))}; - else if constexpr (is_same_v<_Tp, long double> && sizeof(_Tp) == 12) - // Remove this case once __bit_cast is implemented via __builtin_bit_cast. - // It is necessary, because __signmask below cannot be computed at compile - // time. - return simd<_Tp, _Abi>( - [&](auto __i) { return std::copysign(__x[__i], __y[__i]); }); else { using _V = simd<_Tp, _Abi>; diff --git a/libstdc++-v3/testsuite/experimental/simd/tests/bits/test_values.h b/libstdc++-v3/testsuite/experimental/simd/tests/bits/test_values.h index b69bd0b..67aa870 100644 --- a/libstdc++-v3/testsuite/experimental/simd/tests/bits/test_values.h +++ b/libstdc++-v3/testsuite/experimental/simd/tests/bits/test_values.h @@ -221,11 +221,11 @@ template if constexpr (sizeof(T) <= sizeof(double)) { using I = rebind_simd_t<__int_for_sizeof_t, V>; - const I abs_x = __bit_cast(abs(x)); - const I min = __bit_cast(V(std::__norm_min_v)); - const I max = __bit_cast(V(std::__finite_max_v)); + const I abs_x = simd_bit_cast(abs(x)); + const I min = simd_bit_cast(V(std::__norm_min_v)); + const I max = simd_bit_cast(V(std::__finite_max_v)); return static_simd_cast( - __bit_cast(x) == 0 || (abs_x >= min && abs_x <= max)); + simd_bit_cast(x) == 0 || (abs_x >= min && abs_x <= max)); } else { -- cgit v1.1 From e0672017370b9a9362fda52ecffe33d1c9c41829 Mon Sep 17 00:00:00 2001 From: Chung-Lin Tang Date: Sat, 26 Jun 2021 00:42:58 +0800 Subject: testsuite/101114: Adjust libgomp.c-c++-common/struct-elem-5.c testcase The dg-shouldfail testcase libgomp.c-c++-common/struct-elem-5.c does not properly fail for non-shared address space offloading. Adjust testcase to limit testing only for "target offload_device_nonshared_as". libgomp/ChangeLog: PR testsuite/101114 * testsuite/libgomp.c-c++-common/struct-elem-5.c: Add "target offload_device_nonshared_as" condition for enabling test. --- libgomp/testsuite/libgomp.c-c++-common/struct-elem-5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgomp/testsuite/libgomp.c-c++-common/struct-elem-5.c b/libgomp/testsuite/libgomp.c-c++-common/struct-elem-5.c index 814c301..31a2fa5 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/struct-elem-5.c +++ b/libgomp/testsuite/libgomp.c-c++-common/struct-elem-5.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do run { target offload_device_nonshared_as } } */ struct S { -- cgit v1.1 From e83a5a6b6893e910dc0b6b1cd034e1a258406c93 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 25 Jun 2021 18:31:22 +0100 Subject: libstdc++: More workarounds in 17_intro/names.cc test [PR 97088] Conditionally #undef some more names that are used in system headers. libstdc++-v3/ChangeLog: PR libstdc++/97088 * testsuite/17_intro/names.cc: Undef more names for newlib and also for arm-none-linux-gnueabi. * testsuite/experimental/names.cc: Disable PCH. --- libstdc++-v3/testsuite/17_intro/names.cc | 14 ++++++++++++++ libstdc++-v3/testsuite/experimental/names.cc | 1 + 2 files changed, 15 insertions(+) diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc index 534dab7..805c100 100644 --- a/libstdc++-v3/testsuite/17_intro/names.cc +++ b/libstdc++-v3/testsuite/17_intro/names.cc @@ -208,6 +208,11 @@ #undef r #endif +#if defined (__linux__) && defined (__arm__) +// defines fpregset_t::fpregs::j +#undef j +#endif + #if defined (__linux__) && defined (__powerpc__) // defines __vector128::u #undef u @@ -220,6 +225,15 @@ #if ! __has_include() // newlib's defines __lockable as a macro, so we can't use it. # define __lockable cannot be used as an identifier +// newlib's defines __tzrule_type with these members. +#undef d +#undef m +#undef n +#undef s +// newlib's uses this for parameters +#undef x +// newlib's uses this for parameters +#undef j #endif #ifdef __sun__ diff --git a/libstdc++-v3/testsuite/experimental/names.cc b/libstdc++-v3/testsuite/experimental/names.cc index 34ec3ba..d695a25 100644 --- a/libstdc++-v3/testsuite/experimental/names.cc +++ b/libstdc++-v3/testsuite/experimental/names.cc @@ -16,6 +16,7 @@ // . // { dg-do compile { target c++11 } } +// { dg-add-options no_pch } // Define macros for some common variables names that we must not use for // naming variables, parameters etc. in the library. -- cgit v1.1 From 7ab7fa1b51cb7227e051842bcb971b95c962327a Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 25 Jun 2021 18:31:22 +0100 Subject: libstdc++: Remove noexcept from syncbuf::swap (LWG 3498) The proposed resolution for the inconsistent noexcept-specifiers in the spec is to remove it from bto hthe assignment operator and swap. libstdc++-v3/ChangeLog: * include/std/syncstream (basic_syncbuf::swap()): Remove noexcept, as per LWG 3498. --- libstdc++-v3/include/std/syncstream | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libstdc++-v3/include/std/syncstream b/libstdc++-v3/include/std/syncstream index 299941f..db6ebd5 100644 --- a/libstdc++-v3/include/std/syncstream +++ b/libstdc++-v3/include/std/syncstream @@ -114,7 +114,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - swap(basic_syncbuf& __other) noexcept + swap(basic_syncbuf& __other) { using _ATr = allocator_traits<_Alloc>; if constexpr (!_ATr::propagate_on_container_swap::value) -- cgit v1.1 From 9b6c65c754f2b2a78f5353219ec62817064e0d24 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 25 Jun 2021 18:31:23 +0100 Subject: libstdc++: Fix exception handling in std::ostream seek functions N3168 added the requirement that the [ostream.seeks] functions create a sentry object. Nothing in the requirements of those functions says anything about catching exceptions and setting badbit. As well as not catching exceptions, this change results in another observable behaviour change. Previously seeking on a stream with eofbit set would work (as long as badbit and failbit weren't set). The construction of a sentry causes failbit to be set when eofbit is set, which causes the seek to fail. It is necessary to clear the eofbit before seeking now. libstdc++-v3/ChangeLog: * include/bits/ostream.tcc (sentry): Only set failbit if badbit is set, not if eofbit is set. (tellp, seekp, seekp): Create sentry object. Do not set badbit on exceptions. * testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc: Adjust expected behaviour. * testsuite/27_io/basic_ostream/seekp/wchar_t/exceptions_badbit_throw.cc: Likewise. * testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc: Likewise. * testsuite/27_io/basic_ostream/tellp/wchar_t/exceptions_badbit_throw.cc: Likewise. * testsuite/27_io/basic_ostream/seekp/char/n3168.cc: New test. * testsuite/27_io/basic_ostream/seekp/wchar_t/n3168.cc: New test. * testsuite/27_io/basic_ostream/tellp/char/n3168.cc: New test. * testsuite/27_io/basic_ostream/tellp/wchar_t/n3168.cc: New test. --- libstdc++-v3/include/bits/ostream.tcc | 76 +++++---------- .../seekp/char/exceptions_badbit_throw.cc | 20 ++-- .../27_io/basic_ostream/seekp/char/n3168.cc | 103 +++++++++++++++++++++ .../seekp/wchar_t/exceptions_badbit_throw.cc | 22 ++--- .../27_io/basic_ostream/seekp/wchar_t/n3168.cc | 101 ++++++++++++++++++++ .../tellp/char/exceptions_badbit_throw.cc | 10 +- .../27_io/basic_ostream/tellp/char/n3168.cc | 64 +++++++++++++ .../tellp/wchar_t/exceptions_badbit_throw.cc | 10 +- .../27_io/basic_ostream/tellp/wchar_t/n3168.cc | 64 +++++++++++++ 9 files changed, 372 insertions(+), 98 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/n3168.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/n3168.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/n3168.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/n3168.cc diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index 76ca285..20585f4 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__os.good()) _M_ok = true; - else + else if (__os.bad()) __os.setstate(ios_base::failbit); } @@ -236,19 +236,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_ostream<_CharT, _Traits>:: tellp() { + sentry __cerb(*this); pos_type __ret = pos_type(-1); - __try - { - if (!this->fail()) - __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); - } - __catch(__cxxabiv1::__forced_unwind&) - { - this->_M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { this->_M_setstate(ios_base::badbit); } + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); return __ret; } @@ -257,30 +248,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_ostream<_CharT, _Traits>:: seekp(pos_type __pos) { - ios_base::iostate __err = ios_base::goodbit; - __try + sentry __cerb(*this); + if (!this->fail()) { - if (!this->fail()) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 136. seekp, seekg setting wrong streams? - const pos_type __p = this->rdbuf()->pubseekpos(__pos, - ios_base::out); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out); - // 129. Need error indication from seekp() and seekg() - if (__p == pos_type(off_type(-1))) - __err |= ios_base::failbit; - } - } - __catch(__cxxabiv1::__forced_unwind&) - { - this->_M_setstate(ios_base::badbit); - __throw_exception_again; + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + this->setstate(ios_base::failbit); } - __catch(...) - { this->_M_setstate(ios_base::badbit); } - if (__err) - this->setstate(__err); return *this; } @@ -289,30 +267,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_ostream<_CharT, _Traits>:: seekp(off_type __off, ios_base::seekdir __dir) { - ios_base::iostate __err = ios_base::goodbit; - __try + sentry __cerb(*this); + if (!this->fail()) { - if (!this->fail()) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 136. seekp, seekg setting wrong streams? - const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, - ios_base::out); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::out); - // 129. Need error indication from seekp() and seekg() - if (__p == pos_type(off_type(-1))) - __err |= ios_base::failbit; - } + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + this->setstate(ios_base::failbit); } - __catch(__cxxabiv1::__forced_unwind&) - { - this->_M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { this->_M_setstate(ios_base::badbit); } - if (__err) - this->setstate(__err); return *this; } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc index a5a95fd..bc59578 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc @@ -28,7 +28,6 @@ void test01() __gnu_test::fail_streambuf bib; ostream stream(&bib); - stream.exceptions(ios_base::badbit); ostream::pos_type pos = ostream::pos_type(); @@ -37,14 +36,11 @@ void test01() stream.seekp(pos); VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.good() ); } - catch (...) + catch (...) { VERIFY( false ); } @@ -56,7 +52,6 @@ void test02() __gnu_test::fail_streambuf bib; ostream stream(&bib); - stream.exceptions(ios_base::badbit); ostream::off_type off(5); @@ -65,14 +60,11 @@ void test02() stream.seekp(off, ios_base::cur); VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.good() ); } - catch (...) + catch (...) { VERIFY( false ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/n3168.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/n3168.cc new file mode 100644 index 0000000..12da0b1 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/n3168.cc @@ -0,0 +1,103 @@ +#include +#include +#include + +// C++11 27.7.3.5 basic_ostream seek members [ostream.seeks] + +// Verify [ostream.seeks] functions use a sentry, as per N3168. + +void +test01() +{ + // Check that the sentry sets failbit when seeking on a bad stream. + // The standard doesn't guarantee this, but it is true for libstdc++. + + std::ostream os(0); + VERIFY( os.rdstate() == std::ios_base::badbit ); + + std::ostream::pos_type pos = std::ostream::pos_type(); + os.seekp(pos); + VERIFY( os.rdstate() & std::ios_base::failbit ); + + os.clear(); + std::ostream::off_type off(5); + os.seekp(off, std::ios_base::cur); + VERIFY( os.rdstate() & std::ios_base::failbit ); + + os.clear(); + os.exceptions(std::ios_base::failbit); + + try + { + os.clear(); + os.seekp(pos); + VERIFY( false ); + } + catch (const std::ios_base::failure&) + { + VERIFY( os.rdstate() & std::ios_base::failbit ); + } + catch (...) + { + VERIFY( false ); + } + + try + { + os.clear(); + os.seekp(off, std::ios_base::cur); + VERIFY( false ); + } + catch (const std::ios_base::failure&) + { + VERIFY( os.rdstate() & std::ios_base::failbit ); + } + catch (...) + { + VERIFY( false ); + } +} + +void +test02() +{ + // Check that the sentry flushes a tied stream when seeking. + + { + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + os.tie(&os_tie); + + std::ostream::pos_type pos = std::ostream::pos_type(); + os.seekp(pos); + + VERIFY( ! buf.sync_called() ); + VERIFY( buf_tie.sync_called() ); + } + + { + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + os.tie(&os_tie); + + std::ostream::off_type off(0); + os.seekp(off, std::ios_base::cur); + + VERIFY( ! buf.sync_called() ); + VERIFY( buf_tie.sync_called() ); + } +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/exceptions_badbit_throw.cc index 499389b..2daa959 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/exceptions_badbit_throw.cc @@ -28,7 +28,6 @@ void test01() __gnu_test::fail_wstreambuf bib; wostream stream(&bib); - stream.exceptions(ios_base::badbit); wostream::pos_type pos = wostream::pos_type(); @@ -37,14 +36,11 @@ void test01() stream.seekp(pos); VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.good() ); } - catch (...) + catch (...) { VERIFY( false ); } @@ -53,10 +49,9 @@ void test01() void test02() { using namespace std; - + __gnu_test::fail_wstreambuf bib; wostream stream(&bib); - stream.exceptions(ios_base::badbit); wostream::off_type off(5); @@ -65,14 +60,11 @@ void test02() stream.seekp(off, ios_base::cur); VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.good() ); } - catch (...) + catch (...) { VERIFY( false ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/n3168.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/n3168.cc new file mode 100644 index 0000000..652f46f --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/wchar_t/n3168.cc @@ -0,0 +1,101 @@ +#include +#include +#include + +// C++11 27.7.3.5 basic_ostream seek members [ostream.seeks] + +// Verify [ostream.seeks] functions use a sentry, as per N3168. + +void +test01() +{ + // Check that the sentry sets failbit when seeking on a bad stream. + // The standard doesn't guarantee this, but it is true for libstdc++. + + std::wostream os(0); + VERIFY( os.rdstate() == std::ios_base::badbit ); + + std::wostream::pos_type pos = std::wostream::pos_type(); + os.seekp(pos); + VERIFY( os.rdstate() & std::ios_base::failbit ); + + os.clear(); + std::wostream::off_type off(5); + os.seekp(off, std::ios_base::cur); + VERIFY( os.rdstate() & std::ios_base::failbit ); + + os.clear(); + os.exceptions(std::ios_base::failbit); + + try + { + os.clear(); + os.seekp(pos); + VERIFY( false ); + } + catch (const std::ios_base::failure&) + { + VERIFY( os.rdstate() & std::ios_base::failbit ); + } + catch (...) + { + VERIFY( false ); + } + + try + { + os.clear(); + os.seekp(off, std::ios_base::cur); + VERIFY( false ); + } + catch (const std::ios_base::failure&) + { + VERIFY( os.rdstate() & std::ios_base::failbit ); + } + catch (...) + { + VERIFY( false ); + } +} + +void +test02() +{ + // Check that the sentry flushes a tied stream when seeking. + + { + __gnu_test::sync_wstreambuf buf; + std::wostream os(&buf); + + __gnu_test::sync_wstreambuf buf_tie; + std::wostream os_tie(&buf_tie); + + os.tie(&os_tie); + + std::wostream::pos_type pos = std::wostream::pos_type(); + os.seekp(pos); + + VERIFY( buf_tie.sync_called() ); + } + + { + __gnu_test::sync_wstreambuf buf; + std::wostream os(&buf); + + __gnu_test::sync_wstreambuf buf_tie; + std::wostream os_tie(&buf_tie); + + os.tie(&os_tie); + + std::wostream::off_type off(0); + os.seekp(off, std::ios_base::cur); + + VERIFY( buf_tie.sync_called() ); + } +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc index c6b7a8a..7ddddec 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc @@ -28,21 +28,17 @@ void test01() { __gnu_test::fail_streambuf bib; ostream stream(&bib); - stream.exceptions(ios_base::badbit); try { stream.tellp(); VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.good() ); } - catch (...) + catch (...) { VERIFY(false); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/n3168.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/n3168.cc new file mode 100644 index 0000000..8c2fe85 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/char/n3168.cc @@ -0,0 +1,64 @@ +#include +#include +#include + +// C++11 27.7.3.5 basic_ostream seek members [ostream.seeks] + +// Verify [ostream.seeks] functions use a sentry, as per N3168. + +void +test01() +{ + // Check that the sentry sets failbit when seeking on a bad stream. + // The standard doesn't guarantee this, but it is true for libstdc++. + + std::ostream os(0); + VERIFY( os.rdstate() == std::ios_base::badbit ); + + os.tellp(); + VERIFY( os.rdstate() & std::ios_base::failbit ); + + os.clear(); + + os.exceptions(std::ios_base::failbit); + + try + { + os.clear(); + os.tellp(); + VERIFY( false ); + } + catch (const std::ios_base::failure&) + { + VERIFY( os.rdstate() & std::ios_base::failbit ); + } + catch (...) + { + VERIFY( false ); + } +} + +void +test02() +{ + // Check that the sentry flushes a tied stream when seeking. + + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + os.tie(&os_tie); + + os.tellp(); + + VERIFY( ! buf.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/exceptions_badbit_throw.cc index 6bdeeeb..803c45a 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/exceptions_badbit_throw.cc @@ -28,21 +28,17 @@ void test01() { __gnu_test::fail_wstreambuf bib; wostream stream(&bib); - stream.exceptions(ios_base::badbit); try { stream.tellp(); VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.good() ); } - catch (...) + catch (...) { VERIFY(false); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/n3168.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/n3168.cc new file mode 100644 index 0000000..887a9a7 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/tellp/wchar_t/n3168.cc @@ -0,0 +1,64 @@ +#include +#include +#include + +// C++11 27.7.3.5 basic_ostream seek members [ostream.seeks] + +// Verify [ostream.seeks] functions use a sentry, as per N3168. + +void +test01() +{ + // Check that the sentry sets failbit when seeking on a bad stream. + // The standard doesn't guarantee this, but it is true for libstdc++. + + std::wostream os(0); + VERIFY( os.rdstate() == std::ios_base::badbit ); + + os.tellp(); + VERIFY( os.rdstate() & std::ios_base::failbit ); + + os.clear(); + + os.exceptions(std::ios_base::failbit); + + try + { + os.clear(); + os.tellp(); + VERIFY( false ); + } + catch (const std::ios_base::failure&) + { + VERIFY( os.rdstate() & std::ios_base::failbit ); + } + catch (...) + { + VERIFY( false ); + } +} + +void +test02() +{ + // Check that the sentry flushes a tied stream when seeking. + + __gnu_test::sync_wstreambuf buf; + std::wostream os(&buf); + + __gnu_test::sync_wstreambuf buf_tie; + std::wostream os_tie(&buf_tie); + + os.tie(&os_tie); + + os.tellp(); + + VERIFY( ! buf.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} + +int main() +{ + test01(); + test02(); +} -- cgit v1.1 From f8c5b542f6cb6a947600e34420565ac67486ea14 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 25 Jun 2021 18:31:23 +0100 Subject: libstdc++: Implement LWG 581 for std:ostream::flush() LWG 581 changed ostream::flush() to an unformatted output function for C++11, but it was never implemented in libstdc++. libstdc++-v3/ChangeLog: * doc/xml/manual/intro.xml: Document LWG 581 change. * doc/html/manual/bugs.html: Regenerate. * include/bits/basic_ios.tcc: Whitespace. * include/bits/ostream.tcc (basic_ostream::flush()): Construct sentry. * testsuite/27_io/basic_ostream/flush/char/2.cc: Check additional cases. * testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc: Likewise. * testsuite/27_io/basic_ostream/flush/wchar_t/2.cc: Likewise. * testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc: Likewise. --- libstdc++-v3/doc/html/manual/bugs.html | 3 ++ libstdc++-v3/doc/xml/manual/intro.xml | 6 +++ libstdc++-v3/include/bits/basic_ios.tcc | 2 +- libstdc++-v3/include/bits/ostream.tcc | 35 ++++++++++------ .../testsuite/27_io/basic_ostream/flush/char/2.cc | 48 +++++++++++++++++----- .../flush/char/exceptions_badbit_throw.cc | 16 ++++---- .../27_io/basic_ostream/flush/wchar_t/2.cc | 48 +++++++++++++++++----- .../flush/wchar_t/exceptions_badbit_throw.cc | 16 ++++---- 8 files changed, 126 insertions(+), 48 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index 7e08373..7b49e4a 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -303,6 +303,9 @@

550: What should the return type of pow(float,int) be?

In C++11 mode, remove the pow(float,int), etc., signatures. +

581: + flush() not unformatted function +

Change it to be a unformatted output function (i.e. construct a sentry and catch exceptions).

586: string inserter not a formatted function

Change it to be a formatted output function (i.e. catch exceptions). diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 3e7843f..45762ca 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -743,6 +743,12 @@ requirements of the license of GCC. In C++11 mode, remove the pow(float,int), etc., signatures. + 581: + flush() not unformatted function + + Change it to be a unformatted output function (i.e. construct a sentry and catch exceptions). + + 586: string inserter not a formatted function diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc index 6285f73..664a9f2 100644 --- a/libstdc++-v3/include/bits/basic_ios.tcc +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -43,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (this->rdbuf()) _M_streambuf_state = __state; else - _M_streambuf_state = __state | badbit; + _M_streambuf_state = __state | badbit; if (this->exceptions() & this->rdstate()) __throw_ios_failure(__N("basic_ios::clear")); } diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index 20585f4..d3220e8 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -213,21 +213,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() is *not* an unformatted output function. - ios_base::iostate __err = ios_base::goodbit; - __try - { - if (this->rdbuf() && this->rdbuf()->pubsync() == -1) - __err |= ios_base::badbit; - } - __catch(__cxxabiv1::__forced_unwind&) + // 581. flush() not unformatted function + // basic_ostream::flush() *is* an unformatted output function. + if (__streambuf_type* __buf = this->rdbuf()) { - this->_M_setstate(ios_base::badbit); - __throw_exception_again; + sentry __cerb(*this); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + __try + { + if (this->rdbuf()->pubsync() == -1) + __err |= ios_base::badbit; + } + __catch(__cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } } - __catch(...) - { this->_M_setstate(ios_base::badbit); } - if (__err) - this->setstate(__err); return *this; } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc index 0b33e60..96969de 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc @@ -22,42 +22,70 @@ // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() does not behave as an unformatted output function. +// But wait ... +// 581. flush() not unformatted function +// So now basic_ostream::flush() *is* an unformatted output function. #include #include #include +void +test01() +{ + std::ostream os(0); + VERIFY( os.bad() ); + + // Nothing should happen if os.rdbuf() is null. No sentry is constructed. + os.flush(); + VERIFY( os.rdstate() == std::ios_base::badbit ); // no failbit + + os.exceptions(std::ios_base::failbit); + os.flush(); +} + void test02() { __gnu_test::sync_streambuf buf; std::ostream os(&buf); - + __gnu_test::sync_streambuf buf_tie; std::ostream os_tie(&buf_tie); - // No sentry should be constructed so os.tie()->flush() should not be - // called. + // A sentry should be constructed so os.tie()->flush() should be called. os.tie(&os_tie); - + os.flush(); VERIFY( os.good() ); VERIFY( buf.sync_called() ); - VERIFY( !buf_tie.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} - // os.rdbuf()->pubsync() should be called even if !os.good(). +void +test03() +{ + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + os.tie(&os_tie); + + // os.rdbuf()->pubsync() should not be called if !os.good(). os.setstate(std::ios_base::eofbit); os.flush(); - VERIFY( os.rdstate() == std::ios_base::eofbit ); - VERIFY( buf.sync_called() ); + VERIFY( os.rdstate() & std::ios_base::eofbit ); + VERIFY( !buf.sync_called() ); VERIFY( !buf_tie.sync_called() ); } int main() { + test01(); test02(); - return 0; + test03(); } - diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc index bba5fb0..115b004 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc @@ -28,21 +28,23 @@ void test01() { __gnu_test::fail_streambuf bib; ostream stream(&bib); + + stream.flush(); // should catch exception and set badbit + VERIFY( stream.rdstate() == ios_base::badbit ); + + stream.clear(); stream.exceptions(ios_base::badbit); try { - stream.flush(); + stream.flush(); // should catch exception and set badbit and rethrow VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.rdstate() == ios_base::badbit ); } - catch (...) + catch (...) { VERIFY( false ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc index 3711fde..4403fd3 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/2.cc @@ -20,42 +20,70 @@ // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() does not behave as an unformatted output function. +// But wait ... +// 581. flush() not unformatted function +// So now basic_ostream::flush() *is* an unformatted output function. #include #include #include +void +test01() +{ + std::wostream os(0); + VERIFY( os.bad() ); + + // Nothing should happen if os.rdbuf() is null. No sentry is constructed. + os.flush(); + VERIFY( os.rdstate() == std::ios_base::badbit ); // no failbit + + os.exceptions(std::ios_base::failbit); + os.flush(); +} + void test02() { __gnu_test::sync_wstreambuf buf; std::wostream os(&buf); - + __gnu_test::sync_wstreambuf buf_tie; std::wostream os_tie(&buf_tie); - // No sentry should be constructed so os.tie()->flush() should not be - // called. + // A sentry should be constructed so os.tie()->flush() should be called. os.tie(&os_tie); - + os.flush(); VERIFY( os.good() ); VERIFY( buf.sync_called() ); - VERIFY( !buf_tie.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} - // os.rdbuf()->pubsync() should be called even if !os.good(). +void +test03() +{ + __gnu_test::sync_wstreambuf buf; + std::wostream os(&buf); + + __gnu_test::sync_wstreambuf buf_tie; + std::wostream os_tie(&buf_tie); + + os.tie(&os_tie); + + // os.rdbuf()->pubsync() should not be called if !os.good(). os.setstate(std::ios_base::eofbit); os.flush(); - VERIFY( os.rdstate() == std::ios_base::eofbit ); - VERIFY( buf.sync_called() ); + VERIFY( os.rdstate() & std::ios_base::eofbit ); + VERIFY( !buf.sync_called() ); VERIFY( !buf_tie.sync_called() ); } int main() { + test01(); test02(); - return 0; + test03(); } - diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc index 86440e1..d88f385 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc @@ -28,21 +28,23 @@ void test01() { __gnu_test::fail_wstreambuf bib; wostream stream(&bib); + + stream.flush(); // should catch exception and set badbit + VERIFY( stream.rdstate() == ios_base::badbit ); + + stream.clear(); stream.exceptions(ios_base::badbit); try { - stream.flush(); + stream.flush(); // should catch exception and set badbit and rethrow VERIFY( false ); } - catch (const __gnu_test::positioning_error&) + catch (const __gnu_test::positioning_error&) { - // stream should set badbit and rethrow facet_error. - VERIFY( stream.bad() ); - VERIFY( (stream.rdstate() & ios_base::failbit) == 0 ); - VERIFY( !stream.eof() ); + VERIFY( stream.rdstate() == ios_base::badbit ); } - catch (...) + catch (...) { VERIFY( false ); } -- cgit v1.1 From 4a52cf2eb9d6864ad85674ab56838e0d9ce27926 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 25 Jun 2021 18:31:23 +0100 Subject: libstdc++: Avoid intercepting exception in ostream::write Currently if ostream::write fails and sets badbit and that causes an exception, we will catch the exception, set badbit again, and rethrow the exception. This change delays setting badbit until after the try-catch block, so that if it causes an exception we don't need to catch and rethrow it. This removes the last remaining use of _M_write, so it can be made private (or removed entirely for versioned namespace builds, where ABI compatibility is not required). All other uses of _M_write were replaced by calls to __ostream_insert, so make _M_write use that too. libstdc++-v3/ChangeLog: * include/bits/ostream.tcc (basic_ostream::write): Call sputn directly instead of using _M_write. Do setstate(__err) all outside the try-catch block. * include/std/ostream (basic_ostream::_M_write): Declare private. Use __ostream_insert. Do not define for the versioned namespace. --- libstdc++-v3/include/bits/ostream.tcc | 8 +++++++- libstdc++-v3/include/std/ostream | 20 +++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc index d3220e8..06b2217 100644 --- a/libstdc++-v3/include/bits/ostream.tcc +++ b/libstdc++-v3/include/bits/ostream.tcc @@ -192,8 +192,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION sentry __cerb(*this); if (__cerb) { + ios_base::iostate __err = ios_base::goodbit; __try - { _M_write(__s, __n); } + { + if (this->rdbuf()->sputn(__s, __n) != __n) + __err = ios_base::badbit; + } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); @@ -201,6 +205,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } __catch(...) { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(ios_base::badbit); } return *this; } diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 9816973..ddb33fe 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -309,19 +309,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION put(char_type __c); /** - * @brief Core write functionality, without sentry. - * @param __s The array to insert. - * @param __n Maximum number of characters to insert. - */ - void - _M_write(const char_type* __s, streamsize __n) - { - const streamsize __put = this->rdbuf()->sputn(__s, __n); - if (__put != __n) - this->setstate(ios_base::badbit); - } - - /** * @brief Character string insertion. * @param __s The array to insert. * @param __n Maximum number of characters to insert. @@ -419,6 +406,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template __ostream_type& _M_insert(_ValueT __v); + + private: +#if !_GLIBCXX_INLINE_VERSION + void + _M_write(const char_type* __s, streamsize __n) + { std::__ostream_insert(*this, __s, __n); } +#endif }; /** -- cgit v1.1 From fd51b344ca86c9673db0161d4a383cccdb2f429c Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 25 Jun 2021 17:01:01 -0600 Subject: PR middle-end/101216 - spurious notes for function calls PR middle-end/101216 gcc/ChangeLog: * calls.c (maybe_warn_rdwr_sizes): Use the no_warning constant. gcc/testsuite/ChangeLog: * gcc.dg/Wnonnull-7.c: New test. --- gcc/calls.c | 6 +++--- gcc/testsuite/gcc.dg/Wnonnull-7.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wnonnull-7.c diff --git a/gcc/calls.c b/gcc/calls.c index 27e8c45..f8a4b79 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2054,7 +2054,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) *sizstr = '\0'; /* Set if a warning has been issued for the current argument. */ - opt_code arg_warned = N_OPTS; + opt_code arg_warned = no_warning; location_t loc = EXPR_LOCATION (exp); tree ptr = access.second.ptr; if (*sizstr @@ -2080,7 +2080,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) exp, sizidx + 1, sizstr)) arg_warned = OPT_Wstringop_overflow_; - if (arg_warned != N_OPTS) + if (arg_warned != no_warning) { append_attrname (access, attrstr, sizeof attrstr); /* Remember a warning has been issued and avoid warning @@ -2152,7 +2152,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) arg_warned = OPT_Wnonnull; } - if (arg_warned) + if (arg_warned != no_warning) { append_attrname (access, attrstr, sizeof attrstr); /* Remember a warning has been issued and avoid warning diff --git a/gcc/testsuite/gcc.dg/Wnonnull-7.c b/gcc/testsuite/gcc.dg/Wnonnull-7.c new file mode 100644 index 0000000..e7b331a --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wnonnull-7.c @@ -0,0 +1,15 @@ +/* PR middle-end/101216 - spurious notes for function calls + { dg-do compile } + { dg-options "-O2 -w" } */ + +__attribute__ ((access (write_only, 1, 2))) char* +getcwd (char *, __SIZE_TYPE__); + +char* f (void) +{ + char a[8]; + return getcwd (0, 8); +} + +/* Expect no messages of any kind on output. + { dg-bogus "" "" { target *-*-* } 0 } */ -- cgit v1.1 From 176289e50e3d379b681f8775cdb0230b1e9f50dc Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 25 Jun 2021 19:07:25 -0400 Subject: jit: fix test-asm failures on i?86 On i686, test_i386_basic_asm_4 has: error: inconsistent operand constraints in an 'asm' and test_i386_basic_asm_5 has: /tmp/libgccjit-9FsLie/fake.s:9: Error: bad register name `%rdi' /tmp/libgccjit-9FsLie/fake.s:10: Error: bad register name `%rsi' This is only intended as a smoketest of asm support, so only run it on x86_64. gcc/testsuite/ChangeLog: * jit.dg/test-asm.c: Remove i?86-*-* from target specifier. * jit.dg/test-asm.cc: Likewise. Signed-off-by: David Malcolm --- gcc/testsuite/jit.dg/test-asm.c | 2 +- gcc/testsuite/jit.dg/test-asm.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/jit.dg/test-asm.c b/gcc/testsuite/jit.dg/test-asm.c index e7777ee..35a9f9d 100644 --- a/gcc/testsuite/jit.dg/test-asm.c +++ b/gcc/testsuite/jit.dg/test-asm.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile { target x86_64-*-* } } */ #include #include diff --git a/gcc/testsuite/jit.dg/test-asm.cc b/gcc/testsuite/jit.dg/test-asm.cc index 6f18280..be487e3 100644 --- a/gcc/testsuite/jit.dg/test-asm.cc +++ b/gcc/testsuite/jit.dg/test-asm.cc @@ -1,4 +1,4 @@ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile { target x86_64-*-* } } */ #include "libgccjit++.h" -- cgit v1.1 From 99585d88a090b4c5b7791f7ab62f70eb37b748fa Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 25 Jun 2021 19:07:30 -0400 Subject: jit: fix test-vector-* failures Fix failures seen on i686 due to relying on exact floating-point equality when testing results of vector division. gcc/testsuite/ChangeLog: * jit.dg/test-vector-rvalues.cc (check_div): Add specialization for v4f, to avoid relying on exact floating-point equality. * jit.dg/test-vector-types.cc (check_div): Likewise. Signed-off-by: David Malcolm --- gcc/testsuite/jit.dg/test-vector-rvalues.cc | 8 ++++++++ gcc/testsuite/jit.dg/test-vector-types.cc | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/gcc/testsuite/jit.dg/test-vector-rvalues.cc b/gcc/testsuite/jit.dg/test-vector-rvalues.cc index ac230bf7..0287711 100644 --- a/gcc/testsuite/jit.dg/test-vector-rvalues.cc +++ b/gcc/testsuite/jit.dg/test-vector-rvalues.cc @@ -165,6 +165,14 @@ check_div (const V &a, const V &b, const V &c) CHECK_VALUE (c[i], a[i] / b[i]); } +template <> +void +check_div (const v4f &a, const v4f &b, const v4f &c) +{ + for (int i = 0; i < 4; i++) + CHECK_DOUBLE_VALUE (c[i], a[i] / b[i]); +} + template void verify_vec_code (gcc_jit_context *ctxt, gcc_jit_result *result, diff --git a/gcc/testsuite/jit.dg/test-vector-types.cc b/gcc/testsuite/jit.dg/test-vector-types.cc index 3389e04..1f49be6 100644 --- a/gcc/testsuite/jit.dg/test-vector-types.cc +++ b/gcc/testsuite/jit.dg/test-vector-types.cc @@ -139,6 +139,14 @@ check_div (const T &a, const T &b, const T &c) CHECK_VALUE (c[i], a[i] / b[i]); } +template <> +void +check_div (const v4f &a, const v4f &b, const v4f &c) +{ + for (int i = 0; i < 4; i++) + CHECK_DOUBLE_VALUE (c[i], a[i] / b[i]); +} + template void verify_vec_code (gcc_jit_context *ctxt, gcc_jit_result *result, -- cgit v1.1 From f9c80eb12c58126a94ad869380af5b88b752c06f Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 8 Jun 2021 17:44:13 -0400 Subject: c++: Failure to delay noexcept parsing with ptr-operator [PR100752] We weren't passing 'flags' to the recursive call to cp_parser_declarator in the ptr-operator case and as an effect, delayed parsing of noexcept didn't work as advertised. The following change passes more than just CP_PARSER_FLAGS_DELAY_NOEXCEPT but that doesn't seem to break anything. I'm now also passing member_p and static_p, as a consequence, two tests needed small tweaks. PR c++/100752 gcc/cp/ChangeLog: * parser.c (cp_parser_declarator): Pass flags down to cp_parser_declarator. Also pass static_p/member_p. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept69.C: New test. * g++.dg/parse/saved1.C: Adjust dg-error. * g++.dg/template/crash50.C: Likewise. --- gcc/cp/parser.c | 6 ++---- gcc/testsuite/g++.dg/cpp0x/noexcept69.C | 12 ++++++++++++ gcc/testsuite/g++.dg/parse/saved1.C | 4 ++-- gcc/testsuite/g++.dg/template/crash50.C | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept69.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 096580e..02daa7a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22170,12 +22170,10 @@ cp_parser_declarator (cp_parser* parser, cp_parser_parse_tentatively (parser); /* Parse the dependent declarator. */ - declarator = cp_parser_declarator (parser, dcl_kind, - CP_PARSER_FLAGS_NONE, + declarator = cp_parser_declarator (parser, dcl_kind, flags, /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false, - friend_p, /*static_p=*/false); + member_p, friend_p, static_p); /* If we are parsing an abstract-declarator, we must handle the case where the dependent declarator is absent. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept69.C b/gcc/testsuite/g++.dg/cpp0x/noexcept69.C new file mode 100644 index 0000000..9b87ba0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept69.C @@ -0,0 +1,12 @@ +// PR c++/100752 +// { dg-do compile { target c++11 } } + +struct S { + void f() noexcept {} + S &g() noexcept(noexcept(f())) { f(); return *this; } +}; + +struct X { + int& f() noexcept(noexcept(i)); + int i; +}; diff --git a/gcc/testsuite/g++.dg/parse/saved1.C b/gcc/testsuite/g++.dg/parse/saved1.C index 979a056..1deaa93 100644 --- a/gcc/testsuite/g++.dg/parse/saved1.C +++ b/gcc/testsuite/g++.dg/parse/saved1.C @@ -1,7 +1,7 @@ // Test that the parser doesn't go into an infinite loop from ignoring the // PRE_PARSED_FUNCTION_DECL token. -class C { static void* operator new(size_t); }; // { dg-error "24:declaration of .operator new. as non-function" } -// { dg-error "expected|ISO C\\+\\+ forbids" "" { target *-*-* } .-1 } +class C { static void* operator new(size_t); }; // { dg-error "37:.size_t. has not been declared" } +// { dg-error ".operator new. takes type .size_t." "" { target *-*-* } .-1 } void* C::operator new(size_t) { return 0; } // { dg-error "" } class D { D(int i): integer(i){}}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash50.C b/gcc/testsuite/g++.dg/template/crash50.C index 286685a..4b846cd 100644 --- a/gcc/testsuite/g++.dg/template/crash50.C +++ b/gcc/testsuite/g++.dg/template/crash50.C @@ -3,5 +3,5 @@ struct A { - template void* foo(; // { dg-error "primary-expression|initialization|static|template" } + template void* foo(; // { dg-error "expected|initialization|static|template" } }; -- cgit v1.1 From 90708f87b8d13da61f7d5cba7c6597fee0025bb1 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 26 Jun 2021 00:16:39 +0000 Subject: Daily bump. --- ChangeLog | 4 ++ gcc/ChangeLog | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/c-family/ChangeLog | 13 +++++ gcc/c/ChangeLog | 26 ++++++++++ gcc/cp/ChangeLog | 62 +++++++++++++++++++++++ gcc/testsuite/ChangeLog | 39 +++++++++++++++ libgomp/ChangeLog | 6 +++ libstdc++-v3/ChangeLog | 71 +++++++++++++++++++++++++++ lto-plugin/ChangeLog | 7 +++ 10 files changed, 357 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7e16a491..aa38933 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2021-06-25 Matthias Kretz + + * MAINTAINERS: Add myself for write after approval and DCO + 2021-06-24 prathamesh.kulkarni * .gitignore: Add entry for cscope.out. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7ea100..d58c034 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,131 @@ +2021-06-25 Martin Sebor + + PR middle-end/101216 + * calls.c (maybe_warn_rdwr_sizes): Use the no_warning constant. + +2021-06-25 Jeff Law + + * config/h8300/h8300.c (select_cc_mode): Handle ASHIFTRT and LSHIFTRT. + +2021-06-25 Richard Biener + + PR tree-optimization/101202 + * tree-vect-slp.c (vect_optimize_slp): Explicitely handle + failed nodes. + +2021-06-25 Richard Biener + + * tree-vect-slp-patterns.c (addsub_pattern::build): Copy + STMT_VINFO_REDUC_DEF from the original representative. + +2021-06-25 Martin Sebor + + * builtins.c (warn_string_no_nul): Replace uses of TREE_NO_WARNING, + gimple_no_warning_p and gimple_set_no_warning with + warning_suppressed_p, and suppress_warning. + (c_strlen): Same. + (maybe_warn_for_bound): Same. + (warn_for_access): Same. + (check_access): Same. + (expand_builtin_strncmp): Same. + (fold_builtin_varargs): Same. + * calls.c (maybe_warn_nonstring_arg): Same. + (maybe_warn_rdwr_sizes): Same. + * cfgexpand.c (expand_call_stmt): Same. + * cgraphunit.c (check_global_declaration): Same. + * fold-const.c (fold_undefer_overflow_warnings): Same. + (fold_truth_not_expr): Same. + (fold_unary_loc): Same. + (fold_checksum_tree): Same. + * gimple-array-bounds.cc (array_bounds_checker::check_array_ref): Same. + (array_bounds_checker::check_mem_ref): Same. + (array_bounds_checker::check_addr_expr): Same. + (array_bounds_checker::check_array_bounds): Same. + * gimple-expr.c (copy_var_decl): Same. + * gimple-fold.c (gimple_fold_builtin_strcpy): Same. + (gimple_fold_builtin_strncat): Same. + (gimple_fold_builtin_stxcpy_chk): Same. + (gimple_fold_builtin_stpcpy): Same. + (gimple_fold_builtin_sprintf): Same. + (fold_stmt_1): Same. + * gimple-ssa-isolate-paths.c (diag_returned_locals): Same. + * gimple-ssa-nonnull-compare.c (do_warn_nonnull_compare): Same. + * gimple-ssa-sprintf.c (handle_printf_call): Same. + * gimple-ssa-store-merging.c (imm_store_chain_info::output_merged_store): Same. + * gimple-ssa-warn-restrict.c (maybe_diag_overlap): Same. + * gimple-ssa-warn-restrict.h: Adjust declarations. + (maybe_diag_access_bounds): Replace uses of TREE_NO_WARNING, + gimple_no_warning_p and gimple_set_no_warning with + warning_suppressed_p, and suppress_warning. + (check_call): Same. + (check_bounds_or_overlap): Same. + * gimple.c (gimple_build_call_from_tree): Same. + * gimplify.c (gimplify_return_expr): Same. + (gimplify_cond_expr): Same. + (gimplify_modify_expr_complex_part): Same. + (gimplify_modify_expr): Same. + (gimple_push_cleanup): Same. + (gimplify_expr): Same. + * omp-expand.c (expand_omp_for_generic): Same. + (expand_omp_taskloop_for_outer): Same. + * omp-low.c (lower_rec_input_clauses): Same. + (lower_lastprivate_clauses): Same. + (lower_send_clauses): Same. + (lower_omp_target): Same. + * tree-cfg.c (pass_warn_function_return::execute): Same. + * tree-complex.c (create_one_component_var): Same. + * tree-inline.c (remap_gimple_op_r): Same. + (copy_tree_body_r): Same. + (declare_return_variable): Same. + (expand_call_inline): Same. + * tree-nested.c (lookup_field_for_decl): Same. + * tree-sra.c (create_access_replacement): Same. + (generate_subtree_copies): Same. + * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Same. + * tree-ssa-forwprop.c (combine_cond_expr_cond): Same. + * tree-ssa-loop-ch.c (ch_base::copy_headers): Same. + * tree-ssa-loop-im.c (execute_sm): Same. + * tree-ssa-phiopt.c (cond_store_replacement): Same. + * tree-ssa-strlen.c (maybe_warn_overflow): Same. + (handle_builtin_strcpy): Same. + (maybe_diag_stxncpy_trunc): Same. + (handle_builtin_stxncpy_strncat): Same. + (handle_builtin_strcat): Same. + * tree-ssa-uninit.c (get_no_uninit_warning): Same. + (set_no_uninit_warning): Same. + (uninit_undefined_value_p): Same. + (warn_uninit): Same. + (maybe_warn_operand): Same. + * tree-vrp.c (compare_values_warnv): Same. + * vr-values.c (vr_values::extract_range_for_var_from_comparison_expr): Same. + (test_for_singularity): Same. + * gimple.h (warning_suppressed_p): New function. + (suppress_warning): Same. + (copy_no_warning): Same. + (gimple_set_block): Call gimple_set_location. + (gimple_set_location): Call copy_warning. + +2021-06-25 Martin Sebor + + * tree.h (warning_suppressed_at, copy_warning, + warning_suppressed_p, suppress_warning): New functions. + +2021-06-25 Martin Sebor + + * Makefile.in (OBJS-libcommon): Add diagnostic-spec.o. + * gengtype.c (open_base_files): Add diagnostic-spec.h. + * diagnostic-spec.c: New file. + * diagnostic-spec.h: New file. + * tree.h (no_warning, all_warnings, suppress_warning_at): New + declarations. + * warning-control.cc: New file. + +2021-06-25 liuhongt + + PR target/101185 + * config/i386/i386.c (x86_order_regs_for_local_alloc): + Revert r12-1669. + 2021-06-24 Andrew MacLeod PR tree-optimization/101189 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ed06b62..ed547dc 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210625 +20210626 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 1521f2d..fe6a44c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,16 @@ +2021-06-25 Martin Sebor + + * c-common.c (c_wrap_maybe_const): Remove TREE_NO_WARNING. + (c_common_truthvalue_conversion): Replace direct uses of + TREE_NO_WARNING with warning_suppressed_p, suppress_warning, and + copy_no_warning. + (check_function_arguments_recurse): Same. + * c-gimplify.c (c_gimplify_expr): Same. + * c-warn.c (overflow_warning): Same. + (warn_logical_operator): Same. + (warn_if_unused_value): Same. + (do_warn_unused_parameter): Same. + 2021-06-24 Jakub Jelinek * c-common.h (enum c_omp_region_type): Add C_ORT_TARGET and diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c38b665..ba53da8 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,29 @@ +2021-06-25 Martin Sebor + + * c-decl.c (pop_scope): Replace direct uses of TREE_NO_WARNING with + warning_suppressed_p, suppress_warning, and copy_no_warning. + (diagnose_mismatched_decls): Same. + (duplicate_decls): Same. + (grokdeclarator): Same. + (finish_function): Same. + (c_write_global_declarations_1): Same. + * c-fold.c (c_fully_fold_internal): Same. + * c-parser.c (c_parser_expr_no_commas): Same. + (c_parser_postfix_expression): Same. + * c-typeck.c (array_to_pointer_conversion): Same. + (function_to_pointer_conversion): Same. + (default_function_array_conversion): Same. + (convert_lvalue_to_rvalue): Same. + (default_conversion): Same. + (build_indirect_ref): Same. + (build_function_call_vec): Same. + (build_atomic_assign): Same. + (build_unary_op): Same. + (c_finish_return): Same. + (emit_side_effect_warnings): Same. + (c_finish_stmt_expr): Same. + (c_omp_clause_copy_ctor): Same. + 2021-06-24 Jakub Jelinek PR c/101176 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 770d327..c53fb0c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,65 @@ +2021-06-26 Marek Polacek + + PR c++/100752 + * parser.c (cp_parser_declarator): Pass flags down to + cp_parser_declarator. Also pass static_p/member_p. + +2021-06-25 Martin Sebor + + * call.c (build_over_call): Replace direct uses of TREE_NO_WARNING + with warning_suppressed_p, suppress_warning, and copy_no_warning, or + nothing if not necessary. + (set_up_extended_ref_temp): Same. + * class.c (layout_class_type): Same. + * constraint.cc (constraint_satisfaction_value): Same. + * coroutines.cc (finish_co_await_expr): Same. + (finish_co_yield_expr): Same. + (finish_co_return_stmt): Same. + (build_actor_fn): Same. + (coro_rewrite_function_body): Same. + (morph_fn_to_coro): Same. + * cp-gimplify.c (genericize_eh_spec_block): Same. + (gimplify_expr_stmt): Same. + (cp_genericize_r): Same. + (cp_fold): Same. + * cp-ubsan.c (cp_ubsan_instrument_vptr): Same. + * cvt.c (cp_fold_convert): Same. + (convert_to_void): Same. + * decl.c (wrapup_namespace_globals): Same. + (grokdeclarator): Same. + (finish_function): Same. + (require_deduced_type): Same. + * decl2.c (no_linkage_error): Same. + (c_parse_final_cleanups): Same. + * except.c (expand_end_catch_block): Same. + * init.c (build_new_1): Same. + (build_new): Same. + (build_vec_delete_1): Same. + (build_vec_init): Same. + (build_delete): Same. + * method.c (defaultable_fn_check): Same. + * parser.c (cp_parser_fold_expression): Same. + (cp_parser_primary_expression): Same. + * pt.c (push_tinst_level_loc): Same. + (tsubst_copy): Same. + (tsubst_omp_udr): Same. + (tsubst_copy_and_build): Same. + * rtti.c (build_if_nonnull): Same. + * semantics.c (maybe_convert_cond): Same. + (finish_return_stmt): Same. + (finish_parenthesized_expr): Same. + (cp_check_omp_declare_reduction): Same. + * tree.c (build_cplus_array_type): Same. + * typeck.c (build_ptrmemfunc_access_expr): Same. + (cp_build_indirect_ref_1): Same. + (cp_build_function_call_vec): Same. + (warn_for_null_address): Same. + (cp_build_binary_op): Same. + (unary_complex_lvalue): Same. + (cp_build_modify_expr): Same. + (build_x_modify_expr): Same. + (convert_for_assignment): Same. + 2021-06-24 Patrick Palka PR c++/98832 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6895330..80322a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,42 @@ +2021-06-26 Marek Polacek + + PR c++/100752 + * g++.dg/cpp0x/noexcept69.C: New test. + * g++.dg/parse/saved1.C: Adjust dg-error. + * g++.dg/template/crash50.C: Likewise. + +2021-06-25 David Malcolm + + * jit.dg/test-vector-rvalues.cc (check_div): Add specialization + for v4f, to avoid relying on exact floating-point equality. + * jit.dg/test-vector-types.cc (check_div): Likewise. + +2021-06-25 David Malcolm + + * jit.dg/test-asm.c: Remove i?86-*-* from target specifier. + * jit.dg/test-asm.cc: Likewise. + +2021-06-25 Martin Sebor + + PR middle-end/101216 + * gcc.dg/Wnonnull-7.c: New test. + +2021-06-25 Richard Biener + + PR tree-optimization/101202 + * gcc.dg/torture/pr101202.c: New testcase. + +2021-06-25 Xi Ruoyao + + * g++.dg/no-stack-protector-attr-3.C (dg-final): Adjust for MIPS. + +2021-06-25 liuhongt + + PR target/101185 + * gcc.target/i386/bitwise_mask_op-3.c: Add xfail to + temporarily avoid regression, eventually xfail should be + removed. + 2021-06-24 Andrew MacLeod * gcc.dg/tree-ssa/evrp30.c: New. diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 640d6fa..c0f2a5f 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,9 @@ +2021-06-25 Chung-Lin Tang + + PR testsuite/101114 + * testsuite/libgomp.c-c++-common/struct-elem-5.c: + Add "target offload_device_nonshared_as" condition for enabling test. + 2021-06-24 Jakub Jelinek * testsuite/libgomp.c-c++-common/target-in-reduction-1.c: New test. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 58d591c..162d707 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,74 @@ +2021-06-25 Jonathan Wakely + + * include/bits/ostream.tcc (basic_ostream::write): Call sputn + directly instead of using _M_write. Do setstate(__err) all + outside the try-catch block. + * include/std/ostream (basic_ostream::_M_write): Declare + private. Use __ostream_insert. Do not define for the versioned + namespace. + +2021-06-25 Jonathan Wakely + + * doc/xml/manual/intro.xml: Document LWG 581 change. + * doc/html/manual/bugs.html: Regenerate. + * include/bits/basic_ios.tcc: Whitespace. + * include/bits/ostream.tcc (basic_ostream::flush()): Construct + sentry. + * testsuite/27_io/basic_ostream/flush/char/2.cc: Check + additional cases. + * testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc: + Likewise. + * testsuite/27_io/basic_ostream/flush/wchar_t/2.cc: Likewise. + * testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc: + Likewise. + +2021-06-25 Jonathan Wakely + + * include/bits/ostream.tcc (sentry): Only set failbit if badbit + is set, not if eofbit is set. + (tellp, seekp, seekp): Create sentry object. Do not set badbit + on exceptions. + * testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc: + Adjust expected behaviour. + * testsuite/27_io/basic_ostream/seekp/wchar_t/exceptions_badbit_throw.cc: + Likewise. + * testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc: + Likewise. + * testsuite/27_io/basic_ostream/tellp/wchar_t/exceptions_badbit_throw.cc: + Likewise. + * testsuite/27_io/basic_ostream/seekp/char/n3168.cc: New test. + * testsuite/27_io/basic_ostream/seekp/wchar_t/n3168.cc: New test. + * testsuite/27_io/basic_ostream/tellp/char/n3168.cc: New test. + * testsuite/27_io/basic_ostream/tellp/wchar_t/n3168.cc: New test. + +2021-06-25 Jonathan Wakely + + * include/std/syncstream (basic_syncbuf::swap()): Remove + noexcept, as per LWG 3498. + +2021-06-25 Jonathan Wakely + + PR libstdc++/97088 + * testsuite/17_intro/names.cc: Undef more names for newlib and + also for arm-none-linux-gnueabi. + * testsuite/experimental/names.cc: Disable PCH. + +2021-06-25 Matthias Kretz + + * include/experimental/bits/simd.h (__bit_cast): Implement via + __builtin_bit_cast #if available. + (__proposed::simd_bit_cast): Add overloads for simd and + simd_mask, which use __builtin_bit_cast (or __bit_cast #if not + available), which return an object of the requested type with + the same bits as the argument. + * include/experimental/bits/simd_math.h: Use simd_bit_cast + instead of __bit_cast to allow casts to fixed_size_simd. + (copysign): Remove branch that was only required if __bit_cast + cannot be constexpr. + * testsuite/experimental/simd/tests/bits/test_values.h: Switch + from __bit_cast to __proposed::simd_bit_cast since the former + will not cast fixed_size objects anymore. + 2021-06-24 Matthias Kretz * include/experimental/bits/simd_math.h diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog index d38aac9..cf88276 100644 --- a/lto-plugin/ChangeLog +++ b/lto-plugin/ChangeLog @@ -1,3 +1,10 @@ +2021-06-25 Richard Biener + + * lto-plugin.c (ltrans_objects): New global. + (all_symbols_read_handler): If -ltrans-objects was specified, + add the output files from the specified file directly. + (process_option): Handle -ltrans-objects. + 2021-05-10 Martin Liska * lto-plugin.c (LTO_SEGMENT_NAME): Remove. -- cgit v1.1 From 86fc076dc289f1861adebee02e6afcbaa1a2cdb6 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Fri, 11 Jun 2021 19:52:30 -0700 Subject: Expand the comparison argument of fold_cond_expr_with_comparison To make things slightly easiler to convert fold_cond_expr_with_comparison over to match.pd, expanding the arg0 argument into 3 different arguments is done. Also this was simple because we don't use arg0 after grabbing the code and the two operands. Also since we do this, we don't need to fold the comparison to get the inverse but just use invert_tree_comparison directly. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * fold-const.c (fold_cond_expr_with_comparison): Exand arg0 into comp_code, arg00, and arg01. (fold_ternary_loc): Use invert_tree_comparison instead of fold_invert_truthvalue for the case where we have A CMP B ? C : A. --- gcc/fold-const.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3aafbc9..e2110b6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -126,7 +126,8 @@ static tree range_binop (enum tree_code, tree, tree, int, tree, int); static tree range_predecessor (tree); static tree range_successor (tree); static tree fold_range_test (location_t, enum tree_code, tree, tree, tree); -static tree fold_cond_expr_with_comparison (location_t, tree, tree, tree, tree); +static tree fold_cond_expr_with_comparison (location_t, tree, enum tree_code, + tree, tree, tree, tree); static tree unextend (tree, int, int, tree); static tree extract_muldiv (tree, tree, enum tree_code, tree, bool *); static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *); @@ -5734,20 +5735,19 @@ merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0, /* Subroutine of fold, looking inside expressions of the form - A op B ? A : C, where ARG0, ARG1 and ARG2 are the three operands - of the COND_EXPR. This function is being used also to optimize - A op B ? C : A, by reversing the comparison first. + A op B ? A : C, where (ARG00, COMP_CODE, ARG01), ARG1 and ARG2 + are the three operands of the COND_EXPR. This function is + being used also to optimize A op B ? C : A, by reversing the + comparison first. Return a folded expression whose code is not a COND_EXPR anymore, or NULL_TREE if no folding opportunity is found. */ static tree fold_cond_expr_with_comparison (location_t loc, tree type, - tree arg0, tree arg1, tree arg2) + enum tree_code comp_code, + tree arg00, tree arg01, tree arg1, tree arg2) { - enum tree_code comp_code = TREE_CODE (arg0); - tree arg00 = TREE_OPERAND (arg0, 0); - tree arg01 = TREE_OPERAND (arg0, 1); tree arg1_type = TREE_TYPE (arg1); tree tem; @@ -12821,7 +12821,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1) && !HONOR_SIGNED_ZEROS (element_mode (op1))) { - tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2); + tem = fold_cond_expr_with_comparison (loc, type, TREE_CODE (arg0), + TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg0, 1), + op1, op2); if (tem) return tem; } @@ -12830,14 +12833,16 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op2) && !HONOR_SIGNED_ZEROS (element_mode (op2))) { - location_t loc0 = expr_location_or (arg0, loc); - tem = fold_invert_truthvalue (loc0, arg0); - if (tem && COMPARISON_CLASS_P (tem)) - { - tem = fold_cond_expr_with_comparison (loc, type, tem, op2, op1); - if (tem) - return tem; - } + enum tree_code comp_code = TREE_CODE (arg0); + tree arg00 = TREE_OPERAND (arg0, 0); + tree arg01 = TREE_OPERAND (arg0, 1); + comp_code = invert_tree_comparison (comp_code, HONOR_NANS (arg00)); + tem = fold_cond_expr_with_comparison (loc, type, comp_code, + arg00, + arg01, + op2, op1); + if (tem) + return tem; } /* If the second operand is simpler than the third, swap them -- cgit v1.1 From fbad6c62529fd2e5dcf9f7db884cee01e9dcc4bd Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Fri, 18 Jun 2021 17:55:51 -0700 Subject: Reset the range info on the moved instruction in PHIOPT I had missed this when wrote the patch which allowed the gimple to be moved from inside the conditional as it. It was also missed in the review. Anyways the range information needs to be reset for the moved gimple as it was under a conditional and the flow has changed to be unconditional. I have not seen any testcase in the wild that produces wrong code yet which is why there is no testcase but this is similar to what the other code in phiopt does so after moving those to match, there might be some. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * tree-ssa-phiopt.c (match_simplify_replacement): Reset flow senatitive info on the moved ssa set. --- gcc/tree-ssa-phiopt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index ce5f0d5..1777bff 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -836,7 +836,7 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, if (!is_gimple_assign (stmt_to_move)) return false; - tree lhs = gimple_assign_lhs (stmt_to_move); + tree lhs = gimple_assign_lhs (stmt_to_move); gimple *use_stmt; use_operand_p use_p; @@ -892,6 +892,7 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, } gimple_stmt_iterator gsi1 = gsi_for_stmt (stmt_to_move); gsi_move_before (&gsi1, &gsi); + reset_flow_sensitive_info (gimple_assign_lhs (stmt_to_move)); } if (seq) gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); -- cgit v1.1 From 2afe882858699bb6c13f8502f4f6e862a126d4ef Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 12 Jun 2021 18:58:03 -0700 Subject: Lower for loops before lowering cond in genmatch While converting some fold_cond_expr_with_comparison to match, I found that I wanted to use "for cnd (cond vec_cond)" but that was not causing the lowering of cond to happen. What was happening was the lowering of the for loop was happening after the lowering of the cond. So swapping was the correct thing to do but it also means we need to copy for_subst_vec in lower_cond. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * genmatch.c (lower_cond): Copy for_subst_vec for the simplify also. (lower): Swap the order for lower_for and lower_cond. --- gcc/genmatch.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 4d47672..970a2eb 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -1306,6 +1306,7 @@ lower_cond (simplify *s, vec& simplifiers) { simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result, s->for_vec, s->capture_ids); + ns->for_subst_vec.safe_splice (s->for_subst_vec); simplifiers.safe_push (ns); } } @@ -1543,24 +1544,27 @@ static void lower (vec& simplifiers, bool gimple) { auto_vec out_simplifiers; - for (unsigned i = 0; i < simplifiers.length (); ++i) - lower_opt (simplifiers[i], out_simplifiers); + for (auto s: simplifiers) + lower_opt (s, out_simplifiers); simplifiers.truncate (0); - for (unsigned i = 0; i < out_simplifiers.length (); ++i) - lower_commutative (out_simplifiers[i], simplifiers); + for (auto s: out_simplifiers) + lower_commutative (s, simplifiers); + /* Lower for needs to happen before lowering cond + to support (for cnd (cond vec_cond)). This is + safe as substitution delay does not happen for + cond or vec_cond. */ out_simplifiers.truncate (0); - if (gimple) - for (unsigned i = 0; i < simplifiers.length (); ++i) - lower_cond (simplifiers[i], out_simplifiers); - else - out_simplifiers.safe_splice (simplifiers); - + for (auto s: simplifiers) + lower_for (s, out_simplifiers); simplifiers.truncate (0); - for (unsigned i = 0; i < out_simplifiers.length (); ++i) - lower_for (out_simplifiers[i], simplifiers); + if (gimple) + for (auto s: out_simplifiers) + lower_cond (s, simplifiers); + else + simplifiers.safe_splice (out_simplifiers); } -- cgit v1.1 From 2168bfb81448ae1bfa4351760a23d4ec051c2a00 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 24 Jun 2021 17:32:02 -0400 Subject: c++: constexpr aggr init of empty class [PR101040] This is basically the aggregate initializer version of PR97566; as in that bug, we are trying to initialize empty field 'obj' in 'single' when there's no CONSTRUCTOR entry for the 'single' base class subobject of 'derived'. As with that bug, the fix is to stop trying to add entries for empty fields, this time in cxx_eval_bare_aggregate. The change to the other function isn't necessary for this version of the patch, but seems worthwhile for robustness anyway. PR c++/101040 PR c++/97566 gcc/cp/ChangeLog: * class.c (is_empty_field): Handle null argument. * constexpr.c (cxx_eval_bare_aggregate): Discard initializer for empty field. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/no_unique_address13.C: New test. --- gcc/cp/class.c | 2 +- gcc/cp/constexpr.c | 9 ++++++++- gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c89ffad..33093e1 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4220,7 +4220,7 @@ field_poverlapping_p (tree decl) bool is_empty_field (tree decl) { - if (TREE_CODE (decl) != FIELD_DECL) + if (!decl || TREE_CODE (decl) != FIELD_DECL) return false; bool r = (is_empty_class (TREE_TYPE (decl)) diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index a26aead..4cd9db3 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4449,7 +4449,12 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value) { tree orig_value = value; - init_subob_ctx (ctx, new_ctx, index, value); + /* Like in cxx_eval_store_expression, omit entries for empty fields. */ + bool no_slot = TREE_CODE (type) == RECORD_TYPE && is_empty_field (index); + if (no_slot) + new_ctx = *ctx; + else + init_subob_ctx (ctx, new_ctx, index, value); int pos_hint = -1; if (new_ctx.ctor != ctx->ctor) { @@ -4495,6 +4500,8 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t, gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index)))); changed = true; } + else if (no_slot) + changed = true; else { if (TREE_CODE (type) == UNION_TYPE diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C b/gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C new file mode 100644 index 0000000..66b83d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C @@ -0,0 +1,24 @@ +// PR c++/101040 +// { dg-do compile { target c++11 } } + +// This class has to be empty. +struct empty +{}; + +// This class has to be empty. +struct single +{ + // This member has to be no_unique_address. + [[no_unique_address]] empty obj; +}; + +// This class has to be empty and derived from single. +struct derived : single +{ + // This constructor has to be constexpr and take a forwarding reference. + template + constexpr derived(Arg&& arg) : single{arg} + {} +}; + +auto obj = derived{empty{}}; -- cgit v1.1 From 5b1ce655b25040048861af6c0264cb667b66fcd7 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 24 Jun 2021 10:37:42 -0400 Subject: except: remove dwarf2out.h dependency When thinking about the CTF debug patchset dwarf2out.h split, I noticed that except.c only needs macros from dwarf2.h, nothing from dwarf2out.h. gcc/ChangeLog: * except.c: #include "dwarf2.h" instead of "dwarf2out.h". --- gcc/except.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/except.c b/gcc/except.c index d481a5e..8e905a3 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -136,7 +136,7 @@ along with GCC; see the file COPYING3. If not see #include "except.h" #include "output.h" #include "dwarf2asm.h" -#include "dwarf2out.h" +#include "dwarf2.h" #include "common/common-target.h" #include "langhooks.h" #include "cfgrtl.h" -- cgit v1.1 From 9f26e34a5a9614a5b66f146752ecef9ea67b3e2d Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Sat, 26 Jun 2021 11:05:54 -0400 Subject: c++: access scope during partial spec matching [PR96204] Here, when determining whether the partial specialization matches has_type_member, we do so from the scope of where the template-id appears rather than from the scope of the specialization, and this causes us to select the partial specialization (since Child::type is accessible from Parent). When we later instantiate this partial specialization, we've entered the scope of the specialization and so substitution into e.g. the DECL_CONTEXT of has_type_member::value fails with access errors since the friend declaration that we relied on to choose the partial specialization no longer applies. It seems the appropriate access scope from which to perform partial specialization matching is the specialization itself (similar to how we check access of base-clauses), which is what this patch implements. PR c++/96204 gcc/cp/ChangeLog: * pt.c (instantiate_class_template_1): Enter the scope of the type when calling most_specialized_partial_spec. gcc/testsuite/ChangeLog: * g++.dg/template/access40.C: New test. * g++.dg/template/access40a.C: New test. --- gcc/cp/pt.c | 5 ++++- gcc/testsuite/g++.dg/template/access40.C | 28 ++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/template/access40a.C | 28 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/access40.C create mode 100644 gcc/testsuite/g++.dg/template/access40a.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e5a2a2c..f2039e0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11769,8 +11769,11 @@ instantiate_class_template_1 (tree type) deferring_access_check_sentinel acs (dk_no_deferred); /* Determine what specialization of the original template to - instantiate. */ + instantiate; do this relative to the scope of the class for + sake of access checking. */ + push_nested_class (type); t = most_specialized_partial_spec (type, tf_warning_or_error); + pop_nested_class (); if (t == error_mark_node) return error_mark_node; else if (t) diff --git a/gcc/testsuite/g++.dg/template/access40.C b/gcc/testsuite/g++.dg/template/access40.C new file mode 100644 index 0000000..d035e99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access40.C @@ -0,0 +1,28 @@ +// PR c++/96204 + +template +struct has_type_member { + static const bool value = false; +}; + +template +struct has_type_member { + static const bool value = true; +}; + +struct Parent; + +struct Child { +private: + friend struct Parent; + typedef void type; +}; + +struct Parent { + static void f() { + // The partial specialization does not match despite Child::type + // being accessible from the current scope. + extern int x[1]; + extern int x[!has_type_member::value]; + } +}; diff --git a/gcc/testsuite/g++.dg/template/access40a.C b/gcc/testsuite/g++.dg/template/access40a.C new file mode 100644 index 0000000..94025c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access40a.C @@ -0,0 +1,28 @@ +// PR c++/96204 + +template +struct has_type_member { + static const bool value = false; +}; + +template +struct has_type_member { + static const bool value = true; +}; + +struct Parent; + +struct Child { +private: + friend struct has_type_member; + typedef void type; +}; + +struct Parent { + static void f() { + // The partial specialization matches because has_type_member + // is a friend of Child. + extern int x[1]; + extern int x[has_type_member::value]; + } +}; -- cgit v1.1 From 461f937b47278eaa4ca3c5507c80cca26af4b015 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 27 Jun 2021 00:16:24 +0000 Subject: Daily bump. --- gcc/ChangeLog | 23 +++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/cp/ChangeLog | 14 ++++++++++++++ gcc/testsuite/ChangeLog | 12 ++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d58c034..7a590fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2021-06-26 Jason Merrill + + * except.c: #include "dwarf2.h" instead of "dwarf2out.h". + +2021-06-26 Andrew Pinski + + * genmatch.c (lower_cond): Copy for_subst_vec + for the simplify also. + (lower): Swap the order for lower_for and lower_cond. + +2021-06-26 Andrew Pinski + + * tree-ssa-phiopt.c (match_simplify_replacement): Reset + flow senatitive info on the moved ssa set. + +2021-06-26 Andrew Pinski + + * fold-const.c (fold_cond_expr_with_comparison): + Exand arg0 into comp_code, arg00, and arg01. + (fold_ternary_loc): Use invert_tree_comparison + instead of fold_invert_truthvalue for the case + where we have A CMP B ? C : A. + 2021-06-25 Martin Sebor PR middle-end/101216 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ed547dc..cddb984 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210626 +20210627 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c53fb0c..3791ac4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2021-06-26 Patrick Palka + + PR c++/96204 + * pt.c (instantiate_class_template_1): Enter the scope of the + type when calling most_specialized_partial_spec. + +2021-06-26 Jason Merrill + + PR c++/101040 + PR c++/97566 + * class.c (is_empty_field): Handle null argument. + * constexpr.c (cxx_eval_bare_aggregate): Discard initializer + for empty field. + 2021-06-26 Marek Polacek PR c++/100752 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 80322a4..f9b08d8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2021-06-26 Patrick Palka + + PR c++/96204 + * g++.dg/template/access40.C: New test. + * g++.dg/template/access40a.C: New test. + +2021-06-26 Jason Merrill + + PR c++/101040 + PR c++/97566 + * g++.dg/cpp2a/no_unique_address13.C: New test. + 2021-06-26 Marek Polacek PR c++/100752 -- cgit v1.1 From 3966726333b2a4cf54333549c8331d833364266e Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Thu, 24 Jun 2021 15:40:25 -0400 Subject: aix: Add AIX 7.3 configuration and SPDX License Identifiers. The anticipated release of AIX 7.3 has been announced. This patch adds the configuration bits based on AIX 7.2 configuration. gcc/ChangeLog: * config.gcc: Add SPDX License Identifier. (powerpc-ibm-aix789): Default to aix73.h. (powerpc-ibm-aix7.2.*.*): New stanza. * config/rs6000/aix72.h: Add SPDX License Identifier. * config/rs6000/aix73.h: New file. --- gcc/config.gcc | 16 ++- gcc/config/rs6000/aix72.h | 5 +- gcc/config/rs6000/aix73.h | 294 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 gcc/config/rs6000/aix73.h diff --git a/gcc/config.gcc b/gcc/config.gcc index 1be8d96..0230bb8 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-3.0-or-later # GCC target-specific configuration file. # Copyright (C) 1997-2021 Free Software Foundation, Inc. @@ -3099,7 +3100,7 @@ rs6000-ibm-aix7.1.* | powerpc-ibm-aix7.1.*) use_gcc_stdint=wrap default_use_cxa_atexit=yes ;; -rs6000-ibm-aix[789].* | powerpc-ibm-aix[789].*) +rs6000-ibm-aix7.2.* | powerpc-ibm-aix7.2.*) tmake_file="rs6000/t-aix52 t-slibgcc" if test x$cpu_is_64bit = xyes; then tm_file="${tm_file} rs6000/biarch64.h" @@ -3112,6 +3113,19 @@ rs6000-ibm-aix[789].* | powerpc-ibm-aix[789].*) use_gcc_stdint=wrap default_use_cxa_atexit=yes ;; +rs6000-ibm-aix[789].* | powerpc-ibm-aix[789].*) + tmake_file="rs6000/t-aix52 t-slibgcc" + if test x$cpu_is_64bit = xyes; then + tm_file="${tm_file} rs6000/biarch64.h" + tmake_file="rs6000/t-aix64 t-slibgcc" + fi + tm_file="${tm_file} rs6000/aix.h rs6000/aix73.h rs6000/xcoff.h rs6000/aix-stdint.h" + extra_options="${extra_options} rs6000/aix64.opt" + use_collect2=yes + thread_file='aix' + use_gcc_stdint=wrap + default_use_cxa_atexit=yes + ;; rl78-*-elf*) tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}" target_has_targetm_common=no diff --git a/gcc/config/rs6000/aix72.h b/gcc/config/rs6000/aix72.h index 4cd27e3..a497a7d 100644 --- a/gcc/config/rs6000/aix72.h +++ b/gcc/config/rs6000/aix72.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0-or-later /* Definitions of target machine for GNU compiler, for IBM RS/6000 POWER running AIX V7.2. Copyright (C) 2002-2021 Free Software Foundation, Inc. @@ -124,7 +125,7 @@ do { \ %{mpe: -I%R/usr/lpp/ppe.poe/include} \ %{pthread: -D_THREAD_SAFE}" -/* The GNU C++ standard library requires that these macros be +/* The GNU C++ standard library requires that these macros be defined. Synchronize with libstdc++ os_defines.h. */ #define CPLUSPLUS_CPP_SPEC_COMMON \ "-D_ALL_SOURCE -D__COMPATMATH__ \ @@ -254,7 +255,7 @@ do { \ #define LD_INIT_SWITCH "-binitfini" #ifndef _AIX52 -extern long long int atoll(const char *); +extern long long int atoll(const char *); #endif /* This target uses the aix64.opt file. */ diff --git a/gcc/config/rs6000/aix73.h b/gcc/config/rs6000/aix73.h new file mode 100644 index 0000000..c707c7e --- /dev/null +++ b/gcc/config/rs6000/aix73.h @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX V7.3. + Copyright (C) 2002-2021 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "%<-maix64%> requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ + { \ + rs6000_long_double_type_size = 64; \ + if (global_options_set.x_rs6000_long_double_type_size) \ + warning (0, "soft-float and long-double-128 are incompatible"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("%<-maix64%> required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ + if ((rs6000_isa_flags_explicit \ + & OPTION_MASK_MINIMAL_TOC) != 0) \ + { \ + if (global_options_set.x_rs6000_current_cmodel \ + && rs6000_current_cmodel != CMODEL_SMALL) \ + error ("%<-mcmodel%> incompatible with other toc options"); \ + SET_CMODEL (CMODEL_SMALL); \ + } \ + if (rs6000_current_cmodel != CMODEL_SMALL) \ + { \ + TARGET_NO_FP_IN_TOC = 1; \ + TARGET_NO_SUM_IN_TOC = 1; \ + } \ + if (rs6000_current_cmodel == CMODEL_MEDIUM) \ + { \ + rs6000_current_cmodel = CMODEL_LARGE; \ + } \ + if (! strcmp (lang_hooks.name, "GNU Go") \ + && TARGET_32BIT) \ + { \ + /* aix/ppc doesn't support -mvsx and -maltivec with Go */ \ + rs6000_isa_flags &= ~(OPTION_MASK_VSX | OPTION_MASK_ALTIVEC); \ + } \ + if (!global_options_set.x_dwarf_version) \ + /* AIX only supports DWARF 4. */ \ + dwarf_version = 4; \ +} while (0) + +#define ASM_SPEC32 "-a32" +#define ASM_SPEC64 "-a64" +#define ASM_SPEC_COMMON "-u %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst the various targets for + handling -mcpu=xxx switches. There is a parallel list in driver-rs6000.c to + provide the default assembler options if the user uses -mcpu=native, so if + you make changes here, make them there also. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{mcpu=native: %(asm_cpu_native); \ + mcpu=power10: -mpwr10; \ + mcpu=power9: -mpwr9; \ + mcpu=power8: -mpwr8; \ + mcpu=power7: -mpwr7; \ + mcpu=power6x|mcpu=power6: -mpwr6; \ + mcpu=power5+: -mpwr5x; \ + mcpu=power5: -mpwr5; \ + mcpu=power4: -mpwr4; \ + mcpu=power3: -m620; \ + mcpu=powerpc: -mppc; \ + mcpu=rs64: -mppc; \ + mcpu=603: -m603; \ + mcpu=603e: -m603; \ + mcpu=604: -m604; \ + mcpu=604e: -m604; \ + mcpu=620: -m620; \ + mcpu=630: -m620; \ + mcpu=970|mcpu=G5: -m970; \ + !mcpu*: %(asm_default)} \ +-many" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mpwr7" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + builtin_define ("_AIX51"); \ + builtin_define ("_AIX52"); \ + builtin_define ("_AIX53"); \ + builtin_define ("_AIX61"); \ + builtin_define ("_AIX71"); \ + builtin_define ("_AIX72"); \ + builtin_define ("_AIX73"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#define CPP_SPEC32 "" +#define CPP_SPEC64 "-D__64BIT__" +#define CPP_SPEC_COMMON "%{posix: -D_POSIX_SOURCE} \ + %{ansi: -D_ANSI_C_SOURCE} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. Synchronize with libstdc++ os_defines.h. */ +#define CPLUSPLUS_CPP_SPEC_COMMON \ + "-D_ALL_SOURCE -D__COMPATMATH__ \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#define RS6000_CPU(NAME, CPU, FLAGS) +#include "rs6000-cpus.def" +#undef RS6000_CPU + +#undef TARGET_DEFAULT +#ifdef RS6000_BI_ARCH +#define TARGET_DEFAULT (ISA_2_6_MASKS_EMBEDDED | MASK_POWERPC64 | MASK_64BIT) +#else +#define TARGET_DEFAULT ISA_2_6_MASKS_EMBEDDED +#endif + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER7 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER7 + +/* AIX 7.2 kernel and assembler have necessary support for Altivec and VSX. */ +#undef OS_MISSING_ALTIVEC + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS + +#define DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT) + +#define LIB_SPEC32 "%{!shared:%{g*:-lg}}" +#define LIB_SPEC64 "" +#define LIB_SPEC_COMMON "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{fprofile-arcs|fprofile-generate*|coverage:-lpthreads}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{mlong-double-128:-lc128}\ + %{pthread:-lpthreads} -lc" + +#define LINK_SPEC32 "%{!shared:%{g*: %(link_libg) }} -b32" +#define LINK_SPEC64 "-b64" +#define LINK_SPEC_COMMON "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{mpe:-binitfini:poe_remote_main} " + +#undef STARTFILE_SPEC +#if DEFAULT_ARCH64_P +#define STARTFILE_SPEC "%{!shared:\ + %{!maix32:%{pg:gcrt0_64%O%s;:%{p:mcrt0_64%O%s;:crt0_64%O%s}};:\ + %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ + %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ + %{!maix32:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" +#else +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s;:%{p:mcrt0_64%O%s;:crt0_64%O%s}};:\ + %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ + %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ + %{maix64:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" +#endif + + +#undef ASM_SPEC +#undef CPP_SPEC +#undef CPLUSPLUS_CPP_SPEC +#undef LIB_SPEC +#undef LINK_SPEC + +#if DEFAULT_ARCH64_P +#define ASM_SPEC "%{maix32:%(asm_spec32);:%(asm_spec64)} %(asm_spec_common)" +#define CPP_SPEC "%{maix32:%(cpp_spec32);:%(cpp_spec64)} %(cpp_spec_common)" +#define CPLUSPLUS_CPP_SPEC "%{maix32:%(cpp_spec32);:%(cpp_spec64)} %(cplusplus_cpp_spec_common)" +#define LIB_SPEC "%{maix32:%(lib_spec32);:%(lib_spec64)} %(lib_spec_common)" +#define LINK_SPEC "%{maix32:%(link_spec32);:%(link_spec64)} %(link_spec_common)" +#else +#define ASM_SPEC "%{maix64:%(asm_spec64);:%(asm_spec32)} %(asm_spec_common)" +#define CPP_SPEC "%{maix64:%(cpp_spec64);:%(cpp_spec32)} %(cpp_spec_common)" +#define CPLUSPLUS_CPP_SPEC "%{maix64:%(cpp_spec64);:%(cpp_spec32)} %(cplusplus_cpp_spec_common)" +#define LIB_SPEC "%{maix64:%(lib_spec64);:%(lib_spec32)} %(lib_spec_common)" +#define LINK_SPEC "%{maix64:%(link_spec64);:%(link_spec32)} %(link_spec_common)" +#endif + +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + { "asm_spec_common", ASM_SPEC_COMMON }, \ + { "asm_spec32", ASM_SPEC32 }, \ + { "asm_spec64", ASM_SPEC64 }, \ + { "cpp_spec_common", CPP_SPEC_COMMON }, \ + { "cplusplus_cpp_spec_common", CPLUSPLUS_CPP_SPEC_COMMON }, \ + { "cpp_spec32", CPP_SPEC32 }, \ + { "cpp_spec64", CPP_SPEC64 }, \ + { "lib_spec_common", LIB_SPEC_COMMON }, \ + { "lib_spec32", LIB_SPEC32 }, \ + { "lib_spec64", LIB_SPEC64 }, \ + { "link_spec_common", LINK_SPEC_COMMON }, \ + { "link_spec32", LINK_SPEC32 }, \ + { "link_spec64", LINK_SPEC64 }, + +/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Type used for wchar_t, as a string used in a declaration. */ +#undef WCHAR_TYPE +#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") + +/* Width of wchar_t in bits. */ +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +#ifndef _AIX52 +extern long long int atoll(const char *); +#endif + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +/* Large TOC Support */ +#ifdef HAVE_LD_LARGE_TOC +#undef TARGET_CMODEL +#define TARGET_CMODEL rs6000_current_cmodel +#define SET_CMODEL(opt) rs6000_current_cmodel = opt +#else +#define SET_CMODEL(opt) do {} while (0) +#endif + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_AIX_VERSION 72 + +/* AIX 7.2 supports DWARF3+ debugging. */ +#define DWARF2_DEBUGGING_INFO 1 +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG +#define DEBUG_INFO_SECTION "0x10000" +#define DEBUG_LINE_SECTION "0x20000" +#define DEBUG_PUBNAMES_SECTION "0x30000" +#define DEBUG_PUBTYPES_SECTION "0x40000" +#define DEBUG_ARANGES_SECTION "0x50000" +#define DEBUG_ABBREV_SECTION "0x60000" +#define DEBUG_STR_SECTION "0x70000" +#define DEBUG_RANGES_SECTION "0x80000" +#define DEBUG_LOC_SECTION "0x90000" +#define DEBUG_FRAME_SECTION "0xA0000" +#define DEBUG_MACINFO_SECTION "0xB0000" +#define DEBUG_MACRO_SECTION "0xB0000" + -- cgit v1.1 From 37ad257c06d88fdb810be336d212c1ab54b99dad Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sun, 27 Jun 2021 13:14:48 -0700 Subject: Fix PR 101230: ICE in fold_cond_expr_with_comparison This fixes PR 101230 where I had messed up and forgot that invert_tree_comparison can return ERROR_MARK if the comparsion is not invertable (floating point types). Committed as obvious after a bootstrap/test on x86_64-linux-gnu-gnu gcc/ChangeLog: PR middle-end/101230 * fold-const.c (fold_ternary_loc): Check the return value of invert_tree_comparison. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr101230-1.c: New test. --- gcc/fold-const.c | 9 +++++---- gcc/testsuite/gcc.dg/torture/pr101230-1.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101230-1.c diff --git a/gcc/fold-const.c b/gcc/fold-const.c index e2110b6..dfccbae 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -12837,10 +12837,11 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, tree arg00 = TREE_OPERAND (arg0, 0); tree arg01 = TREE_OPERAND (arg0, 1); comp_code = invert_tree_comparison (comp_code, HONOR_NANS (arg00)); - tem = fold_cond_expr_with_comparison (loc, type, comp_code, - arg00, - arg01, - op2, op1); + if (comp_code != ERROR_MARK) + tem = fold_cond_expr_with_comparison (loc, type, comp_code, + arg00, + arg01, + op2, op1); if (tem) return tem; } diff --git a/gcc/testsuite/gcc.dg/torture/pr101230-1.c b/gcc/testsuite/gcc.dg/torture/pr101230-1.c new file mode 100644 index 0000000..f10ca8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101230-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fno-signed-zeros" } */ + + +double distance3d_sqr_pt4d_pt4d(void); + +int update_r_k_curr_cluster; +void update_r_k(void) { + double curr_distance = distance3d_sqr_pt4d_pt4d(); + for (int cluster; cluster; cluster++) + if (0 < curr_distance) { + curr_distance = 0; + update_r_k_curr_cluster = cluster; + } +} -- cgit v1.1 From a766c79fc64bba66f16adfe1c8639b5857219f4d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 28 Jun 2021 00:16:30 +0000 Subject: Daily bump. --- gcc/ChangeLog | 14 ++++++++++++++ gcc/DATESTAMP | 2 +- gcc/testsuite/ChangeLog | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a590fb..cf73c34 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2021-06-27 Andrew Pinski + + PR middle-end/101230 + * fold-const.c (fold_ternary_loc): Check + the return value of invert_tree_comparison. + +2021-06-27 David Edelsohn + + * config.gcc: Add SPDX License Identifier. + (powerpc-ibm-aix789): Default to aix73.h. + (powerpc-ibm-aix7.2.*.*): New stanza. + * config/rs6000/aix72.h: Add SPDX License Identifier. + * config/rs6000/aix73.h: New file. + 2021-06-26 Jason Merrill * except.c: #include "dwarf2.h" instead of "dwarf2out.h". diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index cddb984..47b060d5 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210627 +20210628 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9b08d8..241fec5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2021-06-27 Andrew Pinski + + * gcc.dg/torture/pr101230-1.c: New test. + 2021-06-26 Patrick Palka PR c++/96204 -- cgit v1.1 From 28560c6d4043d8f6ac570f35fb84e952e9c719fe Mon Sep 17 00:00:00 2001 From: liuhongt Date: Fri, 21 May 2021 09:48:18 +0800 Subject: Fold blendv builtins into gimple. Fold __builtin_ia32_pblendvb128 (a, b, c) as VEC_COND_EXPR (c < 0, b, a), similar for float version but with mask operand VIEW_CONVERT_EXPR to same sized integer vectype. gcc/ChangeLog: * config/i386/i386-builtin.def (IX86_BUILTIN_BLENDVPD256, IX86_BUILTIN_BLENDVPS256, IX86_BUILTIN_PBLENDVB256, IX86_BUILTIN_BLENDVPD, IX86_BUILTIN_BLENDVPS, IX86_BUILTIN_PBLENDVB128): Replace icode with CODE_FOR_nothing. * config/i386/i386.c (ix86_gimple_fold_builtin): Fold blendv builtins. * config/i386/sse.md (*_pblendvb_lt_subreg_not): New pre_reload splitter. gcc/testsuite/ChangeLog: * gcc.target/i386/funcspec-8.c: Replace __builtin_ia32_blendvpd with __builtin_ia32_roundps_az. * gcc.target/i386/blendv-1.c: New test. * gcc.target/i386/blendv-2.c: New test. --- gcc/config/i386/i386-builtin.def | 12 +++---- gcc/config/i386/i386.c | 37 ++++++++++++++++++++++ gcc/config/i386/sse.md | 22 +++++++++++++ gcc/testsuite/gcc.target/i386/blendv-1.c | 51 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/blendv-2.c | 41 ++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/funcspec-8.c | 16 +++++----- 6 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/blendv-1.c create mode 100644 gcc/testsuite/gcc.target/i386/blendv-2.c diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index ea79e0b..1cc0cc6 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -902,13 +902,13 @@ BDESC (OPTION_MASK_ISA_SSSE3 | OPTION_MASK_ISA_MMX, 0, CODE_FOR_ssse3_palignrdi, /* SSE4.1 */ BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_blendpd, "__builtin_ia32_blendpd", IX86_BUILTIN_BLENDPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_blendps, "__builtin_ia32_blendps", IX86_BUILTIN_BLENDPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT) -BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_blendvpd, "__builtin_ia32_blendvpd", IX86_BUILTIN_BLENDVPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_V2DF) -BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_blendvps, "__builtin_ia32_blendvps", IX86_BUILTIN_BLENDVPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_V4SF) +BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_nothing, "__builtin_ia32_blendvpd", IX86_BUILTIN_BLENDVPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_V2DF) +BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_nothing, "__builtin_ia32_blendvps", IX86_BUILTIN_BLENDVPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_V4SF) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_dppd, "__builtin_ia32_dppd", IX86_BUILTIN_DPPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_dpps, "__builtin_ia32_dpps", IX86_BUILTIN_DPPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_insertps, "__builtin_ia32_insertps128", IX86_BUILTIN_INSERTPS128, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_mpsadbw, "__builtin_ia32_mpsadbw128", IX86_BUILTIN_MPSADBW128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_INT) -BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_pblendvb, "__builtin_ia32_pblendvb128", IX86_BUILTIN_PBLENDVB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI) +BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_nothing, "__builtin_ia32_pblendvb128", IX86_BUILTIN_PBLENDVB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_pblendw, "__builtin_ia32_pblendw128", IX86_BUILTIN_PBLENDW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_INT) BDESC (OPTION_MASK_ISA_SSE4_1, 0, CODE_FOR_sse4_1_sign_extendv8qiv8hi2, "__builtin_ia32_pmovsxbw128", IX86_BUILTIN_PMOVSXBW128, UNKNOWN, (int) V8HI_FTYPE_V16QI) @@ -1028,8 +1028,8 @@ BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_vpermilvarv8sf3, "__builtin_ia32_vpe BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendpd256, "__builtin_ia32_blendpd256", IX86_BUILTIN_BLENDPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_INT) BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendps256, "__builtin_ia32_blendps256", IX86_BUILTIN_BLENDPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT) -BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendvpd256, "__builtin_ia32_blendvpd256", IX86_BUILTIN_BLENDVPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_V4DF) -BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_blendvps256, "__builtin_ia32_blendvps256", IX86_BUILTIN_BLENDVPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_V8SF) +BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin_ia32_blendvpd256", IX86_BUILTIN_BLENDVPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_V4DF) +BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin_ia32_blendvps256", IX86_BUILTIN_BLENDVPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_V8SF) BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_dpps256, "__builtin_ia32_dpps256", IX86_BUILTIN_DPPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT) BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_shufpd256, "__builtin_ia32_shufpd256", IX86_BUILTIN_SHUFPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_INT) BDESC (OPTION_MASK_ISA_AVX, 0, CODE_FOR_avx_shufps256, "__builtin_ia32_shufps256", IX86_BUILTIN_SHUFPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT) @@ -1154,7 +1154,7 @@ BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_andv4di3, "__builtin_ia32_andsi256", IX BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_avx2_andnotv4di3, "__builtin_ia32_andnotsi256", IX86_BUILTIN_ANDNOT256I, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI) BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_avx2_uavgv32qi3, "__builtin_ia32_pavgb256", IX86_BUILTIN_PAVGB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI) BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_avx2_uavgv16hi3, "__builtin_ia32_pavgw256", IX86_BUILTIN_PAVGW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI) -BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_avx2_pblendvb, "__builtin_ia32_pblendvb256", IX86_BUILTIN_PBLENDVB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI) +BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_nothing, "__builtin_ia32_pblendvb256", IX86_BUILTIN_PBLENDVB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI) BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_avx2_pblendw, "__builtin_ia32_pblendw256", IX86_BUILTIN_PBLENDVW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_INT) BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_nothing, "__builtin_ia32_pcmpeqb256", IX86_BUILTIN_PCMPEQB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI) BDESC (OPTION_MASK_ISA_AVX2, 0, CODE_FOR_nothing, "__builtin_ia32_pcmpeqw256", IX86_BUILTIN_PCMPEQW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c71c9e6..a93128f 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -17983,6 +17983,43 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi) } break; + case IX86_BUILTIN_PBLENDVB128: + case IX86_BUILTIN_PBLENDVB256: + case IX86_BUILTIN_BLENDVPS: + case IX86_BUILTIN_BLENDVPD: + case IX86_BUILTIN_BLENDVPS256: + case IX86_BUILTIN_BLENDVPD256: + gcc_assert (n_args == 3); + arg0 = gimple_call_arg (stmt, 0); + arg1 = gimple_call_arg (stmt, 1); + arg2 = gimple_call_arg (stmt, 2); + if (gimple_call_lhs (stmt)) + { + location_t loc = gimple_location (stmt); + tree type = TREE_TYPE (arg2); + gimple_seq stmts = NULL; + if (VECTOR_FLOAT_TYPE_P (type)) + { + tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode + ? intSI_type_node : intDI_type_node; + type = get_same_sized_vectype (itype, type); + arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2); + } + tree zero_vec = build_zero_cst (type); + tree cmp_type = truth_type_for (type); + tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec); + gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); + gimple *g = gimple_build_assign (gimple_call_lhs (stmt), + VEC_COND_EXPR, cmp, + arg1, arg0); + gimple_set_location (g, loc); + gsi_replace (gsi, g, false); + } + else + gsi_replace (gsi, gimple_build_nop (), false); + return true; + + case IX86_BUILTIN_PCMPEQB128: case IX86_BUILTIN_PCMPEQW128: case IX86_BUILTIN_PCMPEQD128: diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index e4f01e6..3100635 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -17898,6 +17898,28 @@ (set_attr "btver2_decode" "vector,vector,vector") (set_attr "mode" "")]) +(define_insn_and_split "*_pblendvb_lt_subreg_not" + [(set (match_operand:VI1_AVX2 0 "register_operand") + (unspec:VI1_AVX2 + [(match_operand:VI1_AVX2 2 "vector_operand") + (match_operand:VI1_AVX2 1 "register_operand") + (lt:VI1_AVX2 + (subreg:VI1_AVX2 + (not (match_operand 3 "register_operand")) 0) + (match_operand:VI1_AVX2 4 "const0_operand"))] + UNSPEC_BLENDV))] + "TARGET_SSE4_1 + && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_VECTOR_INT + && GET_MODE_SIZE (GET_MODE (operands[3])) == + && ix86_pre_reload_split ()" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:VI1_AVX2 + [(match_dup 1) (match_dup 2) + (lt:VI1_AVX2 (match_dup 3) (match_dup 4))] UNSPEC_BLENDV))] + "operands[3] = gen_lowpart (mode, operands[3]);") + (define_insn "sse4_1_pblendw" [(set (match_operand:V8HI 0 "register_operand" "=Yr,*x,x") (vec_merge:V8HI diff --git a/gcc/testsuite/gcc.target/i386/blendv-1.c b/gcc/testsuite/gcc.target/i386/blendv-1.c new file mode 100644 index 0000000..fcbbfb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/blendv-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O2 -mno-avx512f" } */ +/* { dg-final { scan-assembler-times {pblendvb[\t ]*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {pblendvb[\t ]*%ymm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvps[\t ]*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvps[\t ]*%ymm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvpd[\t ]*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvpd[\t ]*%ymm} 1 } } */ + +typedef float v4sf __attribute__ ((vector_size (16))); +typedef float v8sf __attribute__ ((vector_size (32))); +typedef double v2df __attribute__ ((vector_size (16))); +typedef double v4df __attribute__ ((vector_size (32))); +typedef char v16qi __attribute__ ((vector_size (16))); +typedef char v32qi __attribute__ ((vector_size (32))); + +v4sf +foo (v4sf a, v4sf b, v4sf c) +{ + return __builtin_ia32_blendvps (a, b, c); +} + +v8sf +foo2 (v8sf a, v8sf b, v8sf c) +{ + return __builtin_ia32_blendvps256 (a, b, c); +} + +v2df +foo3 (v2df a, v2df b, v2df c) +{ + return __builtin_ia32_blendvpd (a, b, c); +} + +v4df +foo4 (v4df a, v4df b, v4df c) +{ + return __builtin_ia32_blendvpd256 (a, b, c); +} + +v16qi +foo5 (v16qi a, v16qi b, v16qi c) +{ + return __builtin_ia32_pblendvb128 (a, b, c); +} + +v32qi +foo6 (v32qi a, v32qi b, v32qi c) +{ + return __builtin_ia32_pblendvb256 (a, b, c); +} diff --git a/gcc/testsuite/gcc.target/i386/blendv-2.c b/gcc/testsuite/gcc.target/i386/blendv-2.c new file mode 100644 index 0000000..e61e023 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/blendv-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O2 -mno-avx512f" } */ +/* { dg-final { scan-assembler-not {pblendv} } } */ +/* { dg-final { scan-assembler-not {blendvp} } } */ + +#include +__m128 +foo (__m128 a, __m128 b) +{ + return _mm_blendv_ps (a, b, _mm_setzero_ps ()); +} + +__m256 +foo2 (__m256 a, __m256 b) +{ + return _mm256_blendv_ps (a, b, _mm256_set1_ps (-1.0)); +} + +__m128d +foo3 (__m128d a, __m128d b, __m128d c) +{ + return _mm_blendv_pd (a, b, _mm_set1_pd (1.0)); +} + +__m256d +foo4 (__m256d a, __m256d b, __m256d c) +{ + return _mm256_blendv_pd (a, b, _mm256_set1_pd (-134.3)); +} + +__m128i +foo5 (__m128i a, __m128i b, __m128i c) +{ + return _mm_blendv_epi8 (a, b, _mm_set1_epi8 (3)); +} + +__m256i +foo6 (__m256i a, __m256i b, __m256i c) +{ + return _mm256_blendv_epi8 (a, b, _mm256_set1_epi8 (-22)); +} diff --git a/gcc/testsuite/gcc.target/i386/funcspec-8.c b/gcc/testsuite/gcc.target/i386/funcspec-8.c index 0a6c709..f155411 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-8.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-8.c @@ -52,19 +52,19 @@ generic_psignd128 (__m128w a, __m128w b) #error "-msse4.1 should not be set for this test" #endif -__m128d sse4_1_blendvpd (__m128d a, __m128d b, __m128d c) __attribute__((__target__("sse4.1"))); -__m128d generic_blendvpd (__m128d a, __m128d b, __m128d c); +__m128 sse4_1_roundv4sf2 (__m128 a) __attribute__((__target__("sse4.1"))); +__m128 generic_roundv4sf2 (__m128 a); -__m128d -sse4_1_blendvpd (__m128d a, __m128d b, __m128d c) +__m128 +sse4_1_roundv4sf2 (__m128 a) { - return __builtin_ia32_blendvpd (a, b, c); + return __builtin_ia32_roundps_az (a); } -__m128d -generic_blendvpd (__m128d a, __m128d b, __m128d c) +__m128 +generic_blendvpd (__m128 a) { - return __builtin_ia32_blendvpd (a, b, c); /* { dg-error "needs isa option" } */ + return __builtin_ia32_roundps_az (a); /* { dg-error "needs isa option" } */ } #ifdef __SSE4_2__ -- cgit v1.1 From 3f1a08d9d731975d4061c306837ab28d52f37c7e Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 24 May 2021 10:57:52 +0800 Subject: For 128/256-bit vec_cond_expr, When mask operands is lt reg const0_rtx, blendv can be used instead of avx512 mask. gcc/ChangeLog: PR target/100648 * config/i386/sse.md (*avx_cmp3_lt): New define_insn_and_split. (*avx_cmp3_ltint): Ditto. (*avx2_pcmp3_3): Ditto. (*avx2_pcmp3_4): Ditto. (*avx2_pcmp3_5): Ditto. gcc/testsuite/ChangeLog: PR target/100648 * g++.target/i386/avx2-pr54700-2.C: Adjust testcase. * g++.target/i386/avx512vl-pr54700-1a.C: New test. * g++.target/i386/avx512vl-pr54700-1b.C: New test. * g++.target/i386/avx512vl-pr54700-2a.C: New test. * g++.target/i386/avx512vl-pr54700-2b.C: New test. * gcc.target/i386/avx512vl-pr100648.c: New test. * gcc.target/i386/avx512vl-blendv-1.c: New test. * gcc.target/i386/avx512vl-blendv-2.c: New test. --- gcc/config/i386/sse.md | 152 +++++++++++++++++++++ gcc/testsuite/g++.target/i386/avx2-pr54700-2.C | 8 +- .../g++.target/i386/avx512vl-pr54700-1a.C | 9 ++ .../g++.target/i386/avx512vl-pr54700-1b.C | 9 ++ .../g++.target/i386/avx512vl-pr54700-2a.C | 17 +++ .../g++.target/i386/avx512vl-pr54700-2b.C | 17 +++ gcc/testsuite/gcc.target/i386/avx512vl-blendv-1.c | 51 +++++++ gcc/testsuite/gcc.target/i386/avx512vl-blendv-2.c | 41 ++++++ gcc/testsuite/gcc.target/i386/avx512vl-pr100648.c | 21 +++ 9 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.target/i386/avx512vl-pr54700-1a.C create mode 100644 gcc/testsuite/g++.target/i386/avx512vl-pr54700-1b.C create mode 100644 gcc/testsuite/g++.target/i386/avx512vl-pr54700-2a.C create mode 100644 gcc/testsuite/g++.target/i386/avx512vl-pr54700-2b.C create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-blendv-1.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-blendv-2.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512vl-pr100648.c diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 3100635..ffcc0c8 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -3048,6 +3048,68 @@ UNSPEC_PCMP))] "operands[5] = GEN_INT (INTVAL (operands[5]) ^ 4);") +(define_insn_and_split "*avx_cmp3_lt" + [(set (match_operand:VF_128_256 0 "register_operand") + (vec_merge:VF_128_256 + (match_operand:VF_128_256 1 "vector_operand") + (match_operand:VF_128_256 2 "vector_operand") + (unspec: + [(match_operand: 3 "register_operand") + (match_operand: 4 "const0_operand") + (match_operand:SI 5 "const_0_to_7_operand")] + UNSPEC_PCMP)))] + "TARGET_AVX512VL && ix86_pre_reload_split () + /* LT or GE 0 */ + && ((INTVAL (operands[5]) == 1 && !MEM_P (operands[2])) + || (INTVAL (operands[5]) == 5 && !MEM_P (operands[1])))" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:VF_128_256 + [(match_dup 2) + (match_dup 1) + (lt:VF_128_256 + (match_dup 3) + (match_dup 4))] + UNSPEC_BLENDV))] +{ + if (INTVAL (operands[5]) == 5) + std::swap (operands[1], operands[2]); +}) + +(define_insn_and_split "*avx_cmp3_ltint" + [(set (match_operand:VI48_AVX 0 "register_operand") + (vec_merge:VI48_AVX + (match_operand:VI48_AVX 1 "vector_operand") + (match_operand:VI48_AVX 2 "vector_operand") + (unspec: + [(match_operand:VI48_AVX 3 "register_operand") + (match_operand:VI48_AVX 4 "const0_operand") + (match_operand:SI 5 "const_0_to_7_operand")] + UNSPEC_PCMP)))] + "TARGET_AVX512VL && ix86_pre_reload_split () + /* LT or GE 0 */ + && ((INTVAL (operands[5]) == 1 && !MEM_P (operands[2])) + || (INTVAL (operands[5]) == 5 && !MEM_P (operands[1])))" + "#" + "&& 1" + [(set (match_dup 0) + (unspec: + [(match_dup 2) + (match_dup 1) + (subreg: + (lt:VI48_AVX + (match_dup 3) + (match_dup 4)) 0)] + UNSPEC_BLENDV))] +{ + if (INTVAL (operands[5]) == 5) + std::swap (operands[1], operands[2]); + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + operands[2] = gen_lowpart (mode, operands[2]); +}) + (define_insn "avx_vmcmp3" [(set (match_operand:VF_128 0 "register_operand" "=x") (vec_merge:VF_128 @@ -13063,6 +13125,96 @@ DONE; }) +(define_insn_and_split "*avx2_pcmp3_3" + [(set (match_operand:VI1_AVX2 0 "register_operand") + (vec_merge:VI1_AVX2 + (match_operand:VI1_AVX2 1 "vector_operand") + (match_operand:VI1_AVX2 2 "vector_operand") + (unspec: + [(match_operand:VI1_AVX2 3 "register_operand") + (match_operand:VI1_AVX2 4 "const0_operand") + (match_operand:SI 5 "const_0_to_7_operand")] + UNSPEC_PCMP)))] + "TARGET_AVX512VL && ix86_pre_reload_split () + /* LT or GE 0 */ + && ((INTVAL (operands[5]) == 1 && !MEM_P (operands[2])) + || (INTVAL (operands[5]) == 5 && !MEM_P (operands[1])))" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:VI1_AVX2 + [(match_dup 2) + (match_dup 1) + (lt:VI1_AVX2 + (match_dup 3) + (match_dup 4))] + UNSPEC_BLENDV))] +{ + if (INTVAL (operands[5]) == 5) + std::swap (operands[1], operands[2]); +}) + +(define_insn_and_split "*avx2_pcmp3_4" + [(set (match_operand:VI1_AVX2 0 "register_operand") + (vec_merge:VI1_AVX2 + (match_operand:VI1_AVX2 1 "vector_operand") + (match_operand:VI1_AVX2 2 "vector_operand") + (unspec: + [(subreg:VI1_AVX2 (not (match_operand 3 "register_operand")) 0) + (match_operand:VI1_AVX2 4 "const0_operand") + (match_operand:SI 5 "const_0_to_7_operand")] + UNSPEC_PCMP)))] + "TARGET_AVX512VL && ix86_pre_reload_split () + && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_VECTOR_INT + && GET_MODE_SIZE (GET_MODE (operands[3])) == + /* LT or GE 0 */ + && ((INTVAL (operands[5]) == 1 && !MEM_P (operands[1])) + || (INTVAL (operands[5]) == 5 && !MEM_P (operands[2])))" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:VI1_AVX2 + [(match_dup 1) + (match_dup 2) + (lt:VI1_AVX2 + (match_dup 3) + (match_dup 4))] + UNSPEC_BLENDV))] +{ + if (INTVAL (operands[5]) == 1) + std::swap (operands[1], operands[2]); + operands[3] = gen_lowpart (mode, operands[3]); +}) + +(define_insn_and_split "*avx2_pcmp3_5" + [(set (match_operand:VI1_AVX2 0 "register_operand") + (vec_merge:VI1_AVX2 + (match_operand:VI1_AVX2 1 "vector_operand") + (match_operand:VI1_AVX2 2 "vector_operand") + (unspec: + [(not:VI1_AVX2 (match_operand:VI1_AVX2 3 "register_operand")) + (match_operand:VI1_AVX2 4 "const0_operand") + (match_operand:SI 5 "const_0_to_7_operand")] + UNSPEC_PCMP)))] + "TARGET_AVX512VL && ix86_pre_reload_split () + /* LT or GE 0 */ + && ((INTVAL (operands[5]) == 1 && !MEM_P (operands[1])) + || (INTVAL (operands[5]) == 5 && !MEM_P (operands[2])))" + "#" + "&& 1" + [(set (match_dup 0) + (unspec:VI1_AVX2 + [(match_dup 1) + (match_dup 2) + (lt:VI1_AVX2 + (match_dup 3) + (match_dup 4))] + UNSPEC_BLENDV))] +{ + if (INTVAL (operands[5]) == 1) + std::swap (operands[1], operands[2]); +}) + (define_expand "_eq3" [(set (match_operand: 0 "register_operand") (unspec: diff --git a/gcc/testsuite/g++.target/i386/avx2-pr54700-2.C b/gcc/testsuite/g++.target/i386/avx2-pr54700-2.C index c9054e5..e7a85c3 100644 --- a/gcc/testsuite/g++.target/i386/avx2-pr54700-2.C +++ b/gcc/testsuite/g++.target/i386/avx2-pr54700-2.C @@ -2,9 +2,15 @@ /* { dg-do run { target avx2 } } */ /* { dg-options "-O2 -std=c++14 -mavx2 -mno-xop -mno-avx512f" } */ -#include "avx2-check.h" +#ifndef CHECK_H +#define CHECK_H "avx2-check.h" +#endif +#ifndef TEST #define TEST avx2_test +#endif + +#include CHECK_H #include "avx2-pr54700-1.C" diff --git a/gcc/testsuite/g++.target/i386/avx512vl-pr54700-1a.C b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-1a.C new file mode 100644 index 0000000..fedc3aa --- /dev/null +++ b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-1a.C @@ -0,0 +1,9 @@ +/* PR target/100648 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c++14 -mavx2 -mno-xop -mavx512vl -mavx512bw" } */ +/* { dg-final { scan-assembler-not "vpcmpgt\[bdq]" } } */ +/* { dg-final { scan-assembler-times "vpblendvb" 2 } } */ +/* { dg-final { scan-assembler-times "vblendvps" 4 } } */ +/* { dg-final { scan-assembler-times "vblendvpd" 4 } } */ + +#include "avx2-pr54700-1.C" diff --git a/gcc/testsuite/g++.target/i386/avx512vl-pr54700-1b.C b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-1b.C new file mode 100644 index 0000000..03f9343 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-1b.C @@ -0,0 +1,9 @@ +/* PR target/100648 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c++14 -mavx512vl -mavx512bw -mno-xop" } */ +/* { dg-final { scan-assembler-not "pcmpgt\[bdq]" } } */ +/* { dg-final { scan-assembler-times "pblendvb" 2 } } */ +/* { dg-final { scan-assembler-times "blendvps" 4 } } */ +/* { dg-final { scan-assembler-times "blendvpd" 4 } } */ + +#include "sse4_1-pr54700-1.C" diff --git a/gcc/testsuite/g++.target/i386/avx512vl-pr54700-2a.C b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-2a.C new file mode 100644 index 0000000..687a8c4 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-2a.C @@ -0,0 +1,17 @@ +/* PR target/100648 */ +/* { dg-do run { target avx2 } } */ +/* { dg-options "-O2 -std=c++14 -mavx2 -mavx512vl -mavx512bw" } */ + +#ifndef CHECK_H +#define CHECK_H "avx512f-helper.h" +#endif + +#ifndef TEST +#define TEST_test_256 +#endif + +#include CHECK_H +#include "avx2-pr54700-2.C" + +#define AVX512VL +#define AVX512BW diff --git a/gcc/testsuite/g++.target/i386/avx512vl-pr54700-2b.C b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-2b.C new file mode 100644 index 0000000..40450a9 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/avx512vl-pr54700-2b.C @@ -0,0 +1,17 @@ +/* PR target/pr100648 */ +/* { dg-do run { target sse4 } } */ +/* { dg-options "-O2 -std=c++14 -msse4 -mavx512vl -mavx512bw -mno-xop" } */ + +#ifndef CHECK_H +#define CHECK_H "avx512f-helper.h" +#endif + +#ifndef TEST +#define TEST_test_128 +#endif + +#include CHECK_H +#include "sse4_1-pr54700-2.C" + +#define AVX512VL +#define AVX512BW diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-blendv-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-blendv-1.c new file mode 100644 index 0000000..6aa004b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-blendv-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512vl" } */ +/* { dg-final { scan-assembler-times {pblendvb[\t ]*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {pblendvb[\t ]*%ymm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvps[\t ]*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvps[\t ]*%ymm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvpd[\t ]*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {blendvpd[\t ]*%ymm} 1 } } */ + +typedef float v4sf __attribute__ ((vector_size (16))); +typedef float v8sf __attribute__ ((vector_size (32))); +typedef double v2df __attribute__ ((vector_size (16))); +typedef double v4df __attribute__ ((vector_size (32))); +typedef char v16qi __attribute__ ((vector_size (16))); +typedef char v32qi __attribute__ ((vector_size (32))); + +v4sf +foo (v4sf a, v4sf b, v4sf c) +{ + return __builtin_ia32_blendvps (a, b, c); +} + +v8sf +foo2 (v8sf a, v8sf b, v8sf c) +{ + return __builtin_ia32_blendvps256 (a, b, c); +} + +v2df +foo3 (v2df a, v2df b, v2df c) +{ + return __builtin_ia32_blendvpd (a, b, c); +} + +v4df +foo4 (v4df a, v4df b, v4df c) +{ + return __builtin_ia32_blendvpd256 (a, b, c); +} + +v16qi +foo5 (v16qi a, v16qi b, v16qi c) +{ + return __builtin_ia32_pblendvb128 (a, b, c); +} + +v32qi +foo6 (v32qi a, v32qi b, v32qi c) +{ + return __builtin_ia32_pblendvb256 (a, b, c); +} diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-blendv-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-blendv-2.c new file mode 100644 index 0000000..daddcd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-blendv-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512vl" } */ +/* { dg-final { scan-assembler-not {pblendv} } } */ +/* { dg-final { scan-assembler-not {blendvp} } } */ + +#include +__m128 +foo (__m128 a, __m128 b) +{ + return _mm_blendv_ps (a, b, _mm_setzero_ps ()); +} + +__m256 +foo2 (__m256 a, __m256 b) +{ + return _mm256_blendv_ps (a, b, _mm256_set1_ps (-1.0)); +} + +__m128d +foo3 (__m128d a, __m128d b, __m128d c) +{ + return _mm_blendv_pd (a, b, _mm_set1_pd (1.0)); +} + +__m256d +foo4 (__m256d a, __m256d b, __m256d c) +{ + return _mm256_blendv_pd (a, b, _mm256_set1_pd (-134.3)); +} + +__m128i +foo5 (__m128i a, __m128i b, __m128i c) +{ + return _mm_blendv_epi8 (a, b, _mm_set1_epi8 (3)); +} + +__m256i +foo6 (__m256i a, __m256i b, __m256i c) +{ + return _mm256_blendv_epi8 (a, b, _mm256_set1_epi8 (-22)); +} diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-pr100648.c b/gcc/testsuite/gcc.target/i386/avx512vl-pr100648.c new file mode 100644 index 0000000..2ef7c7b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512vl-pr100648.c @@ -0,0 +1,21 @@ +/* PR target/100648. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512vl -mavx512bw -masm=att" } */ +/* { dg-final { scan-assembler-times "\tvpblendvb\t" 2 } } */ +/* { dg-final { scan-assembler-not "\tvpcmpeq" } } */ +/* { dg-final { scan-assembler-not "\tvpandn" } } */ +#include + +__m256i +f1 (__m256i a, __m256i b, __m256i mask) +{ + return _mm256_blendv_epi8(a, b, + _mm256_andnot_si256(mask, _mm256_set1_epi8(255))); +} + +__m128i +f2 (__m128i a, __m128i b, __m128i mask) +{ + return _mm_blendv_epi8(a, b, + _mm_andnot_si128(mask, _mm_set1_epi8(255))); +} -- cgit v1.1 From 0ad9d88a3d7170b3d864693c9eb512f89a5096ff Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 23 Jun 2021 09:59:28 +0200 Subject: tree-optimization/101173 - fix interchange dependence checking This adjusts the loop interchange dependence checking to disallow an outer loop dependence distance of zero. 2021-06-23 Richard Biener PR tree-optimization/101173 * gimple-loop-interchange.cc (tree_loop_interchange::valid_data_dependences): Disallow outer loop dependence distance of zero. * gcc.dg/torture/pr101173.c: New testcase. --- gcc/gimple-loop-interchange.cc | 4 ++-- gcc/testsuite/gcc.dg/torture/pr101173.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101173.c diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc index 80f749b..43045c54 100644 --- a/gcc/gimple-loop-interchange.cc +++ b/gcc/gimple-loop-interchange.cc @@ -1043,8 +1043,8 @@ tree_loop_interchange::valid_data_dependences (unsigned i_idx, unsigned o_idx, continue; /* Be conservative, skip case if either direction at i_idx/o_idx - levels is not '=' or '<'. */ - if (dist_vect[i_idx] < 0 || dist_vect[o_idx] < 0) + levels is not '=' (for the inner loop) or '<'. */ + if (dist_vect[i_idx] < 0 || dist_vect[o_idx] <= 0) return false; } } diff --git a/gcc/testsuite/gcc.dg/torture/pr101173.c b/gcc/testsuite/gcc.dg/torture/pr101173.c new file mode 100644 index 0000000..0c9090d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101173.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-additional-options "-floop-interchange" } */ + +int a[6][9]; +int main() +{ + a[1][3] = 8; + for (int b = 1; b <= 5; b++) + for (int d = 0; d <= 5; d++) +#pragma GCC unroll 0 + for (int c = 0; c <= 5; c++) + a[b][c] = a[b][c + 2] & 216; + for (int e = 0; e < 6; e++) + for (int f = 0; f < 9; f++) + if (a[e][f] != 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 2ad71efb5de9e929ffd2b8ce0a37c3c34021c0f1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 28 Jun 2021 09:42:58 +0200 Subject: tree-optimization/101207 - fix BB reduc permute elide with life stmts This fixes breakage of live lane extracts from permuted loads we elide from BB reduction vectorization by handling the un-permuting the same as in the regular eliding code - apply the reverse permute to both the scalar stmts and the load permutation. 2021-06-28 Richard Biener PR tree-optimization/101207 * tree-vect-slp.c (vect_optimize_slp): Do BB reduction permute eliding for load permutations properly. * gcc.dg/vect/bb-slp-pr101207.c: New testcase. --- gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c | 25 ++++++++ gcc/tree-vect-slp.c | 88 +++++++++++++++-------------- 2 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c new file mode 100644 index 0000000..1f51d66 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101207.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ffast-math" } */ + +#include "tree-vect.h" + +double a[2]; +double x, y; + +void __attribute__((noipa)) foo () +{ + x = a[1] - a[0]; + y = a[0] + a[1]; +} + +int main() +{ + check_vect (); + + a[0] = 0.; + a[1] = 1.; + foo (); + if (x != 1. || y != 1.) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 17fe5f2..5401dbe 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -3921,6 +3921,52 @@ vect_optimize_slp (vec_info *vinfo) } } + /* Elide any permutations at BB reduction roots. */ + if (is_a (vinfo)) + { + for (slp_instance instance : vinfo->slp_instances) + { + if (SLP_INSTANCE_KIND (instance) != slp_inst_kind_bb_reduc) + continue; + slp_tree old = SLP_INSTANCE_TREE (instance); + if (SLP_TREE_CODE (old) == VEC_PERM_EXPR + && SLP_TREE_CHILDREN (old).length () == 1) + { + slp_tree child = SLP_TREE_CHILDREN (old)[0]; + if (SLP_TREE_DEF_TYPE (child) == vect_external_def) + { + /* Preserve the special VEC_PERM we use to shield existing + vector defs from the rest. But make it a no-op. */ + unsigned i = 0; + for (std::pair &p + : SLP_TREE_LANE_PERMUTATION (old)) + p.second = i++; + } + else + { + SLP_INSTANCE_TREE (instance) = child; + SLP_TREE_REF_COUNT (child)++; + vect_free_slp_tree (old); + } + } + else if (SLP_TREE_LOAD_PERMUTATION (old).exists () + && SLP_TREE_REF_COUNT (old) == 1 + && vertices[old->vertex].materialize) + { + /* ??? For loads the situation is more complex since + we can't modify the permute in place in case the + node is used multiple times. In fact for loads this + should be somehow handled in the propagation engine. */ + /* Apply the reverse permutation to our stmts. */ + int perm = vertices[old->vertex].get_perm_in (); + vect_slp_permute (perms[perm], + SLP_TREE_SCALAR_STMTS (old), true); + vect_slp_permute (perms[perm], + SLP_TREE_LOAD_PERMUTATION (old), true); + } + } + } + /* Free the perms vector used for propagation. */ while (!perms.is_empty ()) perms.pop ().release (); @@ -3987,48 +4033,6 @@ vect_optimize_slp (vec_info *vinfo) } } } - - /* And any permutations of BB reductions. */ - if (is_a (vinfo)) - { - for (slp_instance instance : vinfo->slp_instances) - { - if (SLP_INSTANCE_KIND (instance) != slp_inst_kind_bb_reduc) - continue; - slp_tree old = SLP_INSTANCE_TREE (instance); - if (SLP_TREE_CODE (old) == VEC_PERM_EXPR - && SLP_TREE_CHILDREN (old).length () == 1) - { - slp_tree child = SLP_TREE_CHILDREN (old)[0]; - if (SLP_TREE_DEF_TYPE (child) == vect_external_def) - { - /* Preserve the special VEC_PERM we use to shield existing - vector defs from the rest. But make it a no-op. */ - unsigned i = 0; - for (std::pair &p - : SLP_TREE_LANE_PERMUTATION (old)) - p.second = i++; - } - else - { - SLP_INSTANCE_TREE (instance) = child; - SLP_TREE_REF_COUNT (child)++; - vect_free_slp_tree (old); - } - } - else if (SLP_TREE_LOAD_PERMUTATION (old).exists () - && SLP_TREE_REF_COUNT (old) == 1) - { - /* ??? For loads the situation is more complex since - we can't modify the permute in place in case the - node is used multiple times. In fact for loads this - should be somehow handled in the propagation engine. */ - auto fn = [] (const void *a, const void *b) - { return *(const int *)a - *(const int *)b; }; - SLP_TREE_LOAD_PERMUTATION (old).qsort (fn); - } - } - } } /* Gather loads reachable from the individual SLP graph entries. */ -- cgit v1.1 From 22069036efda4661862aeee213859f1ee8511ab5 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 23 Jun 2021 15:46:22 +0200 Subject: v850: add v850_can_inline_p target hook gcc/ChangeLog: * config/v850/v850.c (v850_option_override): Build default target node. (v850_can_inline_p): New. Allow MASK_PROLOG_FUNCTION to be ignored for inlining. (TARGET_CAN_INLINE_P): New. --- gcc/config/v850/v850.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index e0e5005..371e602 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -3140,6 +3140,11 @@ v850_option_override (void) /* The RH850 ABI does not (currently) support the use of the CALLT instruction. */ if (! TARGET_GCC_ABI) target_flags |= MASK_DISABLE_CALLT; + + /* Save the initial options in case the user does function specific + options. */ + target_option_default_node = target_option_current_node + = build_target_option_node (&global_options, &global_options_set); } const char * @@ -3192,6 +3197,29 @@ v850_modes_tieable_p (machine_mode mode1, machine_mode mode2) return (mode1 == mode2 || (GET_MODE_SIZE (mode1) <= 4 && GET_MODE_SIZE (mode2) <= 4)); } + +static bool +v850_can_inline_p (tree caller, tree callee) +{ + tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller); + tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee); + + const unsigned HOST_WIDE_INT safe_flags = MASK_PROLOG_FUNCTION; + + if (!callee_tree) + callee_tree = target_option_default_node; + if (!caller_tree) + caller_tree = target_option_default_node; + if (callee_tree == caller_tree) + return true; + + cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree); + cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree); + + return ((caller_opts->x_target_flags & ~safe_flags) + == (callee_opts->x_target_flags & ~safe_flags)); +} + /* Initialize the GCC target structure. */ @@ -3306,6 +3334,10 @@ v850_modes_tieable_p (machine_mode mode1, machine_mode mode2) #undef TARGET_HAVE_SPECULATION_SAFE_VALUE #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed +#undef TARGET_CAN_INLINE_P +#define TARGET_CAN_INLINE_P v850_can_inline_p + + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-v850.h" -- cgit v1.1 From ad26c076aaa6f9af144c33c9c04c5dc8010ad156 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 23 Jun 2021 15:48:28 +0200 Subject: v850: silent 2 warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Silents: /home/marxin/Programming/gcc/gcc/config/v850/v850.c: In function ‘char* construct_dispose_instruction(rtx)’: /home/marxin/Programming/gcc/gcc/config/v850/v850.c:2690:22: warning: ‘%s’ directive writing up to 99 bytes into a region of size between 79 and 89 [-Wformat-overflow=] 2690 | sprintf (buff, "dispose %d {%s}, r31", stack_bytes / 4, regs); | ^~~~~~~~~~~~~~~~~~~~~~ ~~~~ /home/marxin/Programming/gcc/gcc/config/v850/v850.c:2690:15: note: ‘sprintf’ output between 18 and 127 bytes into a destination of size 100 2690 | sprintf (buff, "dispose %d {%s}, r31", stack_bytes / 4, regs); | ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/marxin/Programming/gcc/gcc/config/v850/v850.c: In function ‘char* construct_prepare_instruction(rtx)’: /home/marxin/Programming/gcc/gcc/config/v850/v850.c:2814:22: warning: ‘%s’ directive writing up to 99 bytes into a region of size 91 [-Wformat-overflow=] 2814 | sprintf (buff, "prepare {%s}, %d", regs, (- stack_bytes) / 4); | ^~~~~~~~~~~~~~~~~~ ~~~~ /home/marxin/Programming/gcc/gcc/config/v850/v850.c:2814:15: note: ‘sprintf’ output between 14 and 123 bytes into a destination of size 100 2814 | sprintf (buff, "prepare {%s}, %d", regs, (- stack_bytes) / 4); | ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gcc/ChangeLog: * config/v850/v850.c (construct_dispose_instruction): Allocate a bigger buffer. (construct_prepare_instruction): Likewise. --- gcc/config/v850/v850.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index 371e602..4978faf 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -2583,7 +2583,7 @@ construct_dispose_instruction (rtx op) int stack_bytes; unsigned long int mask; int i; - static char buff[ 100 ]; /* XXX */ + static char buff[ 120 ]; /* XXX */ int use_callt = 0; if (count <= 2) @@ -2704,7 +2704,7 @@ construct_prepare_instruction (rtx op) int stack_bytes; unsigned long int mask; int i; - static char buff[ 100 ]; /* XXX */ + static char buff[ 120 ]; /* XXX */ int use_callt = 0; if (XVECLEN (op, 0) <= 1) -- cgit v1.1 From f80c4eaca0805bc9e68ed944519519c3dd1c12e1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 28 Jun 2021 11:05:46 +0200 Subject: tree-optimization/101229 - fix vectorizer SLP hybrid detection with PHIs This fixes the missing handling of PHIs in gimple_walk_op which causes the new vectorizer SLP hybrid detection scheme to fail. 2021-06-28 Richard Biener PR tree-optimization/101229 * gimple-walk.c (gimple_walk_op): Handle PHIs. * gcc.dg/torture/pr101229.c: New testcase. --- gcc/gimple-walk.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr101229.c | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/torture/pr101229.c diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c index e4a55f1..18884c4 100644 --- a/gcc/gimple-walk.c +++ b/gcc/gimple-walk.c @@ -517,6 +517,30 @@ walk_gimple_op (gimple *stmt, walk_tree_fn callback_op, case GIMPLE_PREDICT: break; + case GIMPLE_PHI: + /* PHIs are not GSS_WITH_OPS so we need to handle them explicitely. */ + { + gphi *phi = as_a (stmt); + if (wi) + { + wi->val_only = true; + wi->is_lhs = true; + } + ret = walk_tree (gimple_phi_result_ptr (phi), callback_op, wi, pset); + if (wi) + wi->is_lhs = false; + if (ret) + return ret; + for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) + { + ret = walk_tree (gimple_phi_arg_def_ptr (phi, i), + callback_op, wi, pset); + if (ret) + return ret; + } + break; + } + default: { enum gimple_statement_structure_enum gss; diff --git a/gcc/testsuite/gcc.dg/torture/pr101229.c b/gcc/testsuite/gcc.dg/torture/pr101229.c new file mode 100644 index 0000000..3708031 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101229.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +int a[1024]; +void foo() +{ + for (int i; i; i += 4) { + int suma = a[i]; + int sumb = a[i + 1]; + int sumc; + for (unsigned j = 0; j < 77; ++j) { + suma = (suma ^ i) + 1; + sumb = (sumb ^ i) + 2; + sumc = suma ^ i; + } + a[i] = suma; + a[i + 1] = sumb; + a[i + 2] = sumc; + } +} -- cgit v1.1 From 9fe9c45ae33a2df7a73a7c8d9a92a649206a15b7 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 19 Jun 2021 10:08:21 -0700 Subject: Duplicate the range information of the phi onto the new ssa_name Since match_simplify_replacement uses gimple_simplify, there is a new ssa name created sometimes and then we go and replace the phi edge with this new ssa name, the range information on the phi is lost. Placing this in replace_phi_edge_with_variable is the best option instead of doing it in each time replace_phi_edge_with_variable is called which is what is done today. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * tree-ssa-phiopt.c (replace_phi_edge_with_variable): Duplicate range info if we're the only things setting the target PHI. (value_replacement): Don't duplicate range here. (minmax_replacement): Likewise. --- gcc/tree-ssa-phiopt.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 1777bff..ab12e85 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -391,6 +391,32 @@ replace_phi_edge_with_variable (basic_block cond_block, basic_block bb = gimple_bb (phi); basic_block block_to_remove; gimple_stmt_iterator gsi; + tree phi_result = PHI_RESULT (phi); + + /* Duplicate range info if we're the only things setting the target PHI. + This is needed as later on, the new_tree will be replacing + The assignement of the PHI. + For an example: + bb1: + _4 = min + goto bb2 + + range<-INF,255> + a_3 = PHI<_4(1)> + bb3: + + use(a_3) + And _4 gets prograted into the use of a_3 and losing the range info. + This can't be done for more than 2 incoming edges as the progration + won't happen. */ + if (TREE_CODE (new_tree) == SSA_NAME + && EDGE_COUNT (gimple_bb (phi)->preds) == 2 + && INTEGRAL_TYPE_P (TREE_TYPE (phi_result)) + && !SSA_NAME_RANGE_INFO (new_tree) + && SSA_NAME_RANGE_INFO (phi_result)) + duplicate_ssa_name_range_info (new_tree, + SSA_NAME_RANGE_TYPE (phi_result), + SSA_NAME_RANGE_INFO (phi_result)); /* Change the PHI argument to new. */ SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree); @@ -1385,16 +1411,6 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, : # u_3 = PHI */ reset_flow_sensitive_info (lhs); - if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) - { - /* If available, we can use VR of phi result at least. */ - tree phires = gimple_phi_result (phi); - struct range_info_def *phires_range_info - = SSA_NAME_RANGE_INFO (phires); - if (phires_range_info) - duplicate_ssa_name_range_info (lhs, SSA_NAME_RANGE_TYPE (phires), - phires_range_info); - } gimple_stmt_iterator gsi_from; for (int i = prep_cnt - 1; i >= 0; --i) { @@ -1794,13 +1810,6 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, gimple_seq stmts = NULL; tree phi_result = PHI_RESULT (phi); result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1); - /* Duplicate range info if we're the only things setting the target PHI. */ - if (!gimple_seq_empty_p (stmts) - && EDGE_COUNT (gimple_bb (phi)->preds) == 2 - && !POINTER_TYPE_P (TREE_TYPE (phi_result)) - && SSA_NAME_RANGE_INFO (phi_result)) - duplicate_ssa_name_range_info (result, SSA_NAME_RANGE_TYPE (phi_result), - SSA_NAME_RANGE_INFO (phi_result)); gsi = gsi_last_bb (cond_bb); gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); -- cgit v1.1