diff options
author | Richard Biener <rguenther@suse.de> | 2019-04-11 07:30:59 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-04-11 07:30:59 +0000 |
commit | 2fd579ab530ca9ca5682eeba305c4946bf710c25 (patch) | |
tree | c0a759263425c5222f9e84e09139d9cc3d576ddd /gcc/tree-vect-data-refs.c | |
parent | 375a6bc674794fc8cb53ff703a636e84dd6df9be (diff) |
re PR tree-optimization/90018 (r265453 miscompiled 527.cam4_r in SPEC CPU 2017)
2019-04-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/90018
* tree-vect-data-refs.c (vect_preserves_scalar_order_p):
Test both SLP and interleaving variants.
* gcc.dg/vect/pr90018.c: New testcase.
From-SVN: r270273
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 85997cf9617..d71a39ffd78 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -234,26 +234,60 @@ vect_preserves_scalar_order_p (dr_vec_info *dr_info_a, dr_vec_info *dr_info_b) return true; /* STMT_A and STMT_B belong to overlapping groups. All loads in a - group are emitted at the position of the last scalar load and all - stores in a group are emitted at the position of the last scalar store. + SLP group are emitted at the position of the last scalar load and + all loads in an interleaving group are emitted at the position + of the first scalar load. + Stores in a group are emitted at the position of the last scalar store. Compute that position and check whether the resulting order matches - the current one. */ - stmt_vec_info last_a = DR_GROUP_FIRST_ELEMENT (stmtinfo_a); + the current one. + We have not yet decided between SLP and interleaving so we have + to conservatively assume both. */ + stmt_vec_info il_a; + stmt_vec_info last_a = il_a = DR_GROUP_FIRST_ELEMENT (stmtinfo_a); if (last_a) - for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_a); s; - s = DR_GROUP_NEXT_ELEMENT (s)) - last_a = get_later_stmt (last_a, s); + { + for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_a); s; + s = DR_GROUP_NEXT_ELEMENT (s)) + last_a = get_later_stmt (last_a, s); + if (!DR_IS_WRITE (STMT_VINFO_DATA_REF (stmtinfo_a))) + { + for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (il_a); s; + s = DR_GROUP_NEXT_ELEMENT (s)) + if (get_later_stmt (il_a, s) == il_a) + il_a = s; + } + else + il_a = last_a; + } else - last_a = stmtinfo_a; - stmt_vec_info last_b = DR_GROUP_FIRST_ELEMENT (stmtinfo_b); + last_a = il_a = stmtinfo_a; + stmt_vec_info il_b; + stmt_vec_info last_b = il_b = DR_GROUP_FIRST_ELEMENT (stmtinfo_b); if (last_b) - for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_b); s; - s = DR_GROUP_NEXT_ELEMENT (s)) - last_b = get_later_stmt (last_b, s); + { + for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_b); s; + s = DR_GROUP_NEXT_ELEMENT (s)) + last_b = get_later_stmt (last_b, s); + if (!DR_IS_WRITE (STMT_VINFO_DATA_REF (stmtinfo_b))) + { + for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (il_b); s; + s = DR_GROUP_NEXT_ELEMENT (s)) + if (get_later_stmt (il_b, s) == il_b) + il_b = s; + } + else + il_b = last_b; + } else - last_b = stmtinfo_b; - return ((get_later_stmt (last_a, last_b) == last_a) - == (get_later_stmt (stmtinfo_a, stmtinfo_b) == stmtinfo_a)); + last_b = il_b = stmtinfo_b; + bool a_after_b = (get_later_stmt (stmtinfo_a, stmtinfo_b) == stmtinfo_a); + return (/* SLP */ + (get_later_stmt (last_a, last_b) == last_a) == a_after_b + /* Interleaving */ + && (get_later_stmt (il_a, il_b) == il_a) == a_after_b + /* Mixed */ + && (get_later_stmt (il_a, last_b) == il_a) == a_after_b + && (get_later_stmt (last_a, il_b) == last_a) == a_after_b); } /* A subroutine of vect_analyze_data_ref_dependence. Handle |