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:
parent
a28351e7f5
commit
208149b720
4 changed files with 257 additions and 3 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
223
gcc/testsuite/g++.dg/torture/pr91280.C
Normal file
223
gcc/testsuite/g++.dg/torture/pr91280.C
Normal 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; });
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue