diff options
author | Jan Hubicka <jh@suse.cz> | 2021-04-01 12:11:39 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2021-04-01 12:11:39 +0200 |
commit | 3064fc21aa29d8e04b23c0b52dc4f67de1da6b2f (patch) | |
tree | d909c63a5109536cc33045f23af9361402d2e3dd | |
parent | 7b478ede2a37b1586846abd355bd902ea4cae117 (diff) | |
download | gcc-3064fc21aa29d8e04b23c0b52dc4f67de1da6b2f.zip gcc-3064fc21aa29d8e04b23c0b52dc4f67de1da6b2f.tar.gz gcc-3064fc21aa29d8e04b23c0b52dc4f67de1da6b2f.tar.bz2 |
Add testcase for PR98265
gcc/testsuite/ChangeLog:
2021-04-01 Jan Hubicka <hubicka@ucw.cz>
PR ipa/98265
* gcc.dg/tree-ssa/pr98265.C: New test.
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr98265.C | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98265.C b/gcc/testsuite/gcc.dg/tree-ssa/pr98265.C new file mode 100644 index 0000000..9c798e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98265.C @@ -0,0 +1,348 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +extern void __assert_fail(const char*, const char*, int, const char*); +namespace Eigen { +enum { AutoAlign }; +template <int, typename> +struct conditional; +template <typename Else> +struct conditional<false, Else> { + typedef Else type; +}; +template <typename T> +struct remove_reference { + typedef T type; +}; +struct is_arithmetic { + enum { value }; +}; +template <typename> +struct traits; +template <typename T> +struct traits<const T> : traits<T> {}; +template <typename> +struct evaluator; +template <typename> +struct EigenBase; +template <typename> +class PlainObjectBase; +template <typename, int _Rows, int _Cols, int = AutoAlign, int = _Rows, + int = _Cols> +class Matrix; +template <typename> +class MatrixBase; +template <typename, typename> +class CwiseNullaryOp; +template <typename, typename, typename> +class CwiseBinaryOp; +template <typename> +struct scalar_constant_op; +template <int _Rows> +struct size_at_compile_time { + enum { ret = _Rows }; +}; +struct ref_selector { + typedef const Matrix<float, 3, 1>& type; +}; +template <typename Derived> +struct dense_xpr_base { + typedef MatrixBase<Derived> type; +}; +template <typename Derived, typename = typename traits<Derived>::XprKind> +struct generic_xpr_base { + typedef typename dense_xpr_base<Derived>::type type; +}; +template <typename Expr, typename Scalar = typename Expr::Scalar> +struct plain_constant_type { + ; + typedef CwiseNullaryOp<scalar_constant_op<Scalar>, + Matrix<Scalar, traits<Expr>::ColsAtCompileTime, + traits<Expr>::MaxRowsAtCompileTime, + traits<Expr>::MaxColsAtCompileTime>> + type; +}; +struct scalar_product_op { + float operator()(float a, float b) { return a * b; } +}; +template <typename> +struct scalar_constant_op { + scalar_constant_op(float other) : m_other(other) {} + float operator()() { return m_other; } + float m_other; +}; +struct assign_op { + void assignCoeff(float& a, float b) { a = b; } +}; +template <typename Derived> +class DenseCoeffsBase : public EigenBase<Derived> { + public: + typedef typename traits<Derived>::Scalar Scalar; + typedef + typename conditional<is_arithmetic::value, Scalar>::type CoeffReturnType; +}; +template <typename Derived> +class DenseBase : public DenseCoeffsBase<Derived> { + public: + enum { + RowsAtCompileTime = traits<Derived>::RowsAtCompileTime, + SizeAtCompileTime = size_at_compile_time<RowsAtCompileTime>::ret, + MaxSizeAtCompileTime + }; +}; +template <typename Derived> +class MatrixBase : public DenseBase<Derived> { + public: + using DenseBase<Derived>::derived; + template <typename T> + CwiseBinaryOp<scalar_product_op, const Derived, + const typename plain_constant_type<Derived, T>::type> + operator*(T& scalar) { + return CwiseBinaryOp<scalar_product_op, const Derived, + const typename plain_constant_type<Derived>::type>( + derived(), typename plain_constant_type<Derived>::type(derived().rows(), + 0, scalar)); + } +}; +template <typename Derived> +struct EigenBase { + const Derived& derived() const { return *static_cast<const Derived*>(this); } + Derived& const_cast_derived() const { + return *static_cast<Derived*>(const_cast<EigenBase*>(this)); + } +}; +template <typename> +struct binary_evaluator; +template <typename T> +struct evaluator<const T> : evaluator<T> { + evaluator(const T& xpr) : evaluator<T>(xpr) {} +}; +template <typename Derived> +struct evaluator { + typedef Derived PlainObjectType; + typedef typename PlainObjectType::Scalar Scalar; + evaluator(const PlainObjectType& m) : m_data(m.data()) {} + typename PlainObjectType::CoeffReturnType coeff(long row, long) { + return m_data[row]; + } + Scalar& coeffRef(long row, long) { return const_cast<Scalar*>(m_data)[row]; } + const Scalar* m_data; +}; +template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, + int MaxCols> +struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> + : evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols>>> { + typedef Matrix<Scalar, Rows, Cols> XprType; + evaluator(const XprType& m) : evaluator<PlainObjectBase<XprType>>(m) {} +}; +struct nullary_wrapper { + template <typename IndexType> + float operator()(scalar_constant_op<float> op, IndexType, IndexType) const { + return op(); + } +}; +template <typename NullaryOp, typename PlainObjectType> +struct evaluator<CwiseNullaryOp<NullaryOp, PlainObjectType>> { + typedef CwiseNullaryOp<NullaryOp, PlainObjectType> XprType; + evaluator(XprType n) : m_functor(n.functor()) {} + template <typename IndexType> + typename XprType::CoeffReturnType coeff(IndexType row, IndexType col) { + return m_wrapper(m_functor, row, col); + } + NullaryOp m_functor; + nullary_wrapper m_wrapper; +}; +template <typename BinaryOp, typename Lhs, typename Rhs> +struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> + : binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> { + evaluator(CwiseBinaryOp<BinaryOp, Lhs, Rhs> xpr) + : binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>>(xpr) {} +}; +template <typename BinaryOp, typename Lhs, typename Rhs> +struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> { + typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; + binary_evaluator(XprType xpr) : m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {} + typename XprType::CoeffReturnType coeff(long row, long col) { + return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col)); + } + BinaryOp m_functor; + evaluator<Lhs> m_lhsImpl; + evaluator<Rhs> m_rhsImpl; +}; +template <typename Kernel, int Index, int Stop> +struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling { + enum { outer, inner = Index }; + static void run(Kernel kernel) { + kernel.assignCoeffByOuterInner(outer, inner); + copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Index + 1, + Stop>::run(kernel); + } +}; +template <typename Kernel, int Stop> +struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Stop, + Stop> { + static void run(Kernel) {} +}; +template <typename Kernel> +struct dense_assignment_loop { + static void run(Kernel kernel) { + typedef typename Kernel::DstEvaluatorType::XprType DstXprType; + enum { size = DstXprType::SizeAtCompileTime, alignedSize = 0 }; + copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, + size>::run(kernel); + } +}; +template <typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, + typename Functor> +class generic_dense_assignment_kernel { + typedef typename DstEvaluatorTypeT::XprType DstXprType; + + public: + typedef DstEvaluatorTypeT DstEvaluatorType; + typedef SrcEvaluatorTypeT SrcEvaluatorType; + generic_dense_assignment_kernel(DstEvaluatorType dst, SrcEvaluatorType src, + Functor, DstXprType& dstExpr) + : m_dst(dst), m_src(src), m_dstExpr(dstExpr) {} + long assignCoeff_col; + void assignCoeffByOuterInner(long, long inner) { + long __trans_tmp_1 = inner; + m_functor.assignCoeff(m_dst.coeffRef(__trans_tmp_1, assignCoeff_col), + m_src.coeff(__trans_tmp_1, assignCoeff_col)); + } + DstEvaluatorType m_dst; + SrcEvaluatorType m_src; + Functor m_functor; + DstXprType& m_dstExpr; +}; +template <typename DstXprType, typename SrcXprType, typename Functor> +void call_dense_assignment_loop(DstXprType& dst, SrcXprType src, Functor func) { + typedef evaluator<DstXprType> DstEvaluatorType; + typedef evaluator<SrcXprType> SrcEvaluatorType; + SrcEvaluatorType srcEvaluator(src); + DstEvaluatorType dstEvaluator(dst); + typedef generic_dense_assignment_kernel<DstEvaluatorType, SrcEvaluatorType, + Functor> + Kernel; + Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived()); + dense_assignment_loop<Kernel>::run(kernel); +} +template <typename Dst, typename Src, typename Func> +void call_assignment_no_alias(Dst& dst, Src src, Func func) { + enum { NeedToTranspose }; + typename conditional<NeedToTranspose, Dst&>::type actualDst(dst); + CwiseBinaryOp<scalar_product_op, const Matrix<float, 3, 1>, + const CwiseNullaryOp<scalar_constant_op<float>, + const Matrix<float, 3, 1, 0, 2, 3>>> + __trans_tmp_4 = src; + call_dense_assignment_loop(actualDst, __trans_tmp_4, func); +} +template <int Size> +struct plain_array { + float array[Size]; +}; +template <int Size, int _Rows> +class DenseStorage { + plain_array<Size> m_data; + + public: + DenseStorage() {} + DenseStorage(const DenseStorage&); + static long rows() { return _Rows; } + const float* data() const { return m_data.array; } + float* data() { return m_data.array; } +}; +template <typename Derived> +class PlainObjectBase : public dense_xpr_base<Derived>::type { + public: + typedef typename dense_xpr_base<Derived>::type Base; + typedef typename traits<Derived>::Scalar Scalar; + DenseStorage<Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime> m_storage; + long rows() const { return m_storage.rows(); } + const Scalar* data() const { return m_storage.data(); } + PlainObjectBase() {} + template <typename OtherDerived> + PlainObjectBase(const DenseBase<OtherDerived>& other) { + _set_noalias(other); + } + template <typename OtherDerived> + void _set_noalias(const DenseBase<OtherDerived>& other) { + call_assignment_no_alias(this->derived(), other.derived(), assign_op()); + } +}; +template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, + int _MaxCols> +struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> { + typedef _Scalar Scalar; + typedef int XprKind; + enum { + RowsAtCompileTime = _Rows, + ColsAtCompileTime, + MaxRowsAtCompileTime, + MaxColsAtCompileTime, + }; +}; +template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, + int _MaxCols> +class Matrix + : public PlainObjectBase< + Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> { + public: + typedef PlainObjectBase<Matrix> Base; + typedef typename traits<Matrix>::Scalar Scalar; + Matrix(Scalar& x, Scalar& y, Scalar& z) { + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + } + template <typename OtherDerived> + Matrix(const EigenBase<OtherDerived>& other) : Base(other.derived()) {} + using Base::m_storage; +}; +template <typename BinaryOp, typename Lhs, typename Rhs> +struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs>> { + typedef typename traits<Lhs>::XprKind XprKind; + enum { RowsAtCompileTime }; + typedef float Scalar; +}; +template <typename> +class CwiseBinaryOpImpl; +template <typename, typename, typename RhsType> +class CwiseBinaryOp : public CwiseBinaryOpImpl<RhsType> { + public: + typedef ref_selector::type LhsNested; + typedef RhsType RhsNested; + CwiseBinaryOp(const Matrix<float, 3, 1>& aLhs, RhsType& aRhs) + : m_lhs(aLhs), m_rhs(aRhs) {} + remove_reference<LhsNested>::type& lhs() { return m_lhs; } + typename remove_reference<RhsNested>::type& rhs() { return m_rhs; } + LhsNested m_lhs; + RhsNested m_rhs; +}; +template <typename> +class CwiseBinaryOpImpl + : public generic_xpr_base<CwiseBinaryOp< + scalar_product_op, const Matrix<float, 3, 1>, + const CwiseNullaryOp<scalar_constant_op<float>, + const Matrix<float, 3, 1, 0, 2, 3>>>>::type {}; +template <typename NullaryOp, typename PlainObjectType> +struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType>> + : traits<PlainObjectType> {}; +template <typename, typename PlainObjectType> +class CwiseNullaryOp + : public dense_xpr_base<CwiseNullaryOp<int, PlainObjectType>>::type { + public: + CwiseNullaryOp(long rows, long, scalar_constant_op<float> func) + : m_functor(func) { + rows ? void() : __assert_fail("", "", 1, __PRETTY_FUNCTION__); + } + scalar_constant_op<float> functor() { return m_functor; } + scalar_constant_op<float> m_functor; +}; +} // namespace Eigen +Eigen::Matrix<float, 3, 1> should_inline(float x, float y, float z, + float scale) { + return Eigen::Matrix<float, 3, 1>(x, y, z) * scale; +} + +// We should inline everything to should_inline + +/* { dg-final { scan-tree-dump-times "Function" "optimized" } } */ |