diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2011-09-21 19:37:00 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2011-09-21 19:37:00 +0200 |
commit | bd352290bcbe1c80ce47ea3aa4d66d17a6e8d482 (patch) | |
tree | ae971a93333b822559742d9213ede6fd99d96a3b | |
parent | 655d51578160132920f0f88daadf8c9453c20045 (diff) | |
download | gcc-bd352290bcbe1c80ce47ea3aa4d66d17a6e8d482.zip gcc-bd352290bcbe1c80ce47ea3aa4d66d17a6e8d482.tar.gz gcc-bd352290bcbe1c80ce47ea3aa4d66d17a6e8d482.tar.bz2 |
re PR target/50464 (Using -Ofast -march=bdver1 results in internal compiler error: in extract_insn, at recog.c:2109)
PR target/50464
* config/i386/sse.md (xop_pcmov_<mode><avxsizesuffix>): Change
operand 1 predicate to register_operand and operand 2 predicate
to nonimmediate_operand.
* config/i386/i386.c (ix86_expand_sse_movcc): When generating
xop_pcmov, force op_true to register. Also, force op_false to
register if it doesn't satisfy nonimmediate_operand predicate.
testsuite/ChangeLog:
PR target/50464
* g++.dg/other/pr50464.C: New test.
From-SVN: r179053
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 14 | ||||
-rw-r--r-- | gcc/config/i386/sse.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/pr50464.C | 170 |
5 files changed, 198 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a3c23a..9b9d698 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-09-21 Uros Bizjak <ubizjak@gmail.com> + + PR target/50464 + * config/i386/sse.md (xop_pcmov_<mode><avxsizesuffix>): Change + operand 1 predicate to register_operand and operand 2 predicate + to nonimmediate_operand. + * config/i386/i386.c (ix86_expand_sse_movcc): When generating + xop_pcmov, force op_true to register. Also, force op_false to + register if it doesn't satisfy nonimmediate_operand predicate. + 2011-09-21 Kirill Yukhin <kirill.yukhin@intel.com> * config/i386/bmi2intrin.h (_mulx_u64): New. @@ -6,7 +16,8 @@ 2011-09-21 Jan Hubicka <jh@suse.cz> PR tree-optimization/50433 - * ipa-inline-analysis.c (eliminated_by_inlining_prob): Use get_base_address. + * ipa-inline-analysis.c (eliminated_by_inlining_prob): + Use get_base_address. 2011-09-21 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 57cc8e3..eae3ff2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18897,11 +18897,15 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false) } else if (TARGET_XOP) { - rtx pcmov = gen_rtx_SET (mode, dest, - gen_rtx_IF_THEN_ELSE (mode, cmp, - op_true, - op_false)); - emit_insn (pcmov); + op_true = force_reg (mode, op_true); + + if (!nonimmediate_operand (op_false, mode)) + op_false = force_reg (mode, op_false); + + emit_insn (gen_rtx_SET (mode, dest, + gen_rtx_IF_THEN_ELSE (mode, cmp, + op_true, + op_false))); } else { diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 7c15e1a..6c20ddbd 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -10401,8 +10401,8 @@ [(set (match_operand:V 0 "register_operand" "=x,x") (if_then_else:V (match_operand:V 3 "nonimmediate_operand" "x,m") - (match_operand:V 1 "vector_move_operand" "x,x") - (match_operand:V 2 "vector_move_operand" "xm,x")))] + (match_operand:V 1 "register_operand" "x,x") + (match_operand:V 2 "nonimmediate_operand" "xm,x")))] "TARGET_XOP" "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}" [(set_attr "type" "sse4arg")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7022c0b..0e68b06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-09-21 Uros Bizjak <ubizjak@gmail.com> + + PR target/50464 + * g++.dg/other/pr50464.C: New test. + 2011-09-21 Kirill Yukhin <kirill.yukhin@intel.com> * gcc.target/i386/bmi2-mulx32-2.c: New test. diff --git a/gcc/testsuite/g++.dg/other/pr50464.C b/gcc/testsuite/g++.dg/other/pr50464.C new file mode 100644 index 0000000..8c67213 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/pr50464.C @@ -0,0 +1,170 @@ +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-options "-O3 -mxop" } + +typedef long unsigned int size_t; +typedef unsigned long ulong_t; +typedef signed long slong_t; + + template<typename _Iterator> + struct iterator_traits + { + typedef typename _Iterator::reference reference; + }; + + template<typename _Tp> + struct iterator_traits<_Tp*> + { + typedef _Tp& reference; + }; + + template<typename _Iterator, typename _Container> + class __normal_iterator + { + protected: + _Iterator _M_current; + typedef iterator_traits<_Iterator> __traits_type; + + public: + typedef typename __traits_type::reference reference; + + explicit + __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + + reference + operator*() const + { return *_M_current; } + + __normal_iterator& + operator++() + { + ++_M_current; + return *this; + } + + const _Iterator& + base() const + { return _M_current; } + }; + + template<typename _Iterator, typename _Container> + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } + + template<typename _Tp> + class allocator + { + public: + typedef _Tp* pointer; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef allocator<_Tp1> other; }; + + pointer allocate(size_t __n, const void* = 0) + { + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } + }; + + template<typename _Tp, typename _Alloc> + struct _Vector_base + { + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; + + struct _Vector_impl + : public _Tp_alloc_type + { + typename _Tp_alloc_type::pointer _M_start; + typename _Tp_alloc_type::pointer _M_finish; + typename _Tp_alloc_type::pointer _M_end_of_storage; + + _Vector_impl(_Tp_alloc_type const& __a) { } + }; + + public: + typedef _Alloc allocator_type; + + _Vector_base(size_t __n, const allocator_type& __a) + : _M_impl(__a) + { + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } + + public: + _Vector_impl _M_impl; + + typename _Tp_alloc_type::pointer + _M_allocate(size_t __n) + { return __n != 0 ? _M_impl.allocate(__n) : 0; } + + }; + + template<typename _Tp, typename _Alloc = allocator<_Tp> > + class vector : protected _Vector_base<_Tp, _Alloc> + { + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + + public: + typedef _Tp value_type; + typedef typename _Tp_alloc_type::pointer pointer; + typedef __normal_iterator<pointer, vector> iterator; + typedef _Alloc allocator_type; + + protected: + using _Base::_M_allocate; + using _Base::_M_impl; + + public: + + explicit + vector(size_t __n, const value_type& __value = value_type(), + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_fill_initialize(__n, __value); } + + iterator begin() + { return iterator(this->_M_impl._M_start); } + + iterator end() + { return iterator(this->_M_impl._M_finish); } + + protected: + void + _M_fill_initialize(size_t __n, const value_type& __value) + { + this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; + } + }; + + template<typename _InputIterator, typename _OutputIterator, typename _Tp> + _OutputIterator + replace_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + const _Tp& __old_value, const _Tp& __new_value) + { + ; + for (; __first != __last; ++__first, ++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; + } + +extern size_t shape_rank; + +void createDataspaceIdentifier() +{ + vector< ulong_t > dataspaceDims( shape_rank ); + vector< ulong_t > maxDataspaceDims( shape_rank ); + + replace_copy( + dataspaceDims.begin(), dataspaceDims.end(), + maxDataspaceDims.begin(), ulong_t( 0 ), ((ulong_t)(slong_t)(-1)) ); +} |