Backport PRs 82244, 82264, 82276, 82285, 82291

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

	Backport from mainline
	2017-09-19  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/82244
	* tree-vrp.c (remove_range_assertions): Do not propagate
	a constant to abnormals but replace the assert with a copy.

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

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

	PR tree-optimization/82276
	PR tree-optimization/82244
	* tree-vrp.c (build_assert_expr_for): Set
	SSA_NAME_OCCURS_IN_ABNORMAL_PHI if the variable we assert on
	has it set.
	(remove_range_assertions): Revert earlier change.

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

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

	PR tree-optimization/82264
	* tree-ssa-sccvn.c (vn_phi_eq): Use safe_dyn_cast to check
	for GIMPLE_CONDs.
	(vn_phi_lookup): Likewise.
	(vn_phi_insert): Likewise.
	* is-a.h (safe_dyn_cast): New.

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

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

	PR tree-optimization/82285
	* tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
	enumeral types.

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

	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.

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

From-SVN: r253190
This commit is contained in:
Richard Biener 2017-09-26 10:16:40 +00:00 committed by Richard Biener
parent bff800cf76
commit 87c7cf4766
12 changed files with 329 additions and 98 deletions

View File

@ -1,3 +1,42 @@
2017-09-26 Richard Biener <rguenther@suse.de>
Backport from mainline
2017-09-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/82244
* tree-vrp.c (remove_range_assertions): Do not propagate
a constant to abnormals but replace the assert with a copy.
2017-09-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/82276
PR tree-optimization/82244
* tree-vrp.c (build_assert_expr_for): Set
SSA_NAME_OCCURS_IN_ABNORMAL_PHI if the variable we assert on
has it set.
(remove_range_assertions): Revert earlier change.
2017-09-20 Richard Biener <rguenther@suse.de>
PR tree-optimization/82264
* tree-ssa-sccvn.c (vn_phi_eq): Use safe_dyn_cast to check
for GIMPLE_CONDs.
(vn_phi_lookup): Likewise.
(vn_phi_insert): Likewise.
* is-a.h (safe_dyn_cast): New.
2017-09-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/82285
* tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
enumeral types.
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-21 Alan Modra <amodra@gmail.com>
PR target/81996

View File

@ -103,6 +103,11 @@ TYPE dyn_cast <TYPE> (pointer)
Note that we have converted two sets of assertions in the calls to varpool
into safe and efficient use of a variable.
TYPE safe_dyn_cast <TYPE> (pointer)
Like dyn_cast <TYPE> (pointer), except that it accepts null pointers
and returns null results for them.
If you use these functions and get a 'inline function not defined' or a
'missing symbol' error message for 'is_a_helper<....>::test', it means that
@ -222,4 +227,13 @@ dyn_cast (U *p)
return static_cast <T> (0);
}
/* Similar to dyn_cast, except that the pointer may be null. */
template <typename T, typename U>
inline T
safe_dyn_cast (U *p)
{
return p ? dyn_cast <T> (p) : 0;
}
#endif /* GCC_IS_A_H */

View File

@ -1,3 +1,32 @@
2017-09-26 Richard Biener <rguenther@suse.de>
Backport from mainline
2017-09-19 Richard Biener <rguenther@suse.de>
PR tree-optimization/82244
* gcc.dg/torture/pr82244.c: New testcase.
2017-09-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/82276
PR tree-optimization/82244
* gcc.dg/torture/pr82276.c: New testcase.
2017-09-20 Richard Biener <rguenther@suse.de>
PR tree-optimization/82264
* gcc.dg/torture/pr82264.c: New testcase.
2017-09-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/82285
* gcc.dg/torture/pr82285.c: New testcase.
2017-09-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/82291
* gcc.dg/torture/pr82291.c: New testcase.
2017-09-22 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/81929

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
typedef struct a {
struct a *b;
} a;
extern int d(void);
extern int g(void);
extern int h(void);
extern int _setjmp(void *);
int c(void)
{
1 ? d() : 0;
a *e;
while (e) {
e = (e == (a *) c) ? 0 : e->b;
while (e) {
int f = 0;
g();
if (_setjmp(0)) {
if (f & 6) {
;
} else if (f & 2) {
h();
}
}
}
}
}

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
char a;
int c;
unsigned b ();
unsigned
setjmp ()
{
}
static void
d ()
{
if (b ())
c = 3;
}
void
e ()
{
d ();
a && ({ setjmp (); });
}

