diff options
-rw-r--r-- | gcc/gimple-range-gori.cc | 53 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr109274.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/pr109265.f90 | 39 | ||||
-rw-r--r-- | gcc/value-relation.h | 7 |
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; |