From patchwork Fri Jan 8 12:07:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kugan Vivekanandarajah X-Patchwork-Id: 59342 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp513447lbb; Fri, 8 Jan 2016 04:07:51 -0800 (PST) X-Received: by 10.98.43.73 with SMTP id r70mr3770883pfr.4.1452254870938; Fri, 08 Jan 2016 04:07:50 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id qd3si74389547pab.208.2016.01.08.04.07.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Jan 2016 04:07:50 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-418472-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-return-418472-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-418472-patch=linaro.org@gcc.gnu.org; dkim=pass header.i=@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=uJvJOSTUJHmSkCUpBolYgZ6Ua6pIbCjDpxNCCmk7b/r8wkNdQP w0kLXhHNyZQRE5+Yiev27+gRmh3xUNHEXsssnTwmco+Oogvn5ZkJEAQT9UAH5iVl 1GU7ocjC6ClK2viW51t9McnP4uGDBeJQ1XQ9FQhZFPPVtm1AXx+RsC5Tk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=GJFvFka/QwPj1NpnIBSQlfvQzmk=; b=LQNZmqcFAgGBcpKhA9Jm FzyqaP10O/yxv46UJsuFE5j9VgmNywdiYEqa4sRgBn19u75iSlcmb9BNCSxiQoF3 h1vkB9H+z8s+A8W104s8SaAHc9yAqXhpYBu6/UgmoRxS4orTkVO77tMbtQFH2ClC h7s6BPpUPUxxP6s9oC2S7+M= Received: (qmail 118179 invoked by alias); 8 Jan 2016 12:07:30 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 118157 invoked by uid 89); 8 Jan 2016 12:07:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=wilson, Dynamic, Wilson, col X-HELO: mail-pf0-f181.google.com Received: from mail-pf0-f181.google.com (HELO mail-pf0-f181.google.com) (209.85.192.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 08 Jan 2016 12:07:26 +0000 Received: by mail-pf0-f181.google.com with SMTP id 65so9152915pff.2 for ; Fri, 08 Jan 2016 04:07:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-type; bh=TeReJByUGOZ0sQJqLasAx2SVscQIqIeSiu7BOErgdTo=; b=Tw9m2FCvptL9uRq2O7kp6wS5THhJ2Pk+vn3VwP948eAy8ITZnupQcuF8de5RL0egS+ NSosIWXzV6oDLlSdTtaL8LxJgiGytjKdCLl1oXIOYc+G9zUki6DylEzoQLoU3BWUzFEK j/0DoLetQ2thASw9Gnt/LMY8zfRrGg1bntFv5qKqQvu8UcaBsFZDrWMy8O1EAllok4LQ kuXMWgu+pQR56imz76NEF/lXYNS07STEfAoaUwtxEEEkHbatoZZyBmFEXKrM+AUNAkLV VDCXGBi79/43+o5CkREQGMhyg/pA7aNkNT/y1VBWJc6ofpkLbHeziBm3/eZTTa2QBCNA 2EDg== X-Gm-Message-State: ALoCoQmTlb45vP3hFsgBx2EiIeWhLJuwqVkIMKYKdADXzqVabi/12feh6FHawCWihr7TKUP4K7Js3fiYAL3LD1GxoLZtQB20oQ== X-Received: by 10.98.32.194 with SMTP id m63mr3731161pfj.27.1452254844661; Fri, 08 Jan 2016 04:07:24 -0800 (PST) Received: from [10.1.1.11] (58-6-183-210.dyn.iinet.net.au. [58.6.183.210]) by smtp.googlemail.com with ESMTPSA id y26sm4437797pfi.88.2016.01.08.04.07.21 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 08 Jan 2016 04:07:23 -0800 (PST) To: "gcc-patches@gcc.gnu.org" Cc: Kyrill Tkachov , Ramana Radhakrishnan , Jim Wilson From: Kugan Subject: [ARM][PR69194] Fix ICE in in extract_insn Message-ID: <568FA675.9050405@linaro.org> Date: Fri, 8 Jan 2016 23:07:17 +1100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 X-IsSubscribed: yes neon_vld1 pattern does not accept eliminable registers and due to this, testcase in PR ICE. The problem is in arm_expand_neon_args, in the NEON_ARG_MEMORY case, where it call force_reg. Since an eliminable reg is already a reg, it just returns that value, and we get the wrong result. It needs to call copy_to_mode_reg instead, like arm_expand_binop_builtin does. Attached patch does this. Regression tested on arm-none-linux-gnu with no new regression. Is this OK for trunk? Thanks, Kugan gcc/ChangeLog: 2016-01-08 Kugan Vivekanandarajah Jim Wilson PR target/69194 * config/arm/arm-builtins.c (arm_expand_neon_args): Call copy_to_mode_reg instead of force_reg. gcc/testsuite/ChangeLog: 2016-01-08 Kugan Vivekanandarajah PR target/69194 * gcc.target/arm/pr69194.C: New test. diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c index 11cd17d..40dd620 100644 --- a/gcc/config/arm/arm-builtins.c +++ b/gcc/config/arm/arm-builtins.c @@ -2146,7 +2146,7 @@ constant_arg: if (!(*insn_data[icode].operand[opno].predicate) (op[argc], mode[argc])) op[argc] = (replace_equiv_address - (op[argc], force_reg (Pmode, XEXP (op[argc], 0)))); + (op[argc], copy_to_mode_reg (Pmode, XEXP (op[argc], 0)))); break; case NEON_ARG_STOP: diff --git a/gcc/testsuite/gcc.target/arm/pr69194.C b/gcc/testsuite/gcc.target/arm/pr69194.C index e69de29..b78fb5b 100644 --- a/gcc/testsuite/gcc.target/arm/pr69194.C +++ b/gcc/testsuite/gcc.target/arm/pr69194.C @@ -0,0 +1,504 @@ + +/* { dg-do-compile } */ +/* { dg-require-effective-target arm_neon } */ +/* { dg-options "-O2 -mfpu=neon -S -Wno-deprecated-declarations" } */ + +namespace std { + typedef int size_t; + typedef int ptrdiff_t; + template _Tp *__addressof(_Tp &__r) { return &__r; } + template struct __array_traits { + typedef _Tp _Type[_Nm]; + static _Tp &_S_ref(_Type __t, size_t __n) { return __t[__n]; } + }; + template struct array { + typedef _Tp *pointer; + typedef __array_traits<_Tp, _Nm> _AT_Type; + typename _AT_Type::_Type _M_elems; + pointer data() { return __addressof(_AT_Type::_S_ref(_M_elems, 0)); } + }; + template class complex; + template <> struct complex { + typedef float _ComplexT; + complex(_ComplexT); + _ComplexT _M_value; + }; +} + +typedef __simd128_float32_t float32x4_t; +namespace Eigen { + const int Dynamic = -1; + void vld1q_f32(const float *__a) { __builtin_neon_vld1v4sf(__a); } + const int EvalBeforeNestingBit = 2; + const int NestByRefBit = 6; + enum { Unaligned }; + enum { + DefaultTraversal, + SliceVectorizedTraversal, + InvalidTraversal, + NoUnrolling, + ColMajor + }; + enum { ReadOnlyAccessors, WriteAccessors }; + struct Dense; + namespace internal { + template struct traits; + template struct traits : traits {}; + template struct accessors_level { + enum { has_write_access, value }; + }; + } + template struct EigenBase; + template class DenseBase; + template ::value> + class DenseCoeffsBase; + template + class Matrix; + template class MatrixBase; + template class CwiseUnaryOp; + template class CoeffBasedProduct; + template class MapBase; + template class Stride; + template > class Map; + template class ArrayWrapper; + namespace internal { + template struct product_type; + } + template ::value> + struct ProductReturnType; + namespace internal { + template struct conditional { + typedef Then type; + }; + template struct conditional { + typedef Else type; + }; + template struct is_same { + enum { value = 1 }; + }; + template struct remove_all { typedef T type; }; + template struct remove_all { + typedef typename remove_all::type type; + }; + template struct add_const_on_value_type { typedef T type; }; + template struct scalar_product_traits { + typedef T ReturnType; + }; + } + typedef std::ptrdiff_t DenseIndex; + namespace internal { + class no_assignment_operator {}; + template struct promote_index_type { + typedef typename conditional::type type; + }; + template class variable_if_dynamic { + public: + variable_if_dynamic(T) {} + }; + template struct packet_traits; + template struct unpacket_traits; + template class compute_matrix_flags { + public: + enum { ret }; + }; + template struct plain_matrix_type { + typedef Matrix::Scalar, traits::MaxRowsAtCompileTime, + traits::MaxColsAtCompileTime> type; + }; + template struct eval { + typedef typename plain_matrix_type::type type; + }; + template struct ref_selector { + typedef typename conditional::type type; + }; + template ::type> + struct nested { + typedef typename conditional::Flags, PlainObject, + typename ref_selector::type>::type type; + }; + template struct dense_xpr_base { + typedef MatrixBase type; + }; + template + struct special_scalar_op_base : BaseType {}; + template struct is_lvalue { + enum { value }; + }; + } + template struct GenericNumTraits { + enum { ReadCost, AddCost }; + typedef T Real; + }; + template struct NumTraits : GenericNumTraits {}; + namespace internal { + template + Packet ploadu(const typename unpacket_traits::type *); + template + Packet ploadt(typename unpacket_traits::type *from) { + ploadu(from); + } + typedef float32x4_t Packet4f; + template <> struct packet_traits { typedef Packet4f type; }; + template <> struct unpacket_traits { typedef float type; }; + template <> Packet4f ploadu(const float *from) { vld1q_f32(from); } + struct Packet2cf {}; + template <> struct packet_traits> { + typedef Packet2cf type; + enum { AlignedOnScalar, size }; + }; + template <> struct unpacket_traits { + typedef std::complex type; + }; + template <> Packet2cf ploadu(const std::complex *from) { + ploadu((float *)from); + } + template struct scalar_pow_op; + } + template + class DenseCoeffsBase : public EigenBase { + }; + template + class DenseCoeffsBase + : public DenseCoeffsBase { + public: + typedef DenseCoeffsBase Base; + typedef typename internal::traits::Index Index; + Base::derived; + template + void copyPacket(Index row, Index col, const DenseBase &other) { + derived().template writePacket( + row, col, other.derived().template packet(row, col)); + } + template + void copyPacketByOuterInner(Index, Index inner, + const DenseBase &other) { + Index row; + Index col; + copyPacket(row, col, other); + } + }; + template + class DenseBase + : public internal::special_scalar_op_base< + Derived, typename internal::traits::Scalar, + typename NumTraits::Scalar>::Real, + DenseCoeffsBase> { + public: + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename NumTraits::Real RealScalar; + typedef internal::special_scalar_op_base> Base; + Base::derived; + template + Derived &lazyAssign(const DenseBase &); + }; + template class MatrixBase : public DenseBase { + public: + typename internal::traits; + typedef DenseBase Base; + Base::derived; + template + const typename ProductReturnType::Type + operator*(const MatrixBase &) const; + ArrayWrapper array() const { return derived(); } + }; + template struct EigenBase { + Derived derived(); + const Derived &derived() const { return *static_cast(this); } + }; + namespace internal { + template struct assign_traits { + enum { DstIsAligned, SrcIsAligned }; + enum { MayInnerVectorize = SrcIsAligned, MaySliceVectorize }; + enum { + Traversal = MayInnerVectorize ?: MaySliceVectorize ?: DefaultTraversal, + Unrolling = DefaultTraversal ?: NoUnrolling + }; + }; + template ::Unrolling> + struct assign_impl; + template + struct assign_impl { + typedef typename Derived1::Index Index; + static void run(Derived1 dst, Derived2 src) { + typedef typename Derived1::Scalar Scalar; + typedef packet_traits PacketTraits; + enum { + packetSize = PacketTraits::size, + alignable = PacketTraits::AlignedOnScalar, + dstAlignment + }; + for (Index outer;;) + for (Index inner;;) + dst.template copyPacketByOuterInner( + outer, inner, src); + } + }; + } + template + template + Derived &DenseBase::lazyAssign(const DenseBase &other) { + enum { SameType = internal::is_same::value }; + internal::assign_impl < Derived, OtherDerived, + SameType ? internal::assign_traits::Traversal + : InvalidTraversal > ::run(derived(), other.derived()); + } + namespace internal { + template struct assign_selector; + template + struct assign_selector { + static Derived run(Derived dst, OtherDerived other) { dst.lazyAssign(other); } + }; + } + template + class PlainObjectBase : public internal::dense_xpr_base::type { + public: + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + Scalar coeff(Index, Index) const; + template void writePacket(Index, Index, PacketScalar); + template + Derived _set_noalias(const DenseBase &other) { + internal::assign_selector::run(this->derived(), + other.derived()); + } + }; + namespace internal { + template + struct traits> { + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef DenseIndex Index; + enum { + RowsAtCompileTime, + ColsAtCompileTime, + MaxRowsAtCompileTime = _MaxRows, + MaxColsAtCompileTime, + Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, + _MaxCols>::ret, + CoeffReadCost = NumTraits::ReadCost + }; + }; + } + template + class Matrix : public PlainObjectBase> { + public: + typedef PlainObjectBase Base; + enum { + RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, + ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, + MaxRowsAtCompileTime = + Eigen::internal::traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = + Eigen::internal::traits::MaxColsAtCompileTime, + Flags = Eigen::internal::traits::Flags, + CoeffReadCost = Eigen::internal::traits::CoeffReadCost + }; + template Matrix(MatrixBase &other) { + Base::_set_noalias(other); + } + template Matrix(const EigenBase); + }; + namespace internal { + template + struct traits> : traits {}; + } + template class CwiseUnaryOpImpl; + template + class CwiseUnaryOp + : internal::no_assignment_operator, + public CwiseUnaryOpImpl::StorageKind> { + }; + template + class CwiseUnaryOpImpl + : public internal::dense_xpr_base>::type {}; + template + class MapBase : public internal::dense_xpr_base::type { + public: + typename internal::dense_xpr_base; + enum { + RowsAtCompileTime = internal::traits::RowsAtCompileTime, + ColsAtCompileTime = internal::traits::ColsAtCompileTime + }; + typedef typename internal::traits::Index Index; + typedef typename internal::traits::Scalar Scalar; + typedef typename internal::packet_traits::type PacketScalar; + typedef typename internal::conditional::value, + Scalar, Scalar *>::type PointerType; + template PacketScalar packet(Index, Index) const { + internal::ploadt(m_data); + } + MapBase(PointerType dataPtr) + : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {} + PointerType m_data; + internal::variable_if_dynamic m_rows; + internal::variable_if_dynamic m_cols; + }; + namespace internal { + template + struct traits> + : traits {}; + } + template + class Map : public MapBase> { + public: + typedef MapBase Base; + enum { + RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, + ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, + MaxRowsAtCompileTime = Eigen::internal::traits::MaxRowsAtCompileTime, + MaxColsAtCompileTime = Eigen::internal::traits::MaxColsAtCompileTime, + Flags = Eigen::internal::traits::Flags, + CoeffReadCost = Eigen::internal::traits::CoeffReadCost + }; + typedef typename Base::PointerType PointerArgType; + Map(PointerArgType dataPtr) : Base(dataPtr) {} + }; + enum { Large, Small }; + namespace internal { + template struct product_type_selector; + template struct product_size_category { + enum { is_large = MaxSize == Dynamic, value = is_large ? Large : 1 ?: Small }; + }; + template struct product_type { + typedef typename remove_all::type _Lhs; + typedef typename remove_all::type _Rhs; + enum { + MaxRows = _Lhs::MaxRowsAtCompileTime, + Rows = _Lhs::RowsAtCompileTime, + MaxCols = _Rhs::MaxColsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + MaxDepth = _Lhs::MaxColsAtCompileTime <= _Rhs::MaxRowsAtCompileTime + ?: _Rhs::MaxRowsAtCompileTime, + Depth = _Lhs::ColsAtCompileTime <= _Rhs::RowsAtCompileTime + ?: _Rhs::RowsAtCompileTime + }; + enum { + rows_select = product_size_category::value, + cols_select = product_size_category::value, + depth_select = product_size_category::value + }; + typedef product_type_selector + selector; + enum { value = selector::ret }; + }; + template <> struct product_type_selector { + enum { ret }; + }; + } + template struct ProductReturnType { + typedef typename internal::nested::type + LhsNested; + typedef typename internal::nested::type + RhsNested; + typedef CoeffBasedProduct Type; + }; + template + template + const typename ProductReturnType::Type + MatrixBase:: + operator*(const MatrixBase &other) const { + return typename ProductReturnType::Type( + derived(), other.derived()); + } + namespace internal { + template + struct product_packet_impl; + template + struct traits> { + typedef typename remove_all::type _LhsNested; + typedef typename remove_all::type _RhsNested; + typedef typename scalar_product_traits< + typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType + Scalar; + typedef typename promote_index_type::Index, + typename traits<_RhsNested>::Index>::type + Index; + enum { + LhsFlags = _LhsNested::Flags, + RhsFlags = _RhsNested::Flags, + RowsAtCompileTime = _LhsNested::RowsAtCompileTime, + ColsAtCompileTime = _RhsNested::ColsAtCompileTime, + InnerSize = _LhsNested::RowsAtCompileTime, + MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, + MaxColsAtCompileTime = is_same::value, + CanVectorizeLhs = packet_traits::size, + Flags, + CoeffReadCost = NumTraits::AddCost + }; + }; + } + template + class CoeffBasedProduct + : internal::no_assignment_operator, + public MatrixBase> { + public: + typedef MatrixBase Base; + typedef typename Base::PacketScalar PacketScalar; + typedef typename Eigen::internal::nested::type Nested; + typedef typename Eigen::internal::traits::Index Index; + typedef typename internal::traits::_LhsNested _LhsNested; + typedef typename internal::traits::_RhsNested _RhsNested; + template + CoeffBasedProduct(Lhs lhs, Rhs &rhs) + : m_lhs(lhs), m_rhs(rhs) {} + template PacketScalar packet(Index row, Index col) const { + PacketScalar res; + internal::product_packet_impl::run(row, col, m_lhs, + m_rhs, res); + } + typename internal::add_const_on_value_type::type m_lhs; + typename internal::add_const_on_value_type::type m_rhs; + }; + namespace internal { + template + struct product_packet_impl { + typedef typename Lhs::Index Index; + static void run(Index row, Index col, Lhs lhs, Rhs rhs, Packet) { + lhs.coeff(row, 0), rhs.template packet(0, col); + } + }; + } + template class ArrayBase : public DenseBase { + public: + typedef typename internal::traits::Scalar Scalar; + CwiseUnaryOp, Derived> pow(Scalar); + }; + namespace internal { + template + struct traits> + : traits::type> {}; + } + template + class ArrayWrapper : public ArrayBase> { + public: + typedef typename internal::nested::type NestedExpressionType; + ArrayWrapper(ExpressionType matrix) : m_expression(matrix) {} + NestedExpressionType m_expression; + }; +} + +struct crashes { + int x; + int y; +}; +using Scalar = std::complex; +using Points = std::array; +using Table = Eigen::Matrix; +using Vec = Eigen::Matrix; +crashes do_crash(Table cal, Points p) { + using map_t = Eigen::Map>; + map_t points_mat(p.data()); + Vec top = (cal * points_mat).array().pow(2); +}