View File

@ -0,0 +1,32 @@
/* { dg-do compile } */
typedef struct a {
struct a *b;
} a;
extern int d(void);
extern int g(void);
extern int h(void);
extern int _setjmp();
extern int i(void);
void c(void) {
1 ? d() : 0;
a *e;
while (e) {
e = (e == (a *) c) ? 0 : e->b;
while (e) {
unsigned int f = 0;
g();
_setjmp(f);
if (f & 6) {
;
} else if (f & 2) {
;
} else {
h();
}
i();
}
}
}

View File

@ -0,0 +1,16 @@
/* { dg-do run } */
enum tst { first = 0, second = 1 };
int
main ()
{
enum tst data[16];
for (unsigned i = 0; i < 16; i++)
data[i] = (i < 5 ? second : first);
if (data[2] != second)
__builtin_abort ();
return 0;
}

View File

@ -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;
}

View File

@ -2198,7 +2198,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;
@ -2211,96 +2211,106 @@ 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;
gimple *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;
}
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;
gimple *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);
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 = 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_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;
}
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);
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);
}
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);
}
}
}

View File

@ -2990,16 +2990,13 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
return false;
/* Verify the controlling stmt is the same. */
gimple *last1 = last_stmt (idom1);
gimple *last2 = last_stmt (idom2);
if (gimple_code (last1) != GIMPLE_COND
|| gimple_code (last2) != GIMPLE_COND)
gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1));
gcond *last2 = safe_dyn_cast <gcond *> (last_stmt (idom2));
if (! last1 || ! last2)
return false;
bool inverted_p;
if (! cond_stmts_equal_p (as_a <gcond *> (last1),
vp1->cclhs, vp1->ccrhs,
as_a <gcond *> (last2),
vp2->cclhs, vp2->ccrhs,
if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
last2, vp2->cclhs, vp2->ccrhs,
&inverted_p))
return false;
@ -3084,7 +3081,7 @@ vn_phi_lookup (gimple *phi)
vp1.ccrhs = NULL_TREE;
basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1.block);
if (EDGE_COUNT (idom1->succs) == 2)
if (gcond *last1 = dyn_cast <gcond *> (last_stmt (idom1)))
if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
{
vp1.cclhs = vn_valueize (gimple_cond_lhs (last1));
vp1.ccrhs = vn_valueize (gimple_cond_rhs (last1));
@ -3130,7 +3127,7 @@ vn_phi_insert (gimple *phi, tree result)
vp1->ccrhs = NULL_TREE;
basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
if (EDGE_COUNT (idom1->succs) == 2)
if (gcond *last1 = dyn_cast <gcond *> (last_stmt (idom1)))
if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
{
vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));

View File

@ -3641,7 +3641,7 @@ vect_recog_bool_pattern (vec<gimple *> *stmts, tree *type_in,
rhs_code = gimple_assign_rhs_code (last_stmt);
if (CONVERT_EXPR_CODE_P (rhs_code))
{
if (TREE_CODE (TREE_TYPE (lhs)) != INTEGER_TYPE
if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
return NULL;
vectype = get_vectype_for_scalar_type (TREE_TYPE (lhs));

View File

@ -4897,7 +4897,12 @@ build_assert_expr_for (tree cond, tree v)
operand of the ASSERT_EXPR. Create it so the new name and the old one
are registered in the replacement table so that we can fix the SSA web
after adding all the ASSERT_EXPRs. */
create_new_def_for (v, assertion, NULL);
tree new_def = create_new_def_for (v, assertion, NULL);
/* Make sure we preserve abnormalness throughout an ASSERT_EXPR chain
given we have to be able to fully propagate those out to re-create
valid SSA when removing the asserts. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (v))
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_def) = 1;
return assertion;
}