Commit e56c602e by Richard Biener Committed by Richard Biener

re PR tree-optimization/68583 (Missed if-conversion)

2015-12-09  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/68583
	* tree-if-conv.c (if_convertible_phi_p): Drop
	flag_tree_loop_if_convert_stores check in favor of the
	existing any_mask_load_store check.
	(insert_gimplified_predicates): Likewise.
	(combine_blocks): Likewise.
	(tree_if_conversion): Likewise.
	(ifcvt_memrefs_wont_trap): Properly check
	flag_tree_loop_if_convert_stores in all places that can end
	up introducing store-data-races.
	(if_convertible_gimple_assign_stmt_p): Remove restriction
	on flag_tree_loop_if_convert_stores for stores we can if-convert
	without introducing store-data-races.  Force versioning for
	all if-converted stores.

	* gcc.dg/tree-ssa/ifc-pr68583.c: New testcase.
	* gcc.dg/vect/vect-72.c: Adjust.
	* gcc.dg/vect/vect-cselim-2.c: Likewise.
	* gcc.dg/vect/vect-strided-store-a-u8-i2.c: Likewise.

From-SVN: r231453
parent 03080983
2015-12-09 Richard Biener <rguenther@suse.de>
PR tree-optimization/68583
* tree-if-conv.c (if_convertible_phi_p): Drop
flag_tree_loop_if_convert_stores check in favor of the
existing any_mask_load_store check.
(insert_gimplified_predicates): Likewise.
(combine_blocks): Likewise.
(tree_if_conversion): Likewise.
(ifcvt_memrefs_wont_trap): Properly check
flag_tree_loop_if_convert_stores in all places that can end
up introducing store-data-races.
(if_convertible_gimple_assign_stmt_p): Remove restriction
on flag_tree_loop_if_convert_stores for stores we can if-convert
without introducing store-data-races. Force versioning for
all if-converted stores.
2015-12-09 Tom de Vries <tom@codesourcery.com> 2015-12-09 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68716 PR tree-optimization/68716
2015-12-09 Richard Biener <rguenther@suse.de> 2015-12-09 Richard Biener <rguenther@suse.de>
PR tree-optimization/68583
* gcc.dg/tree-ssa/ifc-pr68583.c: New testcase.
* gcc.dg/vect/vect-72.c: Adjust.
* gcc.dg/vect/vect-cselim-2.c: Likewise.
* gcc.dg/vect/vect-strided-store-a-u8-i2.c: Likewise.
2015-12-09 Richard Biener <rguenther@suse.de>
PR tree-optimization/68417 PR tree-optimization/68417
* gcc.dg/vect/pr68417.c: New testcase. * gcc.dg/vect/pr68417.c: New testcase.
......
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-ifcvt" } */
void foo (long *a)
{
int i;
for (i = 0; i < 100; i+=2)
{
long *p = &a[i+1];
if (a[i] == 0)
{
*p = 2;
a[i] = 3;
}
else
{
*p = 3;
a[i] = 4;
}
}
}
/* { dg-final { scan-tree-dump "Applying if-conversion" "ifcvt" } } */
...@@ -19,9 +19,10 @@ int main1 () ...@@ -19,9 +19,10 @@ int main1 ()
for (i=0; i < N+1; i++) for (i=0; i < N+1; i++)
{ {
ib[i] = i; ib[i] = i;
/* Avoid vectorization. */
if (i%3 == 0) if (i%3 == 0)
ib[i] = 5; ib[i] = 5;
/* Avoid vectorization. */
__asm__ volatile ("" : : : "memory");
} }
for (i = 1; i < N+1; i++) for (i = 1; i < N+1; i++)
......
/* { dg-require-effective-target vect_int } */ /* { dg-require-effective-target vect_int } */
/* We now if-convert the loop unconditonally as the memory locations
are always stored to. */
/* { dg-additional-options "-fno-tree-loop-if-convert" } */
#include <stdarg.h> #include <stdarg.h>
#include "tree-vect.h" #include "tree-vect.h"
......
...@@ -26,6 +26,8 @@ main1 () ...@@ -26,6 +26,8 @@ main1 ()
b[i] = i * 2; b[i] = i * 2;
if (i%3 == 0) if (i%3 == 0)
a[i] = 10; a[i] = 10;
/* Prevent vectorization. */
__asm__ volatile ("" : : : "memory");
} }
for (i = 0; i < N; i++) for (i = 0; i < N; i++)
......
...@@ -517,7 +517,7 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb) ...@@ -517,7 +517,7 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb)
PHI is not if-convertible if: PHI is not if-convertible if:
- it has more than 2 arguments. - it has more than 2 arguments.
When the flag_tree_loop_if_convert_stores is not set, PHI is not When we didn't see if-convertible stores, PHI is not
if-convertible if: if-convertible if:
- a virtual PHI is immediately used in another PHI node, - a virtual PHI is immediately used in another PHI node,
- there is a virtual PHI in a BB other than the loop->header. - there is a virtual PHI in a BB other than the loop->header.
...@@ -545,10 +545,10 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi, ...@@ -545,10 +545,10 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi,
} }
} }
if (flag_tree_loop_if_convert_stores || any_mask_load_store) if (any_mask_load_store)
return true; return true;
/* When the flag_tree_loop_if_convert_stores is not set, check /* When there were no if-convertible stores, check
that there are no memory writes in the branches of the loop to be that there are no memory writes in the branches of the loop to be
if-converted. */ if-converted. */
if (virtual_operand_p (gimple_phi_result (phi))) if (virtual_operand_p (gimple_phi_result (phi)))
...@@ -713,16 +713,15 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs) ...@@ -713,16 +713,15 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
to unconditionally. */ to unconditionally. */
if (base_master_dr if (base_master_dr
&& DR_BASE_W_UNCONDITIONALLY (*base_master_dr)) && DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
return true; return flag_tree_loop_if_convert_stores;
else else
{ {
/* or the base is know to be not readonly. */ /* or the base is know to be not readonly. */
tree base_tree = get_base_address (DR_REF (a)); tree base_tree = get_base_address (DR_REF (a));
if (DECL_P (base_tree) if (DECL_P (base_tree)
&& decl_binds_to_current_def_p (base_tree) && decl_binds_to_current_def_p (base_tree)
&& flag_tree_loop_if_convert_stores && ! TREE_READONLY (base_tree))
&& !TREE_READONLY (base_tree)) return flag_tree_loop_if_convert_stores;
return true;
} }
} }
return false; return false;
...@@ -791,7 +790,6 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt, ...@@ -791,7 +790,6 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt,
bool *any_mask_load_store) bool *any_mask_load_store)
{ {
tree lhs = gimple_assign_lhs (stmt); tree lhs = gimple_assign_lhs (stmt);
basic_block bb;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -835,28 +833,10 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt, ...@@ -835,28 +833,10 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt,
return false; return false;
} }
if (flag_tree_loop_if_convert_stores) /* When if-converting stores force versioning, likewise if we
return true; ended up generating store data races. */
if (gimple_vdef (stmt))
bb = gimple_bb (stmt); *any_mask_load_store = true;
if (TREE_CODE (lhs) != SSA_NAME
&& bb != bb->loop_father->header
&& !bb_with_exit_edge_p (bb->loop_father, bb))
{
if (ifcvt_can_use_mask_load_store (stmt))
{
gimple_set_plf (stmt, GF_PLF_2, true);
*any_mask_load_store = true;
return true;
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "LHS is not var\n");
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
return false;
}
return true; return true;
} }
...@@ -1851,8 +1831,7 @@ insert_gimplified_predicates (loop_p loop, bool any_mask_load_store) ...@@ -1851,8 +1831,7 @@ insert_gimplified_predicates (loop_p loop, bool any_mask_load_store)
stmts = bb_predicate_gimplified_stmts (bb); stmts = bb_predicate_gimplified_stmts (bb);
if (stmts) if (stmts)
{ {
if (flag_tree_loop_if_convert_stores if (any_mask_load_store)
|| any_mask_load_store)
{ {
/* Insert the predicate of the BB just after the label, /* Insert the predicate of the BB just after the label,
as the if-conversion of memory writes will use this as the if-conversion of memory writes will use this
...@@ -2174,7 +2153,7 @@ combine_blocks (struct loop *loop, bool any_mask_load_store) ...@@ -2174,7 +2153,7 @@ combine_blocks (struct loop *loop, bool any_mask_load_store)
insert_gimplified_predicates (loop, any_mask_load_store); insert_gimplified_predicates (loop, any_mask_load_store);
predicate_all_scalar_phis (loop); predicate_all_scalar_phis (loop);
if (flag_tree_loop_if_convert_stores || any_mask_load_store) if (any_mask_load_store)
predicate_mem_writes (loop); predicate_mem_writes (loop);
/* Merge basic blocks: first remove all the edges in the loop, /* Merge basic blocks: first remove all the edges in the loop,
...@@ -2691,7 +2670,7 @@ tree_if_conversion (struct loop *loop) ...@@ -2691,7 +2670,7 @@ tree_if_conversion (struct loop *loop)
} }
todo |= TODO_cleanup_cfg; todo |= TODO_cleanup_cfg;
if (flag_tree_loop_if_convert_stores || any_mask_load_store) if (any_mask_load_store)
{ {
mark_virtual_operands_for_renaming (cfun); mark_virtual_operands_for_renaming (cfun);
todo |= TODO_update_ssa_only_virtuals; todo |= TODO_update_ssa_only_virtuals;
......
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