]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR tree-optimization/91280 (ICE in get_constraint_for_component_ref...
authorRichard Biener <rguenther@suse.de>
Fri, 2 Aug 2019 12:07:33 +0000 (12:07 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 2 Aug 2019 12:07:33 +0000 (12:07 +0000)
2019-08-02  Richard Biener  <rguenther@suse.de>

Backport from mainline
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.

2019-07-31  Richard Biener  <rguenther@suse.de>

PR tree-optimization/91293
* tree-vect-slp.c (vect_build_slp_tree_2): Do not swap operands
of reduction stmts.

* gcc.dg/vect/pr91293-1.c: New testcase.
* gcc.dg/vect/pr91293-2.c: Likewise.
* gcc.dg/vect/pr91293-3.c: Likewise.

From-SVN: r274007

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr91280.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr91293-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr91293-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr91293-3.c [new file with mode: 0644]
gcc/tree-ssa-structalias.c
gcc/tree-vect-slp.c

index 57c1025f6e34cb6fe74f97874e3a74a5b97bdac0..57f7bcabbb3d32b0256d8b1891c43ebe39a411b2 100644 (file)
@@ -1,3 +1,18 @@
+2019-08-02  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       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
+       * tree-vect-slp.c (vect_build_slp_tree_2): Do not swap operands
+       of reduction stmts.
+
 2019-08-02  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index 337b50e194c0ede7bcb4ef4c0c9849467c2d6f1a..41208128e600e81b4869bd8e7203eef1e175d8a0 100644 (file)
@@ -1,3 +1,18 @@
+2019-08-02  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       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
+       * gcc.dg/vect/pr91293-1.c: New testcase.
+       * gcc.dg/vect/pr91293-2.c: Likewise.
+       * gcc.dg/vect/pr91293-3.c: Likewise.
+
 2019-08-02  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/g++.dg/torture/pr91280.C b/gcc/testsuite/g++.dg/torture/pr91280.C
new file mode 100644 (file)
index 0000000..063bef8
--- /dev/null
@@ -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; });
diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-1.c b/gcc/testsuite/gcc.dg/vect/pr91293-1.c
new file mode 100644 (file)
index 0000000..dc321f5
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */
+
+long long a;
+unsigned b, c;
+int d = 62;
+void e(long long *f, int p2) { *f = p2; }
+int main()
+{
+  for (int g = 2; g <= d; g++)
+    {
+      b += g + 4;
+      c += 5 - g;
+    }
+  e(&a, b);
+  if (a != 2196)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-2.c b/gcc/testsuite/gcc.dg/vect/pr91293-2.c
new file mode 100644 (file)
index 0000000..b9354bb
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */
+
+long long a;
+unsigned b, c;
+int d = 62;
+void e(long long *f, int p2) { *f = p2; }
+int main()
+{
+  for (int g = 2; g <= d; g++)
+    {
+      c += 5 - g;
+      b += g + 4;
+    }
+  e(&a, b);
+  if (a != 2196)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-3.c b/gcc/testsuite/gcc.dg/vect/pr91293-3.c
new file mode 100644 (file)
index 0000000..c35bc34
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */
+
+long long a;
+unsigned b, c;
+int d = 62;
+void e(long long *f, int p2) { *f = p2; }
+int xx = 5, yy = 4;
+int main()
+{
+  for (int g = 2; g <= d; g++)
+    {
+      c += xx - g;
+      b += yy + g;
+    }
+  e(&a, b);
+  if (a != 2196)
+    __builtin_abort ();
+  return 0;
+}
index 4a0b02e9b03ce464f8ab78cdc2e96d610282e8a0..f80b8e456b5ca6ad4fcd504d3bf87aa613c92a62 100644 (file)
@@ -3250,9 +3250,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)
     {
index c3137460fd14569416f36b637c3216792b614b71..017bfa873f7398476a3df3b8bade20e2dc0711c7 100644 (file)
@@ -1285,6 +1285,9 @@ vect_build_slp_tree_2 (vec_info *vinfo,
          && nops == 2
          && oprnds_info[1]->first_dt == vect_internal_def
          && is_gimple_assign (stmt_info->stmt)
+         /* Swapping operands for reductions breaks assumptions later on.  */
+         && STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def
+         && STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def
          /* Do so only if the number of not successful permutes was nor more
             than a cut-ff as re-trying the recursive match on
             possibly each level of the tree would expose exponential