Commit 2bedb645 by Jeff Law Committed by Jeff Law

re PR tree-optimization/69320 (wrong code generation at -O2 and higher)

2016-01-18  Jeff Law  <law@redhat.com>

	PR tree-optimization/69320
	* tree-ssa-dom.c (record_edge_info): For comparisons against a boolean
	ranged object, do nothing if the RHS constant is not [0..1].
	(optimize_stmt): Comparing a boolean ranged object against a
	constant outside [0..1] results in a compile-time constant.

	* tree-ssanames.c (ssa_name_has_boolean_range): Remove unnecessary
	test.

	PR tree-optimization/69320
	* gcc.c-torture/pr69320-1.c: New test.
	* gcc.c-torture/pr69320-2.c: New test.
	* gcc.c-torture/pr69320-3.c: New test.
	* gcc.c-torture/pr69320-4.c: New test.

From-SVN: r232548
parent 17c15cb9
2016-01-18 Jeff Law <law@redhat.com>
PR tree-optimization/69320
* tree-ssa-dom.c (record_edge_info): For comparisons against a boolean
ranged object, do nothing if the RHS constant is not [0..1].
(optimize_stmt): Comparing a boolean ranged object against a
constant outside [0..1] results in a compile-time constant.
* tree-ssanames.c (ssa_name_has_boolean_range): Remove unnecessary
test.
2016-01-18 Sandra Loosemore <sandra@codesourcery.com>
* doc/invoke.texi (Invoking GCC): Add new section to menu.
......
2016-01-15 Jeff Law <law@redhat.com>
PR tree-optimization/69320
* gcc.c-torture/pr69320-1.c: New test.
* gcc.c-torture/pr69320-2.c: New test.
* gcc.c-torture/pr69320-3.c: New test.
* gcc.c-torture/pr69320-4.c: New test.
2016-01-18 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/11858
......
#include <stdlib.h>
int a, b, d, f;
char c;
static int *e = &d;
int main() {
int g = -1L;
*e = g;
c = 4;
for (; c >= 14; c++)
*e = 1;
f = a == 0;
*e ^= f;
int h = ~d;
if (d)
b = h;
if (h)
exit (0);
abort ();
}
#include <stdlib.h>
int a, *c, d, e, g, f;
short b;
int
fn1 ()
{
int h = d != 10;
if (h > g)
asm volatile ("" : : : "memory");
if (h == 10)
{
int *i = 0;
a = 0;
for (; a < 7; a++)
for (; *i;)
;
}
else
{
b = e / h;
return f;
}
c = &h;
abort ();
}
int
main ()
{
fn1 ();
exit (0);
}
#include <stdlib.h>
static int a[40] = {7, 5, 3, 3, 0, 0, 3};
short b;
int c = 5;
int main() {
b = 0;
for (; b <= 3; b++)
if (a[b + 6] ^ (0 || c))
;
else
break;
if (b != 4)
abort ();
exit (0);
}
#include <stdlib.h>
int a;
char b, d;
short c;
short fn1(int p1, int p2) { return p2 >= 2 ? p1 : p1 > p2; }
int main() {
int *e = &a, *f = &a;
b = 1;
for (; b <= 9; b++) {
c = *e != 5 || d;
*f = fn1(c || b, a);
}
if ((long long) a != 1)
abort ();
exit (0);
}
......@@ -387,11 +387,16 @@ record_edge_info (basic_block bb)
/* Special case comparing booleans against a constant as we
know the value of OP0 on both arms of the branch. i.e., we
can record an equivalence for OP0 rather than COND. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& TREE_CODE (op0) == SSA_NAME
can record an equivalence for OP0 rather than COND.
However, don't do this if the constant isn't zero or one.
Such conditionals will get optimized more thoroughly during
the domwalk. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& TREE_CODE (op0) == SSA_NAME
&& ssa_name_has_boolean_range (op0)
&& is_gimple_min_invariant (op1))
&& is_gimple_min_invariant (op1)
&& (integer_zerop (op1) || integer_onep (op1)))
{
tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
tree false_val = constant_boolean_node (false, TREE_TYPE (op0));
......@@ -1828,6 +1833,31 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
}
}
if (gimple_code (stmt) == GIMPLE_COND)
{
tree lhs = gimple_cond_lhs (stmt);
tree rhs = gimple_cond_rhs (stmt);
/* If the LHS has a range [0..1] and the RHS has a range ~[0..1],
then this conditional is computable at compile time. We can just
shove either 0 or 1 into the LHS, mark the statement as modified
and all the right things will just happen below.
Note this would apply to any case where LHS has a range
narrower than its type implies and RHS is outside that
narrower range. Future work. */
if (TREE_CODE (lhs) == SSA_NAME
&& ssa_name_has_boolean_range (lhs)
&& TREE_CODE (rhs) == INTEGER_CST
&& ! (integer_zerop (rhs) || integer_onep (rhs)))
{
gimple_cond_set_lhs (as_a <gcond *> (stmt),
fold_convert (TREE_TYPE (lhs),
integer_zero_node));
gimple_set_modified (stmt, true);
}
}
update_stmt_if_modified (stmt);
eliminate_redundant_computations (&si, const_and_copies,
avail_exprs_stack);
......
......@@ -437,8 +437,7 @@ ssa_name_has_boolean_range (tree op)
only takes on values [0..1] as determined by VRP
analysis. */
if (INTEGRAL_TYPE_P (TREE_TYPE (op))
&& (TYPE_PRECISION (TREE_TYPE (op)) > 1
|| TYPE_UNSIGNED (TREE_TYPE (op)))
&& (TYPE_PRECISION (TREE_TYPE (op)) > 1)
&& wi::eq_p (get_nonzero_bits (op), 1))
return true;
......
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