Skip to content

Commit

Permalink
2014-11-13 Richard Biener <rguenther@suse.de>
Browse files Browse the repository at this point in the history
	* match.pd: Add tcc_comparison, inverted_tcc_comparison
	and inverted_tcc_comparison_with_nans operator lists.
	Use tcc_comparison in the truth_valued_p predicate definition.
	Restrict logical_inverted_value with bit_xor to integral types.
	Build a boolean true for simplifying x |^ !x because of
	vector types.  Implement patterns from forward_propagate_comparison
	* tree-ssa-forwprop.c (forward_propagate_comparison): Remove.
	(get_prop_dest_stmt): Likewise.
	(pass_forwprop::execute): Do not call it.
	* fold-const.c (fold_unary_loc): Remove the pattern here.

	* gcc.dg/tree-ssa/forwprop-28.c: Adjust.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217496 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
rguenth committed Nov 13, 2014
1 parent 7e689f9 commit 9ec260f
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 137 deletions.
13 changes: 13 additions & 0 deletions gcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
2014-11-13 Richard Biener <rguenther@suse.de>

* match.pd: Add tcc_comparison, inverted_tcc_comparison
and inverted_tcc_comparison_with_nans operator lists.
Use tcc_comparison in the truth_valued_p predicate definition.
Restrict logical_inverted_value with bit_xor to integral types.
Build a boolean true for simplifying x |^ !x because of
vector types. Implement patterns from forward_propagate_comparison
* tree-ssa-forwprop.c (forward_propagate_comparison): Remove.
(get_prop_dest_stmt): Likewise.
(pass_forwprop::execute): Do not call it.
* fold-const.c (fold_unary_loc): Remove the pattern here.

2014-11-13 Ilya Verbin <ilya.verbin@intel.com>
Andrey Turetskiy <andrey.turetskiy@intel.com>

Expand Down
12 changes: 0 additions & 12 deletions gcc/fold-const.c
Original file line number Diff line number Diff line change
Expand Up @@ -7938,18 +7938,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
if (i == count)
return build_vector (type, elements);
}
else if (COMPARISON_CLASS_P (arg0)
&& (VECTOR_TYPE_P (type)
|| (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1)))
{
tree op_type = TREE_TYPE (TREE_OPERAND (arg0, 0));
enum tree_code subcode = invert_tree_comparison (TREE_CODE (arg0),
HONOR_NANS (TYPE_MODE (op_type)));
if (subcode != ERROR_MARK)
return build2_loc (loc, subcode, type, TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg0, 1));
}


return NULL_TREE;

Expand Down
54 changes: 51 additions & 3 deletions gcc/match.pd
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ along with GCC; see the file COPYING3. If not see
CONSTANT_CLASS_P
tree_expr_nonnegative_p)

/* Operator lists. */
(define_operator_list tcc_comparison
lt le eq ne ge gt unordered ordered unlt unle ungt unge uneq ltgt)
(define_operator_list inverted_tcc_comparison
ge gt ne eq lt le ordered unordered ge gt le lt ltgt uneq)
(define_operator_list inverted_tcc_comparison_with_nans
unge ungt ne eq unlt unle ordered unordered ge gt le lt ltgt uneq)


/* Simplifications of operations with one constant operand and
simplifications to constants or single values. */
Expand Down Expand Up @@ -172,7 +180,7 @@ along with GCC; see the file COPYING3. If not see
(match truth_valued_p
@0
(if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1)))
(for op (lt le eq ne ge gt truth_and truth_andif truth_or truth_orif truth_xor)
(for op (tcc_comparison truth_and truth_andif truth_or truth_orif truth_xor)
(match truth_valued_p
(op @0 @1)))
(match truth_valued_p
Expand All @@ -187,7 +195,8 @@ along with GCC; see the file COPYING3. If not see
(ne truth_valued_p@0 integer_onep)
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))))
(match (logical_inverted_value @0)
(bit_xor truth_valued_p@0 integer_onep))
(bit_xor truth_valued_p@0 integer_onep)
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))))

/* X & !X -> 0. */
(simplify
Expand All @@ -197,7 +206,7 @@ along with GCC; see the file COPYING3. If not see
(for op (bit_ior bit_xor)
(simplify
(op:c truth_valued_p@0 (logical_inverted_value @0))
{ build_one_cst (type); }))
{ constant_boolean_node (true, type); }))

(for bitop (bit_and bit_ior)
rbitop (bit_ior bit_and)
Expand Down Expand Up @@ -632,3 +641,42 @@ along with GCC; see the file COPYING3. If not see
(simplify
(cond (logical_inverted_value truth_valued_p@0) @1 @2)
(cond @0 @2 @1))


/* Simplifications of comparisons. */

/* We can simplify a logical negation of a comparison to the
inverted comparison. As we cannot compute an expression
operator using invert_tree_comparison we have to simulate
that with expression code iteration. */
(for cmp (tcc_comparison)
icmp (inverted_tcc_comparison)
ncmp (inverted_tcc_comparison_with_nans)
/* Ideally we'd like to combine the following two patterns
and handle some more cases by using
(logical_inverted_value (cmp @0 @1))
here but for that genmatch would need to "inline" that.
For now implement what forward_propagate_comparison did. */
(simplify
(bit_not (cmp @0 @1))
(if (VECTOR_TYPE_P (type)
|| (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1))
/* Comparison inversion may be impossible for trapping math,
invert_tree_comparison will tell us. But we can't use
a computed operator in the replacement tree thus we have
to play the trick below. */
(with { enum tree_code ic = invert_tree_comparison
(cmp, HONOR_NANS (TYPE_MODE (TREE_TYPE (@0)))); }
(if (ic == icmp)
(icmp @0 @1))
(if (ic == ncmp)
(ncmp @0 @1)))))
(simplify
(bit_xor (cmp @0 @1) integer_onep)
(if (INTEGRAL_TYPE_P (type))
(with { enum tree_code ic = invert_tree_comparison
(cmp, HONOR_NANS (TYPE_MODE (TREE_TYPE (@0)))); }
(if (ic == icmp)
(icmp @0 @1))
(if (ic == ncmp)
(ncmp @0 @1))))))
4 changes: 4 additions & 0 deletions gcc/testsuite/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2014-11-13 Richard Biener <rguenther@suse.de>

* gcc.dg/tree-ssa/forwprop-28.c: Adjust.

2014-11-12 Alexander Ivchenko <alexander.ivchenko@intel.com>

* lib/target-supports.exp (error_h): New check.
Expand Down
7 changes: 6 additions & 1 deletion gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ test_8 (int code)
oof ();
}

