mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-23 07:00:27 +08:00
re PR tree-optimization/60276 (-O3 autovectorizer breaks on a particular loop)
2014-02-21 Richard Biener <rguenther@suse.de> PR tree-optimization/60276 * tree-vectorizer.h (struct _stmt_vec_info): Add min_neg_dist field. (STMT_VINFO_MIN_NEG_DIST): New macro. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Record STMT_VINFO_MIN_NEG_DIST. * tree-vect-stmts.c (vectorizable_load): Verify if assumptions made for negative dependence distances still hold. * gcc.dg/vect/pr60276.c: New testcase. From-SVN: r207992
This commit is contained in:
parent
32417082bf
commit
f2556b68ca
@ -1,3 +1,13 @@
|
||||
2014-02-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/60276
|
||||
* tree-vectorizer.h (struct _stmt_vec_info): Add min_neg_dist field.
|
||||
(STMT_VINFO_MIN_NEG_DIST): New macro.
|
||||
* tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Record
|
||||
STMT_VINFO_MIN_NEG_DIST.
|
||||
* tree-vect-stmts.c (vectorizable_load): Verify if assumptions
|
||||
made for negative dependence distances still hold.
|
||||
|
||||
2014-02-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/60291
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-02-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/60276
|
||||
* gcc.dg/vect/pr60276.c: New testcase.
|
||||
|
||||
2014-02-21 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/60234
|
||||
|
52
gcc/testsuite/gcc.dg/vect/pr60276.c
Normal file
52
gcc/testsuite/gcc.dg/vect/pr60276.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
static void
|
||||
foo (int *out, const int *lp, unsigned samples)
|
||||
{
|
||||
int x, target;
|
||||
for (x = 0, target = 0; x < (int)samples; x += 2, target++)
|
||||
{
|
||||
out[x] = lp[target];
|
||||
out[x - 1] = out[x - 2] + out[x];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
foo_novec (int *out, const int *lp, unsigned samples)
|
||||
{
|
||||
int x, target;
|
||||
for (x = 0, target = 0; x < (int)samples; x += 2, target++)
|
||||
{
|
||||
out[x] = lp[target];
|
||||
out[x - 1] = out[x - 2] + out[x];
|
||||
__asm__ volatile ("" : : : "memory");
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const int lp[25] = {
|
||||
0, 2, 4, 6, 8,
|
||||
10, 12, 14, 16,
|
||||
18, 20, 22, 24,
|
||||
26, 28, 30, 32,
|
||||
34, 36, 38, 40,
|
||||
42, 44, 46, 48,
|
||||
};
|
||||
int out[49] = {0};
|
||||
int out2[49] = {0};
|
||||
int s;
|
||||
|
||||
foo (out + 2, lp + 1, 48);
|
||||
foo_novec (out2 + 2, lp + 1, 48);
|
||||
|
||||
for (s = 0; s < 49; s++)
|
||||
if (out[s] != out2[s])
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { cleanup-tree-dump "vect" } } */
|
@ -403,6 +403,13 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
|
||||
if (dump_enabled_p ())
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"dependence distance negative.\n");
|
||||
/* Record a negative dependence distance to later limit the
|
||||
amount of stmt copying / unrolling we can perform.
|
||||
Only need to handle read-after-write dependence. */
|
||||
if (DR_IS_READ (drb)
|
||||
&& (STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) == 0
|
||||
|| STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) > (unsigned)dist))
|
||||
STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) = dist;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -5629,6 +5629,20 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Invalidate assumptions made by dependence analysis when vectorization
|
||||
on the unrolled body effectively re-orders stmts. */
|
||||
if (ncopies > 1
|
||||
&& STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0
|
||||
&& ((unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo)
|
||||
> STMT_VINFO_MIN_NEG_DIST (stmt_info)))
|
||||
{
|
||||
if (dump_enabled_p ())
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"cannot perform implicit CSE when unrolling "
|
||||
"with negative dependence distance\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
|
||||
return false;
|
||||
|
||||
@ -5686,6 +5700,20 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
|
||||
else if (!vect_grouped_load_supported (vectype, group_size))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Invalidate assumptions made by dependence analysis when vectorization
|
||||
on the unrolled body effectively re-orders stmts. */
|
||||
if (!PURE_SLP_STMT (stmt_info)
|
||||
&& STMT_VINFO_MIN_NEG_DIST (stmt_info) != 0
|
||||
&& ((unsigned)LOOP_VINFO_VECT_FACTOR (loop_vinfo)
|
||||
> STMT_VINFO_MIN_NEG_DIST (stmt_info)))
|
||||
{
|
||||
if (dump_enabled_p ())
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"cannot perform implicit CSE when performing "
|
||||
"group loads with negative dependence distance\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -622,6 +622,10 @@ typedef struct _stmt_vec_info {
|
||||
is 1. */
|
||||
unsigned int gap;
|
||||
|
||||
/* The minimum negative dependence distance this stmt participates in
|
||||
or zero if none. */
|
||||
unsigned int min_neg_dist;
|
||||
|
||||
/* Not all stmts in the loop need to be vectorized. e.g, the increment
|
||||
of the loop induction variable and computation of array indexes. relevant
|
||||
indicates whether the stmt needs to be vectorized. */
|
||||
@ -677,6 +681,7 @@ typedef struct _stmt_vec_info {
|
||||
#define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
|
||||
#define STMT_VINFO_GROUPED_ACCESS(S) ((S)->first_element != NULL && (S)->data_ref_info)
|
||||
#define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
|
||||
#define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist
|
||||
|
||||
#define GROUP_FIRST_ELEMENT(S) (S)->first_element
|
||||
#define GROUP_NEXT_ELEMENT(S) (S)->next_element
|
||||
|
Loading…
x
Reference in New Issue
Block a user