Skip to content

Commit 27ddda8

Browse files
rguenthRichard Biener
authored and
Richard Biener
committed
tree-optimization/116902 - vectorizer load hosting breaks UID order #2
This is another case of load hoisting breaking UID order in the preheader, this time between two hoistings. The easiest way out is to do what we do for the main stmt - copy instead of move. PR tree-optimization/116902 PR tree-optimization/116842 * tree-vect-stmts.cc (sort_after_uid): Remove again. (hoist_defs_of_uses): Copy defs instead of hoisting them so we can zero their UID. (vectorizable_load): Separate analysis and transform call, do transform on the stmt copy. * g++.dg/torture/pr116902.C: New testcase.
1 parent 60fa7f5 commit 27ddda8

File tree

2 files changed

+45
-29
lines changed

2 files changed

+45
-29
lines changed
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// { dg-do compile }
2+
// { dg-additional-options "-ftree-vectorize" }
3+
4+
template<typename _Tp>
5+
inline const _Tp&
6+
min(const _Tp& __a, const _Tp& __b)
7+
{
8+
if (__b < __a)
9+
return __b;
10+
return __a;
11+
}
12+
13+
unsigned a;
14+
void i(long b, char c[][4], long d[][4]) {
15+
for (char e; e; e++)
16+
for (char f = 0; f < 021; f = b)
17+
for (signed char g; g < 7; g += ~0)
18+
for (bool h = 0; h < bool(d[f][f]); h = 1)
19+
a = c[2][1] - min(c[1][f + 1], c[2][f + 2]);
20+
}

gcc/tree-vect-stmts.cc

+25-29
Original file line numberDiff line numberDiff line change
@@ -9788,36 +9788,22 @@ permute_vec_elements (vec_info *vinfo,
97889788
return data_ref;
97899789
}
97909790

9791-
/* Comparator for qsort, sorting after GIMPLE UID. */
9792-
9793-
static int
9794-
sort_after_uid (const void *a_, const void *b_)
9795-
{
9796-
const gimple *a = *(const gimple * const *)a_;
9797-
const gimple *b = *(const gimple * const *)b_;
9798-
if (gimple_uid (a) < gimple_uid (b))
9799-
return -1;
9800-
else if (gimple_uid (a) > gimple_uid (b))
9801-
return 1;
9802-
return 0;
9803-
}
9804-
98059791
/* Hoist the definitions of all SSA uses on STMT_INFO out of the loop LOOP,
98069792
inserting them on the loops preheader edge. Returns true if we
98079793
were successful in doing so (and thus STMT_INFO can be moved then),
98089794
otherwise returns false. HOIST_P indicates if we want to hoist the
98099795
definitions of all SSA uses, it would be false when we are costing. */
98109796

98119797
static bool
9812-
hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p)
9798+
hoist_defs_of_uses (gimple *stmt, class loop *loop, bool hoist_p)
98139799
{
98149800
ssa_op_iter i;
9815-
tree op;
9816-
auto_vec<gimple *, 8> to_hoist;
9801+
use_operand_p use_p;
9802+
auto_vec<use_operand_p, 8> to_hoist;
98179803

9818-
FOR_EACH_SSA_TREE_OPERAND (op, stmt_info->stmt, i, SSA_OP_USE)
9804+
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_USE)
98199805
{
9820-
gimple *def_stmt = SSA_NAME_DEF_STMT (op);
9806+
gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
98219807
if (!gimple_nop_p (def_stmt)
98229808
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
98239809
{
@@ -9827,7 +9813,9 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p)
98279813
dependencies within them. */
98289814
tree op2;
98299815
ssa_op_iter i2;
9830-
if (gimple_code (def_stmt) == GIMPLE_PHI)
9816+
if (gimple_code (def_stmt) == GIMPLE_PHI
9817+
|| (single_ssa_def_operand (def_stmt, SSA_OP_DEF)
9818+
== NULL_DEF_OPERAND_P))
98319819
return false;
98329820
FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt, i2, SSA_OP_USE)
98339821
{
@@ -9836,7 +9824,7 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p)
98369824
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt2)))
98379825
return false;
98389826
}
9839-
to_hoist.safe_push (def_stmt);
9827+
to_hoist.safe_push (use_p);
98409828
}
98419829
}
98429830

@@ -9846,14 +9834,21 @@ hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop, bool hoist_p)
98469834
if (!hoist_p)
98479835
return true;
98489836

9849-
/* Preserve UID order, otherwise we break dominance checks. */
9850-
to_hoist.qsort (sort_after_uid);
9851-
9852-
for (gimple *def_stmt : to_hoist)
9837+
/* Instead of moving defs we copy them so we can zero their UID to not
9838+
confuse dominance queries in the preheader. */
9839+
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
9840+
for (use_operand_p use_p : to_hoist)
98539841
{
9854-
gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
9855-
gsi_remove (&gsi, false);
9856-
gsi_insert_on_edge_immediate (loop_preheader_edge (loop), def_stmt);
9842+
gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
9843+
gimple *copy = gimple_copy (def_stmt);
9844+
gimple_set_uid (copy, 0);
9845+
def_operand_p def_p = single_ssa_def_operand (def_stmt, SSA_OP_DEF);
9846+
tree new_def = duplicate_ssa_name (DEF_FROM_PTR (def_p), copy);
9847+
update_stmt (copy);
9848+
def_p = single_ssa_def_operand (copy, SSA_OP_DEF);
9849+
SET_DEF (def_p, new_def);
9850+
SET_USE (use_p, new_def);
9851+
gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
98579852
}
98589853

98599854
return true;
@@ -10227,7 +10222,7 @@ vectorizable_load (vec_info *vinfo,
1022710222
transform time. */
1022810223
bool hoist_p = (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo)
1022910224
&& !nested_in_vect_loop
10230-
&& hoist_defs_of_uses (stmt_info, loop, !costing_p));
10225+
&& hoist_defs_of_uses (stmt_info->stmt, loop, false));
1023110226
if (costing_p)
1023210227
{
1023310228
enum vect_cost_model_location cost_loc
@@ -10264,6 +10259,7 @@ vectorizable_load (vec_info *vinfo,
1026410259
gimple *new_stmt = gimple_build_assign (scalar_dest, rhs);
1026510260
gimple_set_vuse (new_stmt, vuse);
1026610261
gsi_insert_on_edge_immediate (pe, new_stmt);
10262+
hoist_defs_of_uses (new_stmt, loop, true);
1026710263
}
1026810264
/* These copies are all equivalent. */
1026910265
if (hoist_p)

0 commit comments

Comments
 (0)