Skip to content

Commit

Permalink
2017-09-22 Richard Biener <rguenther@suse.de>
Browse files Browse the repository at this point in the history
	PR tree-optimization/82291
	* tree-if-conv.c (predicate_mem_writes): Make sure to
	remove writes in blocks predicated with false.

	* gcc.dg/torture/pr82291.c: New testcase.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253093 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
rguenth committed Sep 22, 2017
1 parent 4c03ed5 commit fc1c9df
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 90 deletions.
6 changes: 6 additions & 0 deletions gcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2017-09-22 Richard Biener <rguenther@suse.de>

PR tree-optimization/82291
* tree-if-conv.c (predicate_mem_writes): Make sure to
remove writes in blocks predicated with false.

2017-09-22 Richard Biener <rguenther@suse.de>

* sese.c: Include cfganal.h.
Expand Down
5 changes: 5 additions & 0 deletions gcc/testsuite/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2017-09-22 Richard Biener <rguenther@suse.de>

PR tree-optimization/82291
* gcc.dg/torture/pr82291.c: New testcase.

2017-09-22 Sergey Shalnov <sergey.shalnov@intel.com>

* gcc.target/i386/avx512f-constant-set.c: New test.
Expand Down
37 changes: 37 additions & 0 deletions gcc/testsuite/gcc.dg/torture/pr82291.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* { dg-do run } */

int a, c, d, *h;
unsigned b;

int *fn1 ()
{
int *f[3], g = 0;
for (; g < 3; g++)
f[g] = &a;
if (--b > a)
{
if (a > b)
d++;
return f[0];
}
}

void fn2 ()
{
for (; c >= 0; --c)
{
int j[] = { 0, 0, 0, 0, 0 };
int *k = fn1 ();
if (!k)
__builtin_abort ();
h = &j[4];
}
}

int main ()
{
fn2 ();
if (d != 0)
__builtin_abort ();
return 0;
}
190 changes: 100 additions & 90 deletions gcc/tree-if-conv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2197,7 +2197,7 @@ predicate_mem_writes (loop_p loop)
gimple *stmt;
int index;

if (is_true_predicate (cond) || is_false_predicate (cond))
if (is_true_predicate (cond))
continue;

swap = false;
Expand All @@ -2210,97 +2210,107 @@ predicate_mem_writes (loop_p loop)
vect_sizes.truncate (0);
vect_masks.truncate (0);

for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
if (!gimple_assign_single_p (stmt = gsi_stmt (gsi)))
continue;
else if (gimple_plf (stmt, GF_PLF_2))
{
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
tree ref, addr, ptr, mask;
gcall *new_stmt;
gimple_seq stmts = NULL;
int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
mark_addressable (ref);
addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref),
true, NULL_TREE, true,
GSI_SAME_STMT);
if (!vect_sizes.is_empty ()
&& (index = mask_exists (bitsize, vect_sizes)) != -1)
/* Use created mask. */
mask = vect_masks[index];
else
{
if (COMPARISON_CLASS_P (cond))
mask = gimple_build (&stmts, TREE_CODE (cond),
boolean_type_node,
TREE_OPERAND (cond, 0),
TREE_OPERAND (cond, 1));
else
{
gcc_assert (TREE_CODE (cond) == SSA_NAME);
mask = cond;
}

if (swap)
{
tree true_val
= constant_boolean_node (true, TREE_TYPE (mask));
mask = gimple_build (&stmts, BIT_XOR_EXPR,
TREE_TYPE (mask), mask, true_val);
}
gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);

mask = ifc_temp_var (TREE_TYPE (mask), mask, &gsi);
/* Save mask and its size for further use. */
vect_sizes.safe_push (bitsize);
vect_masks.safe_push (mask);
}
ptr = build_int_cst (reference_alias_ptr_type (ref),
get_object_alignment (ref));
/* Copy points-to info if possible. */
if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
ref);
if (TREE_CODE (lhs) == SSA_NAME)
{
new_stmt
= gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
ptr, mask);
gimple_call_set_lhs (new_stmt, lhs);
gimple_set_vuse (new_stmt, gimple_vuse (stmt));
}
else
{
new_stmt
= gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
if (!gimple_assign_single_p (stmt = gsi_stmt (gsi)))
;
else if (is_false_predicate (cond))
{
unlink_stmt_vdef (stmt);
gsi_remove (&gsi, true);
release_defs (stmt);
continue;
}
else if (gimple_plf (stmt, GF_PLF_2))
{
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
tree ref, addr, ptr, mask;
gcall *new_stmt;
gimple_seq stmts = NULL;
int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
mark_addressable (ref);
addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref),
true, NULL_TREE, true,
GSI_SAME_STMT);
if (!vect_sizes.is_empty ()
&& (index = mask_exists (bitsize, vect_sizes)) != -1)
/* Use created mask. */
mask = vect_masks[index];
else
{
if (COMPARISON_CLASS_P (cond))
mask = gimple_build (&stmts, TREE_CODE (cond),
boolean_type_node,
TREE_OPERAND (cond, 0),
TREE_OPERAND (cond, 1));
else
{
gcc_assert (TREE_CODE (cond) == SSA_NAME);
mask = cond;
}

if (swap)
{
tree true_val
= constant_boolean_node (true, TREE_TYPE (mask));
mask = gimple_build (&stmts, BIT_XOR_EXPR,
TREE_TYPE (mask), mask, true_val);
}
gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);

mask = ifc_temp_var (TREE_TYPE (mask), mask, &gsi);
/* Save mask and its size for further use. */
vect_sizes.safe_push (bitsize);
vect_masks.safe_push (mask);
}
ptr = build_int_cst (reference_alias_ptr_type (ref),
get_object_alignment (ref));
/* Copy points-to info if possible. */
if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
ref);
if (TREE_CODE (lhs) == SSA_NAME)
{
new_stmt
= gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
ptr, mask);
gimple_call_set_lhs (new_stmt, lhs);
gimple_set_vuse (new_stmt, gimple_vuse (stmt));
}
else
{
new_stmt
= gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
mask, rhs);
gimple_set_vuse (new_stmt, gimple_vuse (stmt));
gimple_set_vdef (new_stmt, gimple_vdef (stmt));
SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
}
gimple_call_set_nothrow (new_stmt, true);
gimple_set_vuse (new_stmt, gimple_vuse (stmt));
gimple_set_vdef (new_stmt, gimple_vdef (stmt));
SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
}
gimple_call_set_nothrow (new_stmt, true);

gsi_replace (&gsi, new_stmt, true);
}
else if (gimple_vdef (stmt))
{
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
tree type = TREE_TYPE (lhs);

lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
if (swap)
std::swap (lhs, rhs);
cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
is_gimple_condexpr, NULL_TREE,
true, GSI_SAME_STMT);
rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
update_stmt (stmt);
}
gsi_replace (&gsi, new_stmt, true);
}
else if (gimple_vdef (stmt))
{
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
tree type = TREE_TYPE (lhs);

lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
if (swap)
std::swap (lhs, rhs);
cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
is_gimple_condexpr, NULL_TREE,
true, GSI_SAME_STMT);
rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
update_stmt (stmt);
}
gsi_next (&gsi);
}
}
}

Expand Down

0 comments on commit fc1c9df

Please sign in to comment.