mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
tree-optimization/116674 - vectorizable_simd_clone_call and re-analysis
When SLP analysis scraps an instance because it fails to analyze we can end up calling vectorizable_* in analysis mode on a node that was analyzed during the analysis of that instance again. vectorizable_simd_clone_call wasn't expecting that and instead guarded analysis/transform code on populated data structures. The following changes it so it survives re-analysis. PR tree-optimization/116674 * tree-vect-stmts.cc (vectorizable_simd_clone_call): Support re-analysis. * g++.dg/vect/pr116674.cc: New testcase.
This commit is contained in:
parent
3fd07d4f04
commit
09a514fbb6
85
gcc/testsuite/g++.dg/vect/pr116674.cc
Normal file
85
gcc/testsuite/g++.dg/vect/pr116674.cc
Normal file
@ -0,0 +1,85 @@
|
||||
// { dg-do compile }
|
||||
// { dg-require-effective-target c++11 }
|
||||
// { dg-additional-options "-Ofast" }
|
||||
// { dg-additional-options "-march=x86-64-v3" { target { x86_64-*-* i?86-*-* } } }
|
||||
|
||||
namespace std {
|
||||
typedef int a;
|
||||
template <typename> struct b;
|
||||
template <typename> class aa {};
|
||||
template <typename c> c d(c e, c) { return e; }
|
||||
template <typename c> struct b<aa<c>> {
|
||||
using f = c;
|
||||
using g = c *;
|
||||
template <typename h> using j = aa<h>;
|
||||
};
|
||||
} // namespace std
|
||||
namespace l {
|
||||
template <typename ab> struct m : std::b<ab> {
|
||||
typedef std::b<ab> n;
|
||||
typedef typename n::f &q;
|
||||
template <typename c> struct ac { typedef typename n::j<c> ad; };
|
||||
};
|
||||
} // namespace l
|
||||
namespace std {
|
||||
template <typename c, typename ab> struct o {
|
||||
typedef typename l::m<ab>::ac<c>::ad ae;
|
||||
typedef typename l::m<ae>::g g;
|
||||
struct p {
|
||||
g af;
|
||||
};
|
||||
struct ag : p {
|
||||
ag(ae) {}
|
||||
};
|
||||
typedef ab u;
|
||||
o(a, u e) : ah(e) {}
|
||||
ag ah;
|
||||
};
|
||||
template <typename c, typename ab = aa<c>> class r : o<c, ab> {
|
||||
typedef o<c, ab> s;
|
||||
typedef typename s::ae ae;
|
||||
typedef l::m<ae> w;
|
||||
|
||||
public:
|
||||
c f;
|
||||
typedef typename w::q q;
|
||||
typedef a t;
|
||||
typedef ab u;
|
||||
r(t x, u e = u()) : s(ai(x, e), e) {}
|
||||
q operator[](t x) { return *(this->ah.af + x); }
|
||||
t ai(t x, u) { return x; }
|
||||
};
|
||||
extern "C" __attribute__((__simd__)) double exp(double);
|
||||
} // namespace std
|
||||
using namespace std;
|
||||
int ak;
|
||||
double v, y;
|
||||
void am(double, int an, double, double, double, double, double, double, double,
|
||||
double, double, double, int, double, double, double, double,
|
||||
r<double> ap, double, double, double, double, double, double, double,
|
||||
double, r<double> ar, r<double> as, double, double, r<double> at,
|
||||
r<double> au, r<double> av, double, double) {
|
||||
double ba;
|
||||
for (int k;;)
|
||||
for (int i; i < an; ++i) {
|
||||
y = i;
|
||||
v = d(y, 25.0);
|
||||
ba = exp(v);
|
||||
ar[i * (ak + 1)] = ba;
|
||||
as[i * (ak + 1)] = ar[i * (ak + 1)];
|
||||
if (k && ap[k]) {
|
||||
at[i * (ak + 1)] = av[i * (ak + 1)] = as[i * (ak + 1)];
|
||||
au[i * (ak + 1)] = ar[i * (ak + 1)];
|
||||
} else {
|
||||
au[i * (ak + 1)] = ba;
|
||||
at[i * (ak + 1)] = av[i * (ak + 1)] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
void b(int bc) {
|
||||
double bd, be, bf, bg, bh, ao, ap, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx,
|
||||
by, aq, ar, as, bz, ca, at, au, av, cb, aw;
|
||||
int bi;
|
||||
am(bh, bc, bi, bi, bi, bi, bv, bw, bx, by, bu, bt, bi, ao, bn, bo, bp, ap, bq,
|
||||
br, bs, bd, be, bf, bg, aq, ar, as, bz, ca, at, au, av, cb, aw);
|
||||
}
|
@ -3985,6 +3985,8 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
|
||||
|
||||
vec<tree>& simd_clone_info = (slp_node ? SLP_TREE_SIMD_CLONE_INFO (slp_node)
|
||||
: STMT_VINFO_SIMD_CLONE_INFO (stmt_info));
|
||||
if (!vec_stmt)
|
||||
simd_clone_info.truncate (0);
|
||||
arginfo.reserve (nargs, true);
|
||||
auto_vec<slp_tree> slp_op;
|
||||
slp_op.safe_grow_cleared (nargs);
|
||||
@ -4033,10 +4035,10 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
|
||||
|
||||
/* For linear arguments, the analyze phase should have saved
|
||||
the base and step in {STMT_VINFO,SLP_TREE}_SIMD_CLONE_INFO. */
|
||||
if (i * 3 + 4 <= simd_clone_info.length ()
|
||||
if (vec_stmt
|
||||
&& i * 3 + 4 <= simd_clone_info.length ()
|
||||
&& simd_clone_info[i * 3 + 2])
|
||||
{
|
||||
gcc_assert (vec_stmt);
|
||||
thisarginfo.linear_step = tree_to_shwi (simd_clone_info[i * 3 + 2]);
|
||||
thisarginfo.op = simd_clone_info[i * 3 + 1];
|
||||
thisarginfo.simd_lane_linear
|
||||
@ -4091,7 +4093,7 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
|
||||
unsigned group_size = slp_node ? SLP_TREE_LANES (slp_node) : 1;
|
||||
unsigned int badness = 0;
|
||||
struct cgraph_node *bestn = NULL;
|
||||
if (simd_clone_info.exists ())
|
||||
if (vec_stmt)
|
||||
bestn = cgraph_node::get (simd_clone_info[0]);
|
||||
else
|
||||
for (struct cgraph_node *n = node->simd_clones; n != NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user