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  <rguenther@suse.de>

	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
This commit is contained in:
Richard Biener 2019-07-31 14:38:21 +00:00 committed by Richard Biener
parent a28351e7f5
commit 208149b720
4 changed files with 257 additions and 3 deletions

View file

@ -1,3 +1,9 @@
2019-07-31 Richard Biener <rguenther@suse.de>
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 <rguenther@suse.de>
PR tree-optimization/91293

View file

@ -1,3 +1,8 @@
2019-07-31 Richard Biener <rguenther@suse.de>
PR tree-optimization/91280
* g++.dg/torture/pr91280.C: New testcase.
2019-07-31 Richard Biener <rguenther@suse.de>
PR tree-optimization/91293

View file

@ -0,0 +1,223 @@
// { dg-do compile }
enum { Aligned, RowMajor };
enum { ReadOnlyAccessors };
template <typename> struct K {
enum { value };
};
template <typename> struct traits;
template <typename T> struct traits<const T> : traits<T> {};
struct A {
enum { has_write_access, value };
};
template <typename, int n> class array {
public:
int operator[](unsigned long p1) { return values[p1]; }
int values[n];
};
template <typename> struct I;
template <typename, int, template <class> class = I> class M;
template <typename, int, int, typename> class J;
template <typename, int> class N;
template <typename, typename> class D;
template <typename, typename, typename, typename> class TensorContractionOp;
template <long, typename> class TensorChippingOp;
class C;
template <typename DenseIndex, int NumDims>
struct K<array<DenseIndex, NumDims>> {
static const long value = NumDims;
};
template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_>
struct traits<J<Scalar_, NumIndices_, Options_, IndexType_>> {
typedef IndexType_ Index;
};
template <typename PlainObjectType, int Options_,
template <class> class MakePointer_>
struct traits<M<PlainObjectType, Options_, MakePointer_>>
: traits<PlainObjectType> {};
template <typename T> struct B { typedef T type; };
template <typename Derived> class N<Derived, ReadOnlyAccessors> {
public:
typedef typename traits<Derived>::Index Index;
D<int, Derived> m_fn1();
template <typename OtherDerived, typename Dimensions>
TensorContractionOp<Dimensions, Derived, const OtherDerived, int>
m_fn2(OtherDerived, Dimensions);
template <Index> TensorChippingOp<1, Derived> m_fn3(Index);
};
template <typename Derived, int = A::value>
class N : public N<Derived, ReadOnlyAccessors> {
public:
template <typename DeviceType> C m_fn4(DeviceType);
};
template <typename, typename> struct TensorEvaluator;
template <typename UnaryOp, typename ArgType, typename Device>
struct TensorEvaluator<const D<UnaryOp, ArgType>, Device> {
TensorEvaluator(D<UnaryOp, ArgType>, Device);
};
template <typename, typename> class D {
public:
typedef typename B<D>::type Nested;
};
template <typename Indices_, typename LeftArgType_, typename RightArgType_,
typename OutputKernelType_, typename Device_>
struct traits<
TensorEvaluator<const TensorContractionOp<Indices_, LeftArgType_,
RightArgType_, OutputKernelType_>,
Device_>> {
typedef Indices_ Indices;
typedef LeftArgType_ LeftArgType;
typedef RightArgType_ RightArgType;
typedef OutputKernelType_ OutputKernelType;
typedef Device_ Device;
};
template <typename, typename LhsXprType, typename RhsXprType, typename>
class TensorContractionOp {
public:
typedef typename B<TensorContractionOp>::type Nested;
typename LhsXprType::Nested m_fn5();
typename RhsXprType::Nested m_fn6();
};
template <typename Derived> struct TensorContractionEvaluatorBase {
typedef typename traits<Derived>::LeftArgType LeftArgType;
typedef typename traits<Derived>::RightArgType RightArgType;
typedef typename traits<Derived>::Device Device;
TensorContractionEvaluatorBase(
TensorContractionOp<typename traits<Derived>::Indices, LeftArgType,
RightArgType,
typename traits<Derived>::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<int>::value)
m_j_size = m_j_strides[nocontract_idx];
nocontract_idx++;
}
}
}
array<long, 1> m_j_strides;
long m_j_size;
TensorEvaluator<RightArgType, Device> m_leftImpl;
TensorEvaluator<LeftArgType, Device> m_rightImpl;
};
template <typename Indices, typename LeftArgType, typename RightArgType,
typename OutputKernelType, typename Device>
struct TensorEvaluator<
const TensorContractionOp<Indices, LeftArgType, RightArgType,
OutputKernelType>,
Device>
: TensorContractionEvaluatorBase<TensorEvaluator<
const TensorContractionOp<Indices, LeftArgType, RightArgType,
OutputKernelType>,
Device>> {
typedef TensorEvaluator Self;
typedef TensorContractionEvaluatorBase<Self> Base;
TensorEvaluator(
TensorContractionOp<Indices, LeftArgType, RightArgType, OutputKernelType>
p1,
Device p2)
: Base(p1, p2) {}
};
template <long DimId, typename XprType>
struct traits<TensorChippingOp<DimId, XprType>> : traits<XprType> {};
template <long, typename XprType>
class TensorChippingOp : public N<TensorChippingOp<1, XprType>> {
public:
typedef typename B<TensorChippingOp>::type Nested;
};
template <long DimId, typename ArgType, typename Device>
struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device> {
static const int NumInputDims = K<typename ArgType::Dimensions>::value;
array<long, NumInputDims> m_dimensions;
};
template <long DimId, typename ArgType, typename Device>
struct TensorEvaluator<TensorChippingOp<DimId, ArgType>, Device>
: TensorEvaluator<const TensorChippingOp<1, ArgType>, Device> {
TensorEvaluator(TensorChippingOp<DimId, ArgType>, Device);
};
template <typename, typename RhsXprType> class TensorAssignOp {
public:
TensorAssignOp(TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>>,
RhsXprType);
TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>> m_fn7();
typename RhsXprType::Nested m_fn8();
};
template <typename LeftArgType, typename RightArgType, typename Device>
struct TensorEvaluator<const TensorAssignOp<LeftArgType, RightArgType>,
Device> {
TensorEvaluator(TensorAssignOp<LeftArgType, RightArgType> p1, Device p2)
: m_leftImpl(p1.m_fn7(), p2), m_rightImpl(p1.m_fn8(), p2) {}
TensorEvaluator<LeftArgType, Device> m_leftImpl;
TensorEvaluator<RightArgType, Device> m_rightImpl;
};
template <typename Expression> class F {
public:
static void m_fn9(Expression p1) {
int device;
TensorEvaluator<Expression, int>(p1, device);
}
};
class C {
public:
void
operator=(TensorContractionOp<array<int, 1>,
TensorChippingOp<1, M<J<float, 3, 1, int>, 0>>,
const D<int, M<J<float, 3, 1, int>, 0>>, int>
p1) {
TensorAssignOp<
TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>>,
const TensorContractionOp<
array<int, 1>, TensorChippingOp<1, M<J<float, 3, 1, int>, 0>>,
const D<int, M<J<float, 3, 1, int>, 0>>, int>>
assign(m_expression, p1);
F<const TensorAssignOp<
TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>>,
const TensorContractionOp<
array<int, 1>, TensorChippingOp<1, M<J<float, 3, 1, int>, 0>>,
const D<int, M<J<float, 3, 1, int>, 0>>, int>>>::m_fn9(assign);
}
TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>> m_expression;
};
template <typename, int NumIndices_, int, typename> class J {
public:
typedef array<long, NumIndices_> Dimensions;
};
template <typename PlainObjectType, int Options_, template <class> class>
class M : public N<M<PlainObjectType, Options_>> {
public:
typedef typename PlainObjectType::Dimensions Dimensions;
};
template <int NDIMS> struct TTypes {
typedef M<J<float, NDIMS, RowMajor, int>, Aligned> ConstTensor;
};
class L {
public:
template <typename, long NDIMS> typename TTypes<NDIMS>::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<float, 3>(), Ty = in_y.m_fn10<float, 3>(),
Tz = out.m_fn10<float, 3>(), z = Tz;
array<int, 1> 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; });

View file

@ -3289,9 +3289,29 @@ get_constraint_for_component_ref (tree t, vec<ce_s> *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)
{