diff mbox series

[2/2] cfgexpand: Handle integral vector types and constructors for scope conflicts [PR105769]

Message ID 20241017024205.2660484-2-quic_apinski@quicinc.com
State New
Headers show
Series [PATCHv2,1/2] cfgexpand: Handle scope conflicts better [PR111422] | expand

Commit Message

Andrew Pinski Oct. 17, 2024, 2:42 a.m. UTC
This is an expansion of the last patch to also track pointers via vector types and the
constructor that are used with vector types.
In this case we had:
```
_15 = (long unsigned int) &bias;
_10 = (long unsigned int) &cov_jn;
_12 = {_10, _15};
...

MEM[(struct vec *)&cov_jn] ={v} {CLOBBER(bob)};
bias ={v} {CLOBBER(bob)};
MEM[(struct function *)&D.6156] ={v} {CLOBBER(bob)};

...
MEM <vector(2) long unsigned int> [(void *)&D.6172 + 32B] = _12;
MEM[(struct function *)&D.6157] ={v} {CLOBBER(bob)};
```

Anyways tracking the pointers via vector types to say they are alive
at the point where the store of the vector happens fixes the bug by saying
it is alive at the same time as another variable is alive.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/105769

	PR tree-optimization/105769

gcc/ChangeLog:

	* cfgexpand.cc (addr_ssa_walker::operator()): For constructors
	walk over the elements.

gcc/testsuite/ChangeLog:

	* g++.dg/torture/pr105769-1.C: New test.
---
 gcc/cfgexpand.cc                          | 15 ++++-
 gcc/testsuite/g++.dg/torture/pr105769-1.C | 67 +++++++++++++++++++++++
 2 files changed, 80 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr105769-1.C
diff mbox series

Patch

diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index 74f4cfc0f22..970ee0b85f7 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -691,7 +691,7 @@  addr_ssa_walker::operator() (tree name, T func)
 
       /* Only Pointers and integral types are used to track addresses.  */
       if (!POINTER_TYPE_P (TREE_TYPE (use))
-	  && !INTEGRAL_TYPE_P (TREE_TYPE (use)))
+	  && !ANY_INTEGRAL_TYPE_P (TREE_TYPE (use)))
 	continue;
 
       /* Check the cache, if there is a hit use it.  */
@@ -718,10 +718,21 @@  addr_ssa_walker::operator() (tree name, T func)
 	 if there was too many names associated with the cache. */
       work_list.safe_push (work);
 
+      /* CONSTRUCTOR here is always a vector initialization,
+	 walk each element too. */
+      if (gimple_assign_single_p (g)
+	  && TREE_CODE (gimple_assign_rhs1 (g)) == CONSTRUCTOR)
+	{
+	  tree ctr = gimple_assign_rhs1 (g);
+	  unsigned i;
+	  tree elm;
+	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctr), i, elm)
+	    work_list.safe_push (std::make_pair (elm, use));
+	}
       /* For assign statements, add each operand to the work list.
 	 Note operand 0 is the same as the use here so there is nothing
 	 to be done.  */
-      if (gassign *a = dyn_cast <gassign *> (g))
+      else if (gassign *a = dyn_cast <gassign *> (g))
 	{
 	  for (unsigned i = 1; i < gimple_num_ops (g); i++)
 	    work_list.safe_push (std::make_pair (gimple_op (a, i), use));
diff --git a/gcc/testsuite/g++.dg/torture/pr105769-1.C b/gcc/testsuite/g++.dg/torture/pr105769-1.C
new file mode 100644
index 00000000000..3fe973656b8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr105769-1.C
@@ -0,0 +1,67 @@ 
+// { dg-do run }
+
+// PR tree-optimization/105769
+
+// The partitioning code would incorrectly have bias
+// and a temporary in the same partitioning because
+// it was thought bias was not alive when those were alive
+// do to vectorization of a store of pointers (that included bias).
+
+#include <functional>
+
+template<size_t n, class T>
+struct vec {
+  T dat[n];
+  vec() {}
+  explicit vec(const T& x) { for(size_t i = 0; i < n; i++) dat[i] = x; }
+  T& operator [](size_t i) { return dat[i]; }
+  const T& operator [](size_t i) const { return dat[i]; }
+};
+
+template<size_t m, size_t n, class T>
+using mat = vec<m, vec<n, T>>;
+template<size_t n, class T>
+using sq_mat = mat<n, n, T>;
+using map_t = std::function<size_t(size_t)>;
+template<class T_v>
+using est_t = std::function<T_v(map_t map)>;
+template<class T_v> using est2_t = std::function<T_v(map_t map)>;
+map_t id_map() { return [](size_t j) -> size_t { return j; }; }
+
+template<size_t n, class T>
+est2_t<void> jacknife(const est_t<vec<n, T>> est, sq_mat<n, T>& cov, vec<n, T>& bias) {
+  return [est, &cov, &bias](map_t map) -> void
+  {
+        bias = est(map);
+        for(size_t i = 0; i < n; i++)
+        {
+          bias[i].print();
+        }
+  };
+}
+
+template<class T>
+void print_cov_ratio() {
+  sq_mat<2, T> cov_jn;
+  vec<2, T> bias;
+  jacknife<2, T>([](map_t map) -> vec<2, T> { vec<2, T> retv; retv[0] = 1; retv[1] = 1; return retv; }, cov_jn, bias)(id_map());
+}
+struct ab {
+  long long unsigned a;
+  short unsigned b;
+  double operator()() { return a; }
+  ab& operator=(double rhs) { a = rhs; return *this; }
+ void print();
+};
+
+void
+ab::print()
+{
+
+}
+
+int main() {
+  print_cov_ratio<ab>();
+  return 0;
+}
+