/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* <" 8 "forwprop1"} } */
/* ??? This used to check for 8 times transforming the combined conditional
to a ordered compare. But the transform does not trigger if we transform
the negated code == 22 compare to code != 22 first. It turns out if
we do that we even generate better code on x86 at least. */

/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* <" 4 "forwprop1"} } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */

121 changes: 0 additions & 121 deletions gcc/tree-ssa-forwprop.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,38 +233,6 @@ fwprop_invalidate_lattice (tree name)
}


/* Get the next statement we can propagate NAME's value into skipping
trivial copies. Returns the statement that is suitable as a
propagation destination or NULL_TREE if there is no such one.
This only returns destinations in a single-use chain. FINAL_NAME_P
if non-NULL is written to the ssa name that represents the use. */

static gimple
get_prop_dest_stmt (tree name, tree *final_name_p)
{
use_operand_p use;
gimple use_stmt;

do {
/* If name has multiple uses, bail out. */
if (!single_imm_use (name, &use, &use_stmt))
return NULL;

/* If this is not a trivial copy, we found it. */
if (!gimple_assign_ssa_name_copy_p (use_stmt)
|| gimple_assign_rhs1 (use_stmt) != name)
break;

/* Continue searching uses of the copy destination. */
name = gimple_assign_lhs (use_stmt);
} while (1);

if (final_name_p)
*final_name_p = name;

return use_stmt;
}

/* Get the statement we can propagate from into NAME skipping
trivial copies. Returns the statement which defines the
propagation source or NULL_TREE if there is no such one.
Expand Down Expand Up @@ -1060,90 +1028,6 @@ forward_propagate_addr_expr (tree name, tree rhs, bool parent_single_use_p)
}


/* Forward propagate the comparison defined in *DEFGSI like
cond_1 = x CMP y to uses of the form
a_1 = (T')cond_1
a_1 = !cond_1
a_1 = cond_1 != 0
Returns true if stmt is now unused. Advance DEFGSI to the next
statement. */

static bool
forward_propagate_comparison (gimple_stmt_iterator *defgsi)
{
gimple stmt = gsi_stmt (*defgsi);
tree name = gimple_assign_lhs (stmt);
gimple use_stmt;
tree tmp = NULL_TREE;
gimple_stmt_iterator gsi;
enum tree_code code;
tree lhs;

/* Don't propagate ssa names that occur in abnormal phis. */
if ((TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
|| (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
goto bailout;

/* Do not un-cse comparisons. But propagate through copies. */
use_stmt = get_prop_dest_stmt (name, &name);
if (!use_stmt
|| !is_gimple_assign (use_stmt))
goto bailout;

code = gimple_assign_rhs_code (use_stmt);
lhs = gimple_assign_lhs (use_stmt);
if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
goto bailout;

/* We can propagate the condition into a statement that
computes the logical negation of the comparison result. */
if ((code == BIT_NOT_EXPR
&& TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
|| (code == BIT_XOR_EXPR
&& integer_onep (gimple_assign_rhs2 (use_stmt))))
{
tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
bool nans = HONOR_NANS (TYPE_MODE (type));
enum tree_code inv_code;
inv_code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
if (inv_code == ERROR_MARK)
goto bailout;

tmp = build2 (inv_code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt));
}
else
goto bailout;

gsi = gsi_for_stmt (use_stmt);
gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
use_stmt = gsi_stmt (gsi);
update_stmt (use_stmt);

if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Replaced '");
print_gimple_expr (dump_file, stmt, 0, dump_flags);
fprintf (dump_file, "' with '");
print_gimple_expr (dump_file, use_stmt, 0, dump_flags);
fprintf (dump_file, "'\n");
}

/* When we remove stmt now the iterator defgsi goes off it's current
sequence, hence advance it now. */
gsi_next (defgsi);

/* Remove defining statements. */
return remove_prop_source_from_use (name);

bailout:
gsi_next (defgsi);
return false;
}


/* Helper function for simplify_gimple_switch. Remove case labels that
have values outside the range of the new type. */

Expand Down Expand Up @@ -2316,11 +2200,6 @@ pass_forwprop::execute (function *fun)
else
gsi_next (&gsi);
}
else if (TREE_CODE_CLASS (code) == tcc_comparison)
{
if (forward_propagate_comparison (&gsi))
cfg_changed = true;
}
else
gsi_next (&gsi);
}
Expand Down

0 comments on commit 9ec260f

Please sign in to comment.