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
This commit is contained in:
parent
9eb8c09fda
commit
649d196dbd
@ -1,3 +1,11 @@
|
||||
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>
|
||||
|
||||
* config/ia64/ia64.md (prologue_allocate_stack): Block auto-
|
||||
|
@ -1,3 +1,9 @@
|
||||
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>
|
||||
|
||||
* gcc.target/ia64/pr52731.c: New.
|
||||
|
24
gcc/testsuite/gcc.dg/torture/pr59374-1.c
Normal file
24
gcc/testsuite/gcc.dg/torture/pr59374-1.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* { 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;
|
||||
}
|
26
gcc/testsuite/gcc.dg/torture/pr59374-2.c
Normal file
26
gcc/testsuite/gcc.dg/torture/pr59374-2.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* { 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)
|
||||
/* Unknown data dependence. */
|
||||
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
|
||||
{
|
||||
gimple earlier_stmt;
|
||||
|
||||
if (dump_enabled_p ())
|
||||
{
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"can't determine dependence between ");
|
||||
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
|
||||
dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
|
||||
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
|
||||
if (dump_enabled_p ())
|
||||
{
|
||||
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
|
||||
"can't determine dependence between ");
|
||||
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
|
||||
dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
|
||||
dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (dump_enabled_p ())
|
||||
else if (dump_enabled_p ())
|
||||
{
|
||||
dump_printf_loc (MSG_NOTE, vect_location,
|
||||
"determined dependence between ");
|
||||
@ -531,49 +517,23 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
|
||||
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))
|
||||
return true;
|
||||
|
||||
/* Check dependence between DRA and DRB for basic block vectorization.
|
||||
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.
|
||||
/* If 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
|
||||
corresponding scalar load, and vector store can be only after its
|
||||
corresponding scalar store. So the order of the acceses is preserved in
|
||||
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))))
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user