On Sat, Nov 16, 2024 at 5:24 AM Andrew Pinski <quic_apin...@quicinc.com> wrote:
>
> 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.

OK.

Richard.

> Bootstrapped and tested on x86_64-linux-gnu.
>
>         PR tree-optimization/105769
>
> gcc/ChangeLog:
>
>         * cfgexpand.cc (vars_ssa_cache::operator()): For constructors
>         walk over the elements.
>
> gcc/testsuite/ChangeLog:
>
>         * g++.dg/torture/pr105769-1.C: New test.
>
> Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
> ---
>  gcc/cfgexpand.cc                          | 20 +++++--
>  gcc/testsuite/g++.dg/torture/pr105769-1.C | 67 +++++++++++++++++++++++
>  2 files changed, 83 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/torture/pr105769-1.C
>
> diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
> index 841d3c1254e..50262b38c2d 100644
> --- a/gcc/cfgexpand.cc
> +++ b/gcc/cfgexpand.cc
> @@ -729,7 +729,7 @@ vars_ssa_cache::operator() (tree name)
>    gcc_assert (TREE_CODE (name) == SSA_NAME);
>
>    if (!POINTER_TYPE_P (TREE_TYPE (name))
> -      && !INTEGRAL_TYPE_P (TREE_TYPE (name)))
> +      && !ANY_INTEGRAL_TYPE_P (TREE_TYPE (name)))
>      return empty;
>
>    if (exists (name))
> @@ -759,7 +759,7 @@ vars_ssa_cache::operator() (tree name)
>         continue;
>
>        if (!POINTER_TYPE_P (TREE_TYPE (use))
> -         && !INTEGRAL_TYPE_P (TREE_TYPE (use)))
> +         && !ANY_INTEGRAL_TYPE_P (TREE_TYPE (use)))
>         continue;
>
>        /* Mark the old ssa name needs to be update from the use. */
> @@ -773,10 +773,22 @@ vars_ssa_cache::operator() (tree name)
>          so we don't go into an infinite loop for some phi nodes with loops.  
> */
>        create (use);
>
> +      gimple *g = SSA_NAME_DEF_STMT (use);
> +
> +      /* 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 assignments, walk each operand for possible addresses.
>          For PHI nodes, walk each argument. */
> -      gimple *g = SSA_NAME_DEF_STMT (use);
> -      if (gassign *a = dyn_cast <gassign *> (g))
> +      else if (gassign *a = dyn_cast <gassign *> (g))
>         {
>           /* operand 0 is the lhs. */
>           for (unsigned i = 1; i < gimple_num_ops (g); i++)
> 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;
> +}
> +
> --
> 2.43.0
>

Reply via email to