Commit 649d196d by Richard Biener Committed by Richard Biener

re PR tree-optimization/59374 (-ftree-slp-vectorize breaks unique_ptr's move constructor)

2013-12-05  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/59374
	* tree-vect-data-refs.c (vect_slp_analyze_data_ref_dependence):
	Commonize known and unknown dependence case fixing the allowed
	read-write dependence case and dropping code that should not
	matter.

	* gcc.dg/torture/pr59374-1.c: New testcase.
	* gcc.dg/torture/pr59374-2.c: Likewise.

From-SVN: r205694
parent 9eb8c09f
2013-12-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/59374
* tree-vect-data-refs.c (vect_slp_analyze_data_ref_dependence):
Commonize known and unknown dependence case fixing the allowed
read-write dependence case and dropping code that should not
matter.
2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com> 2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com>
* config/ia64/ia64.md (prologue_allocate_stack): Block auto- * config/ia64/ia64.md (prologue_allocate_stack): Block auto-
2013-12-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/59374
* gcc.dg/torture/pr59374-1.c: New testcase.
* gcc.dg/torture/pr59374-2.c: Likewise.
2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com> 2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com>
* gcc.target/ia64/pr52731.c: New. * gcc.target/ia64/pr52731.c: New.
......
/* { dg-do run } */
/* { dg-additional-options "-ftree-slp-vectorize" } */
extern void abort (void);
static struct X { void *a; void *b; } a, b;
void __attribute__((noinline))
foo (void)
{
void *tem = a.b;
a.b = (void *)0;
b.b = tem;
b.a = a.a;
}
int main()
{
a.b = &a;
foo ();
if (b.b != &a)
abort ();
return 0;
}
/* { dg-do run } */
/* { dg-additional-options "-ftree-slp-vectorize" } */
extern void abort (void);
static struct X { void *a; void *b; } a, b;
static struct X *p;
void __attribute__((noinline))
foo (void)
{
void *tem = a.b;
p->b = (void *)0;
b.b = tem;
b.a = a.a;
}
int main()
{
p = &a;
a.b = &a;
foo ();
if (b.b != &a)
abort ();
return 0;
}
...@@ -497,31 +497,17 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr) ...@@ -497,31 +497,17 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
/* Unknown data dependence. */ /* Unknown data dependence. */
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{ {
gimple earlier_stmt; if (dump_enabled_p ())
{
if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
{ "can't determine dependence between ");
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
"can't determine dependence between "); dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra)); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
} }
/* We do not vectorize basic blocks with write-write dependencies. */
if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))
return true;
/* Check that it's not a load-after-store dependence. */
earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
if (DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
return true;
return false;
} }
else if (dump_enabled_p ())
if (dump_enabled_p ())
{ {
dump_printf_loc (MSG_NOTE, vect_location, dump_printf_loc (MSG_NOTE, vect_location,
"determined dependence between "); "determined dependence between ");
...@@ -531,49 +517,23 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr) ...@@ -531,49 +517,23 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
dump_printf (MSG_NOTE, "\n"); dump_printf (MSG_NOTE, "\n");
} }
/* Do not vectorize basic blocks with write-write dependences. */ /* We do not vectorize basic blocks with write-write dependencies. */
if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)) if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))
return true; return true;
/* Check dependence between DRA and DRB for basic block vectorization. /* If we have a read-write dependence check that the load is before the store.
If the accesses share same bases and offsets, we can compare their initial
constant offsets to decide whether they differ or not. In case of a read-
write dependence we check that the load is before the store to ensure that
vectorization will not change the order of the accesses. */
HOST_WIDE_INT type_size_a, type_size_b, init_a, init_b;
gimple earlier_stmt;
/* Check that the data-refs have same bases and offsets. If not, we can't
determine if they are dependent. */
if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)
|| !dr_equal_offsets_p (dra, drb))
return true;
/* Check the types. */
type_size_a = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))));
type_size_b = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))));
if (type_size_a != type_size_b
|| !types_compatible_p (TREE_TYPE (DR_REF (dra)),
TREE_TYPE (DR_REF (drb))))
return true;
init_a = TREE_INT_CST_LOW (DR_INIT (dra));
init_b = TREE_INT_CST_LOW (DR_INIT (drb));
/* Two different locations - no dependence. */
if (init_a != init_b)
return false;
/* We have a read-write dependence. Check that the load is before the store.
When we vectorize basic blocks, vector load can be only before When we vectorize basic blocks, vector load can be only before
corresponding scalar load, and vector store can be only after its corresponding scalar load, and vector store can be only after its
corresponding scalar store. So the order of the acceses is preserved in corresponding scalar store. So the order of the acceses is preserved in
case the load is before the store. */ case the load is before the store. */
earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb)); gimple earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt)))) if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
return false; {
/* That only holds for load-store pairs taking part in vectorization. */
if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dra)))
&& STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (drb))))
return false;
}
return true; return true;
} }
......
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