From 208149b7201420d965991e08cb4e4c261171b0a2 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 31 Jul 2019 14:38:21 +0000 Subject: [PATCH] re PR tree-optimization/91280 (ICE in get_constraint_for_component_ref, at tree-ssa-structalias.c:3259 since r260354) 2019-07-31 Richard Biener PR tree-optimization/91280 * tree-ssa-structalias.c (get_constraint_for_component_ref): Decompose MEM_REF manually for offset handling. * g++.dg/torture/pr91280.C: New testcase. From-SVN: r273936 --- gcc/ChangeLog | 6 + gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/torture/pr91280.C | 223 +++++++++++++++++++++++++ gcc/tree-ssa-structalias.c | 26 ++- 4 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr91280.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ef8ee9fc2a5..18f2ce2268c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-07-31 Richard Biener + + PR tree-optimization/91280 + * tree-ssa-structalias.c (get_constraint_for_component_ref): + Decompose MEM_REF manually for offset handling. + 2019-07-31 Richard Biener PR tree-optimization/91293 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6cffdc28da9..f490292d534 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-31 Richard Biener + + PR tree-optimization/91280 + * g++.dg/torture/pr91280.C: New testcase. + 2019-07-31 Richard Biener PR tree-optimization/91293 diff --git a/gcc/testsuite/g++.dg/torture/pr91280.C b/gcc/testsuite/g++.dg/torture/pr91280.C new file mode 100644 index 00000000000..063bef836f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr91280.C @@ -0,0 +1,223 @@ +// { dg-do compile } + +enum { Aligned, RowMajor }; +enum { ReadOnlyAccessors }; +template struct K { + enum { value }; +}; +template struct traits; +template struct traits : traits {}; +struct A { + enum { has_write_access, value }; +}; +template class array { +public: + int operator[](unsigned long p1) { return values[p1]; } + int values[n]; +}; +template struct I; +template class = I> class M; +template class J; +template class N; +template class D; +template class TensorContractionOp; +template class TensorChippingOp; +class C; +template +struct K> { + static const long value = NumDims; +}; +template +struct traits> { + typedef IndexType_ Index; +}; +template class MakePointer_> +struct traits> + : traits {}; +template struct B { typedef T type; }; +template class N { +public: + typedef typename traits::Index Index; + D m_fn1(); + template + TensorContractionOp + m_fn2(OtherDerived, Dimensions); + template TensorChippingOp<1, Derived> m_fn3(Index); +}; +template +class N : public N { +public: + template C m_fn4(DeviceType); +}; +template struct TensorEvaluator; +template +struct TensorEvaluator, Device> { + TensorEvaluator(D, Device); +}; +template class D { +public: + typedef typename B::type Nested; +}; +template +struct traits< + TensorEvaluator, + Device_>> { + typedef Indices_ Indices; + typedef LeftArgType_ LeftArgType; + typedef RightArgType_ RightArgType; + typedef OutputKernelType_ OutputKernelType; + typedef Device_ Device; +}; +template +class TensorContractionOp { +public: + typedef typename B::type Nested; + typename LhsXprType::Nested m_fn5(); + typename RhsXprType::Nested m_fn6(); +}; +template struct TensorContractionEvaluatorBase { + typedef typename traits::LeftArgType LeftArgType; + typedef typename traits::RightArgType RightArgType; + typedef typename traits::Device Device; + TensorContractionEvaluatorBase( + TensorContractionOp::Indices, LeftArgType, + RightArgType, + typename traits::OutputKernelType> + p1, + Device p2) + : m_leftImpl(p1.m_fn6(), p2), m_rightImpl(p1.m_fn5(), p2) { + long nocontract_idx; + for (int i;; i++) { + bool contracting; + if (contracting) { + if (nocontract_idx < K::value) + m_j_size = m_j_strides[nocontract_idx]; + nocontract_idx++; + } + } + } + array m_j_strides; + long m_j_size; + TensorEvaluator m_leftImpl; + TensorEvaluator m_rightImpl; +}; +template +struct TensorEvaluator< + const TensorContractionOp, + Device> + : TensorContractionEvaluatorBase, + Device>> { + typedef TensorEvaluator Self; + typedef TensorContractionEvaluatorBase Base; + TensorEvaluator( + TensorContractionOp + p1, + Device p2) + : Base(p1, p2) {} +}; +template +struct traits> : traits {}; +template +class TensorChippingOp : public N> { +public: + typedef typename B::type Nested; +}; +template +struct TensorEvaluator, Device> { + static const int NumInputDims = K::value; + array m_dimensions; +}; +template +struct TensorEvaluator, Device> + : TensorEvaluator, Device> { + TensorEvaluator(TensorChippingOp, Device); +}; +template class TensorAssignOp { +public: + TensorAssignOp(TensorChippingOp<0, const M, 1>>, + RhsXprType); + TensorChippingOp<0, const M, 1>> m_fn7(); + typename RhsXprType::Nested m_fn8(); +}; +template +struct TensorEvaluator, + Device> { + TensorEvaluator(TensorAssignOp p1, Device p2) + : m_leftImpl(p1.m_fn7(), p2), m_rightImpl(p1.m_fn8(), p2) {} + TensorEvaluator m_leftImpl; + TensorEvaluator m_rightImpl; +}; +template class F { +public: + static void m_fn9(Expression p1) { + int device; + TensorEvaluator(p1, device); + } +}; +class C { +public: + void + operator=(TensorContractionOp, + TensorChippingOp<1, M, 0>>, + const D, 0>>, int> + p1) { + TensorAssignOp< + TensorChippingOp<0, const M, 1>>, + const TensorContractionOp< + array, TensorChippingOp<1, M, 0>>, + const D, 0>>, int>> + assign(m_expression, p1); + F, 1>>, + const TensorContractionOp< + array, TensorChippingOp<1, M, 0>>, + const D, 0>>, int>>>::m_fn9(assign); + } + TensorChippingOp<0, const M, 1>> m_expression; +}; +template class J { +public: + typedef array Dimensions; +}; +template class> +class M : public N> { +public: + typedef typename PlainObjectType::Dimensions Dimensions; +}; +template struct TTypes { + typedef M, Aligned> ConstTensor; +}; +class L { +public: + template typename TTypes::ConstTensor m_fn10(); +}; +class H { +public: + H(int *); +}; +class G { +public: + G(H *(int *)); +}; +int Run_d; +class O : H { +public: + int BatchMatMul_context; + O() : H(&BatchMatMul_context) { + L out, in_y, in_x; + auto Tx = in_x.m_fn10(), Ty = in_y.m_fn10(), + Tz = out.m_fn10(), z = Tz; + array contract_pairs; + auto x = Tx.m_fn3<0>(0); + auto y = Ty.m_fn1(); + z.m_fn4(Run_d) = x.m_fn2(y, contract_pairs); + } +}; +G registrar__body__0__object([](int *) -> H * { O(); return 0; }); diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 974b639f2fe..75c6faedc1f 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -3289,9 +3289,29 @@ get_constraint_for_component_ref (tree t, vec *results, return; } - /* Pretend to take the address of the base, we'll take care of - adding the required subset of sub-fields below. */ - get_constraint_for_1 (t, results, true, lhs_p); + /* Avoid creating pointer-offset constraints, so handle MEM_REF + offsets directly. Pretend to take the address of the base, + we'll take care of adding the required subset of sub-fields below. */ + if (TREE_CODE (t) == MEM_REF + && !integer_zerop (TREE_OPERAND (t, 0))) + { + poly_offset_int off = mem_ref_offset (t); + off <<= LOG2_BITS_PER_UNIT; + off += bitpos; + poly_int64 off_hwi; + if (off.to_shwi (&off_hwi)) + bitpos = off_hwi; + else + { + bitpos = 0; + bitmaxsize = -1; + } + get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p); + do_deref (results); + } + else + get_constraint_for_1 (t, results, true, lhs_p); + /* Strip off nothing_id. */ if (results->length () == 2) { -- 2.30.2