aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/gimple-range-gori.cc53
-rw-r--r--gcc/testsuite/gcc.dg/pr109274.c16
-rw-r--r--gcc/testsuite/gfortran.dg/pr109265.f9039
-rw-r--r--gcc/value-relation.h7
4 files changed, 92 insertions, 23 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 3c00448..b9c3ba1 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -623,21 +623,6 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt,
tree op1 = gimple_range_ssa_p (handler.operand1 ());
tree op2 = gimple_range_ssa_p (handler.operand2 ());
- // If there is a relation, use it instead of any passed in. This will allow
- // multiple relations to be processed in compound logicals.
- if (op1 && op2)
- {
- relation_kind k = handler.op1_op2_relation (lhs);
- // If there is no relation, and op1 == op2, create a relation.
- if (!vrel_ptr && k == VREL_VARYING && op1 == op2)
- k = VREL_EQ;
- if (k != VREL_VARYING)
- {
- vrel.set_relation (k, op1, op2);
- vrel_ptr = &vrel;
- }
- }
-
// Handle end of lookup first.
if (op1 == name)
return compute_operand1_range (r, handler, lhs, name, src, vrel_ptr);
@@ -1093,6 +1078,7 @@ gori_compute::compute_operand1_range (vrange &r,
const vrange &lhs, tree name,
fur_source &src, value_relation *rel)
{
+ value_relation local_rel;
gimple *stmt = handler.stmt ();
tree op1 = handler.operand1 ();
tree op2 = handler.operand2 ();
@@ -1101,6 +1087,7 @@ gori_compute::compute_operand1_range (vrange &r,
relation_trio trio;
if (rel)
trio = rel->create_trio (lhs_name, op1, op2);
+ relation_kind op_op = trio.op1_op2 ();
Value_Range op1_range (TREE_TYPE (op1));
Value_Range tmp (TREE_TYPE (op1));
@@ -1113,10 +1100,26 @@ gori_compute::compute_operand1_range (vrange &r,
if (op2)
{
src.get_operand (op2_range, op2);
- relation_kind op_op = trio.op1_op2 ();
+
+ // If there is a relation betwen op1 and op2, use it instead.
+ // This allows multiple relations to be processed in compound logicals.
+ if (gimple_range_ssa_p (op1) && gimple_range_ssa_p (op2))
+ {
+ relation_kind k = handler.op1_op2_relation (lhs);
+ if (k != VREL_VARYING)
+ {
+ op_op = k;
+ local_rel.set_relation (op_op, op1, op2);
+ rel = &local_rel;
+ }
+ }
+
if (op_op != VREL_VARYING)
refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+ // If op1 == op2, create a new trio for just this call.
+ if (op1 == op2 && gimple_range_ssa_p (op1))
+ trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ);
if (!handler.calc_op1 (tmp, lhs, op2_range, trio))
return false;
}
@@ -1185,6 +1188,7 @@ gori_compute::compute_operand2_range (vrange &r,
const vrange &lhs, tree name,
fur_source &src, value_relation *rel)
{
+ value_relation local_rel;
gimple *stmt = handler.stmt ();
tree op1 = handler.operand1 ();
tree op2 = handler.operand2 ();
@@ -1201,9 +1205,26 @@ gori_compute::compute_operand2_range (vrange &r,
if (rel)
trio = rel->create_trio (lhs_name, op1, op2);
relation_kind op_op = trio.op1_op2 ();
+
+ // If there is a relation betwen op1 and op2, use it instead.
+ // This allows multiple relations to be processed in compound logicals.
+ if (gimple_range_ssa_p (op1) && gimple_range_ssa_p (op2))
+ {
+ relation_kind k = handler.op1_op2_relation (lhs);
+ if (k != VREL_VARYING)
+ {
+ op_op = k;
+ local_rel.set_relation (op_op, op1, op2);
+ rel = &local_rel;
+ }
+ }
+
if (op_op != VREL_VARYING)
refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+ // If op1 == op2, create a new trio for this stmt.
+ if (op1 == op2 && gimple_range_ssa_p (op1))
+ trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ);
// Intersect with range for op2 based on lhs and op1.
if (!handler.calc_op2 (tmp, lhs, op1_range, trio))
return false;
diff --git a/gcc/testsuite/gcc.dg/pr109274.c b/gcc/testsuite/gcc.dg/pr109274.c
new file mode 100644
index 0000000..5dbc023
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr109274.c
@@ -0,0 +1,16 @@
+/* PR tree-optimization/109274 */
+/* { dg-do compile } */
+/* { dg-options "-O2 " } */
+
+float a, b, c;
+int d;
+float bar (void);
+
+void
+foo (void)
+{
+ a = 0 * -(2.0f * c);
+ d = a != a ? 0 : bar ();
+ b = c;
+}
+
diff --git a/gcc/testsuite/gfortran.dg/pr109265.f90 b/gcc/testsuite/gfortran.dg/pr109265.f90
new file mode 100644
index 0000000..0d7124c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr109265.f90
@@ -0,0 +1,39 @@
+! PR tree-optimization/109265
+! { dg-do compile }
+! { dg-options "-O3 -w" }
+
+module pr109265
+ integer, parameter :: r8 = selected_real_kind (12)
+contains
+ subroutine foo (b, c, d, e, f)
+ implicit none
+ logical :: b
+ real (kind = r8) :: c, d, e, f, i
+ if (b) then
+ c = bar (c * d, e)
+ i = bar (f, c)
+ call baz (i)
+ call baz (-i)
+ end if
+ end subroutine foo
+ function bar (a, b)
+ implicit none
+ real (kind = r8) :: bar
+ real (kind = r8) :: a, b
+ bar = a + b
+ end function bar
+ subroutine baz (b)
+ implicit none
+ real (kind = r8) :: b, d, e, f, g, h, i
+ d = b
+ i = 0
+ e = d
+ f = d
+ g = d
+ 10 continue
+ if ((e.eq.d) .and. (f.eq.d) .and. (g.eq.d) .and. (h.eq.d)) then
+ h = i
+ goto 10
+ end if
+ end subroutine baz
+end module pr109265
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index 36a7586..3177ecb 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -445,13 +445,6 @@ value_relation::set_relation (relation_kind r, tree n1, tree n2)
{
gcc_checking_assert (TREE_CODE (n1) == SSA_NAME
&& TREE_CODE (n2) == SSA_NAME);
- if (n1 == n2 && r != VREL_EQ)
- {
- related = VREL_VARYING;
- name1 = NULL_TREE;
- name2 = NULL_TREE;
- return;
- }
related = r;
name1 = n1;
name2 = n2;