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 @@
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