Commit 2fd579ab by Richard Biener Committed by Richard Biener

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
parent 375a6bc6
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.
2019-04-11 Robin Dapp <rdapp@linux.ibm.com> 2019-04-11 Robin Dapp <rdapp@linux.ibm.com>
* config/s390/8561.md: New file. * config/s390/8561.md: New file.
......
2019-04-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/90018
* gcc.dg/vect/pr90018.c: New testcase.
2018-04-10 Steve Ellcey <sellcey@marvell.com> 2018-04-10 Steve Ellcey <sellcey@marvell.com>
PR rtl-optimization/87763 PR rtl-optimization/87763
......
/* { dg-do run } */
/* { dg-require-effective-target vect_double } */
#include "tree-vect.h"
void __attribute__((noinline,noclone))
foo (double *a4, int n)
{
for (int i = 0; i < n; ++i)
{
/* We may not apply interleaving to the group (a), (b) because of (c).
Instead group (d) and (b). */
double tem1 = a4[i*4] + a4[i*4+n*4] /* (a) */;
double tem2 = a4[i*4+2*n*4+1];
a4[i*4+n*4+1] = tem1; /* (c) */
a4[i*4+1] = tem2;
double tem3 = a4[i*4] - tem2;
double tem4 = tem3 + a4[i*4+n*4] /* (d) */;
a4[i*4+n*4+1] = tem4 + a4[i*4+n*4+1] /* (b) */;
}
}
int main(int argc, char **argv)
{
int n = 11;
double a4[4 * n * 3];
double a42[4 * n * 3];
check_vect ();
for (int i = 0; i < 4 * n * 3; ++i)
{
a4[i] = a42[i] = i;
__asm__ volatile ("": : : "memory");
}
foo (a4, n);
for (int i = 0; i < n; ++i)
{
double tem1 = a42[i*4] + a42[i*4+n*4];
double tem2 = a42[i*4+2*n*4+1];
a42[i*4+n*4+1] = tem1;
a42[i*4+1] = tem2;
double tem3 = a42[i*4] - tem2;
double tem4 = tem3 + a42[i*4+n*4];
a42[i*4+n*4+1] = tem4 + a42[i*4+n*4+1];
__asm__ volatile ("": : : "memory");
}
for (int i = 0; i < 4 * n * 3; ++i)
if (a4[i] != a42[i])
__builtin_abort ();
return 0;
}
/* For v2df we try to use SLP and fail miserably. */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_sizes_32B_16B } } } */
...@@ -234,26 +234,60 @@ vect_preserves_scalar_order_p (dr_vec_info *dr_info_a, dr_vec_info *dr_info_b) ...@@ -234,26 +234,60 @@ vect_preserves_scalar_order_p (dr_vec_info *dr_info_a, dr_vec_info *dr_info_b)
return true; return true;
/* STMT_A and STMT_B belong to overlapping groups. All loads in a /* 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 SLP group are emitted at the position of the last scalar load and
stores in a group are emitted at the position of the last scalar store. 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 Compute that position and check whether the resulting order matches
the current one. */ the current one.
stmt_vec_info last_a = DR_GROUP_FIRST_ELEMENT (stmtinfo_a); 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) if (last_a)
for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_a); s; {
s = DR_GROUP_NEXT_ELEMENT (s)) for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_a); s;
last_a = get_later_stmt (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 else
last_a = stmtinfo_a; last_a = il_a = stmtinfo_a;
stmt_vec_info last_b = DR_GROUP_FIRST_ELEMENT (stmtinfo_b); stmt_vec_info il_b;
stmt_vec_info last_b = il_b = DR_GROUP_FIRST_ELEMENT (stmtinfo_b);
if (last_b) if (last_b)
for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_b); s; {
s = DR_GROUP_NEXT_ELEMENT (s)) for (stmt_vec_info s = DR_GROUP_NEXT_ELEMENT (last_b); s;
last_b = get_later_stmt (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 else
last_b = stmtinfo_b; last_b = il_b = stmtinfo_b;
return ((get_later_stmt (last_a, last_b) == last_a) bool a_after_b = (get_later_stmt (stmtinfo_a, stmtinfo_b) == stmtinfo_a);
== (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 /* A subroutine of vect_analyze_data_ref_dependence. Handle
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment