diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1b46326306..0f19fc44212 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-01-24 Jeff Law + + PR tree-optimization/92788 + * tree-ssa-threadedge.c (thread_across_edge): Check EDGE_COMPLEX + not EDGE_ABNORMAL. + 2020-01-24 Jakub Jelinek PR target/93395 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1fc95b334a8..a8d517ad8a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-01-24 Jeff Law PR target/93395 diff --git a/gcc/testsuite/g++.dg/pr92788.C b/gcc/testsuite/g++.dg/pr92788.C new file mode 100644 index 00000000000..b92ae38f7aa --- /dev/null +++ b/gcc/testsuite/g++.dg/pr92788.C @@ -0,0 +1,470 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target c++11 } */ +/* { dg-options "-O3 -fnon-call-exceptions -ftracer -march=k8 -Wno-return-type" } */ + + +template struct integral_constant { + + static constexpr int value = __v; + +}; + +template using __bool_constant = integral_constant<__v>; + +template + +struct is_same : integral_constant {}; + +template using __enable_if_t = _Tp; + +void *operator new(unsigned long, void *__p) { return __p; } + +template class __normal_iterator { + + _Iterator _M_current; + + + +public: + + __normal_iterator(_Iterator) {} + + void operator++() { ++_M_current; } + + _Iterator base() { return _M_current; } + +}; + +template + +bool operator!=(__normal_iterator<_IteratorL, _Container> __lhs, + + __normal_iterator<_IteratorR, _Container> __rhs) { + + return __lhs.base() != __rhs.base(); + +} + +template void construct_at(_Tp *__location) noexcept { + + new (__location) _Tp; + +} + +template void _Construct(_Tp __p) { construct_at(__p); } + +struct _Any_data { + + template _Tp _M_access(); + +}; + +enum _Manager_operation {}; + +template class function; + +class _Function_base { + +public: + + template class _Base_manager { + +public: + + static bool _M_manager(_Any_data, _Any_data __source, _Manager_operation) { + + _Functor(*__source._M_access<_Functor *>()); + + return true; + + } + + }; + + typedef bool (*_Manager_type)(_Any_data &, const _Any_data &, + + _Manager_operation); + + _Manager_type _M_manager; + +}; + +template class _Function_handler; + +template + +class _Function_handler<_Res(_ArgTypes...), _Functor> : _Function_base { + +public: + + static bool _M_manager(_Any_data &__dest, const _Any_data &__source, + + _Manager_operation __op) { + + _Base_manager<_Functor>::_M_manager(__dest, __source, __op); + + } + +}; + +template + +class function<_Res(_ArgTypes...)> : _Function_base { + + template using _Requires = _Tp; + + + +public: + + template , void>, + + typename = _Requires<_Functor, void>> + + function(_Functor); + +}; + +template + +template + +function<_Res(_ArgTypes...)>::function(_Functor) { + + _M_manager = _Function_handler<_Res(), _Functor>::_M_manager; + +} + +template class new_allocator { + +public: + + _Tp *allocate(long) { return static_cast<_Tp *>(operator new(sizeof(_Tp))); } + +}; + +namespace std { + + template struct allocator_traits; + + template struct allocator_traits> { + + using allocator_type = new_allocator<_Tp>; + + using pointer = _Tp *; + + using const_pointer = _Tp *; + + using size_type = long; + + template using rebind_alloc = new_allocator<_Up>; + + static pointer allocate(allocator_type __a, size_type __n) { + + return __a.allocate(__n); + + } + + static void deallocate(allocator_type, pointer, size_type); + + }; + +} + +template + +struct __alloc_traits : std::allocator_traits<_Alloc> { + + template struct rebind { + + typedef typename std::allocator_traits<_Alloc>::template rebind_alloc<_Tp> other; + + }; + +}; + +namespace std { + + struct __uninitialized_copy { + + template + + static _ForwardIterator __uninit_copy(_InputIterator __first, + + _InputIterator __last, + + _ForwardIterator __result) { + + for (; __first != __last; ++__first, ++__result) + + _Construct(__result); + + return __result; + + } + + }; + + template + + _ForwardIterator uninitialized_copy(_InputIterator __first, + + _InputIterator __last, + + _ForwardIterator __result) { + + return __uninitialized_copy::__uninit_copy(__first, __last, __result); + + } + + template + + _ForwardIterator __uninitialized_copy_a(_InputIterator __first, + + _InputIterator __last, + + _ForwardIterator __result, _Tp) { + + return uninitialized_copy(__first, __last, __result); + + } + + template struct _Vector_base { + + typedef typename __alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; + + typedef typename __alloc_traits<_Tp_alloc_type>::pointer pointer; + + struct _Vector_impl_data { + + pointer _M_start; + + pointer _M_finish; + + }; + + struct _Vector_impl : _Tp_alloc_type, _Vector_impl_data {}; + + _Tp_alloc_type _M_get_Tp_allocator(); + + _Vector_base(long, _Alloc) { + + _M_impl._M_start = _M_allocate(); + + _M_impl._M_finish = _M_impl._M_start; + + } + + ~_Vector_base() { _M_deallocate(_M_impl._M_start); } + + _Vector_impl _M_impl; + + long _M_allocate___n; + + pointer _M_allocate() { + + typedef __alloc_traits<_Tp_alloc_type> _Tr; + + return _M_allocate___n ? _Tr::allocate(_M_impl, _M_allocate___n) + + : pointer(); + + } + + long _M_deallocate___n; + + void _M_deallocate(pointer __p) { + + typedef __alloc_traits<_Tp_alloc_type> _Tr; + + if (__p) + + _Tr::deallocate(_M_impl, __p, _M_deallocate___n); + + } + + }; + + template > + + class vector : _Vector_base<_Tp, _Alloc> { + + typedef _Vector_base<_Tp, _Alloc> _Base; + + typedef __normal_iterator< + + typename __alloc_traits::const_pointer, + + int> + + const_iterator; + + using _Base::_M_get_Tp_allocator; + + + +public: + + vector(); + + vector(vector &__x) : _Base(0, _M_get_Tp_allocator()) { + + this->_M_impl._M_finish = __uninitialized_copy_a(__x.begin(), __x.end(), + + this->_M_impl._M_start, 0); + + } + + const_iterator begin() noexcept { return this->_M_impl._M_start; } + + const_iterator end() noexcept { return this->_M_impl._M_finish; } + + }; + + template class __shared_ptr_access { + +public: + + using element_type = _Tp; + + element_type *operator->(); + + }; + + enum syntax_option_type : int; + + template using _Matcher = function; + + struct _NFA { + + void _M_insert_matcher(_Matcher); + + }; + + template class _Compiler { + +public: + + typedef typename _TraitsT::char_type *_IterT; + + _Compiler(_IterT, _IterT, const typename _TraitsT::locale_type &, syntax_option_type); + + template void _M_insert_character_class_matcher(); + + syntax_option_type _M_flags; + + __shared_ptr_access<_NFA> _M_nfa; + + _TraitsT _M_traits; + + }; + + template + + using __enable_if_contiguous_iter = + + __enable_if_t::value, + + __shared_ptr_access<_NFA>>; + + syntax_option_type __compile_nfa___flags; + + struct Trans_NS___cxx11_regex_traits { + + typedef char char_type; + + typedef int locale_type; + + struct _RegexMask { + + short _M_base; + + char _M_extended; + + _RegexMask() : _M_extended() {} + + } typedef char_class_type; + + }; + + template + + __enable_if_contiguous_iter<_FwdIter, char> __compile_nfa(_FwdIter) { + + auto __cfirst = nullptr; + + using _Cmplr = _Compiler; + + _Cmplr(__cfirst, __cfirst, 0, __compile_nfa___flags); + + } + + class _RegexTranslatorBase { + +public: + + _RegexTranslatorBase(Trans_NS___cxx11_regex_traits); + + }; + + class _RegexTranslator : _RegexTranslatorBase { + + typedef _RegexTranslatorBase _Base; + + using _Base::_Base; + + }; + + template struct _BracketMatcher { + + _BracketMatcher(bool, _TraitsT __traits) : _M_translator(__traits) {} + + vector _M_neg_class_set; + + _RegexTranslator _M_translator; + + }; + + template + + _Compiler<_TraitsT>::_Compiler(_IterT __b, _IterT __e, + + const typename _TraitsT::locale_type &__loc, + + syntax_option_type) { + + _M_insert_character_class_matcher(); + + _M_insert_character_class_matcher(); + + } + + template + + template + + void _Compiler<_TraitsT>::_M_insert_character_class_matcher() { + + _BracketMatcher<_TraitsT, __collate> __matcher(0, _M_traits); + + _M_nfa->_M_insert_matcher(__matcher); + + } + + class Trans_NS___cxx11_basic_regex { + +public: + + char Trans_NS___cxx11_basic_regex___last; + + Trans_NS___cxx11_basic_regex() + + : _M_automaton(__compile_nfa(Trans_NS___cxx11_basic_regex___last)) {} /* { dg-error } */ + + __shared_ptr_access<_NFA> _M_automaton; + + } regex_sanity_check___f; + +} diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 35440b020cc..c7c08213f9a 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -1323,7 +1323,7 @@ thread_across_edge (gcond *dummy_cond, /* If E->dest has abnormal outgoing edges, then there's no guarantee we can safely redirect any of the edges. Just punt those cases. */ FOR_EACH_EDGE (taken_edge, ei, e->dest->succs) - if (taken_edge->flags & EDGE_ABNORMAL) + if (taken_edge->flags & EDGE_COMPLEX) { const_and_copies->pop_to_marker (); avail_exprs_stack->pop_to_marker ();