[COMMITTED] tree-optimization/102463 - Look for a relation between operands only when possible.

Message ID 229b4cf2-d8ca-584f-585c-06294a5d39a1@redhat.com
State Committed
Headers
Series [COMMITTED] tree-optimization/102463 - Look for a relation between operands only when possible. |

Commit Message

Andrew MacLeod Sept. 23, 2021, 5:36 p.m. UTC
  The routnie that is trapping (relation_fold_and_or)  is looking to see 
if there are any relationships between dependencies that can be 
exploited. ie
    c_2 = a_6 > b_7
    c_3 = a_6 < b_7
    c_4 = c_2 && c_3
   if (c_4 != 0)

when trying to fold c_4,  it looks at c_2 and c_3, it notes that they 
both depend on the same 2 ssa-names,  a_6, and a_7.
It then queries whether there is a relationship between them when c_2 is 
[1,1] and c_3 is [1,1].   If so, it then tries to apply that relation to 
see if the stmt can never be true or not based on that raw relation.  
This allows it to determine the above condition can never be true.

In this case, the 2 defining stmts are both PHI nodes, which happen to 
have the same 2 ssa_names in the dependency list, so it matches the 
pattern being looked for:

   # ntdef_6 = PHI <newdef_10(2), _bfd_elf_merge_symbol_h.0_1(3)>
   # tdef_7 = PHI <_bfd_elf_merge_symbol_h.0_1(2), newdef_10(3)>
   _5 = __tdef_7 & ntdef_6

both names depend on the value of newdef_10 and 
_bfd_elf_merge_symbol_h.0_1, so a check is being made for a relationship 
between op1 and op2 in those stmts.

Whats missing is that we can only check for operand relationships in 
range-ops enabled stmts... The phi will never overtly give us a relation 
between the first and second operand, so no need to check.

Bootstrapped on x86_64-pc-linux-gnu with no regressions.  Pushed.

Andrew
  

Patch

From fe4e6c824a580012bf9034cc33f0b440df93f56f Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Thu, 23 Sep 2021 09:32:00 -0400
Subject: [PATCH 2/2] Look for a relation between operands only when possible.

Do not look for a relation between 2 operands if there is no range-ops handler.

	gcc/
	PR tree-optimization/102463
	* gimple-range-fold.cc (fold_using_range::relation_fold_and_or): If
	there is no range-ops handler, don't look for a relation.

	gcc/testsuite/
	* gcc.dg/pr102463.c: New.
---
 gcc/gimple-range-fold.cc        |  4 ++++
 gcc/testsuite/gcc.dg/pr102463.c | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr102463.c

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 35324fd72c2..bb09b751a4e 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -1358,6 +1358,10 @@  fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
   range_operator *handler1 = gimple_range_handler (SSA_NAME_DEF_STMT (ssa1));
   range_operator *handler2 = gimple_range_handler (SSA_NAME_DEF_STMT (ssa2));
 
+  // If either handler is not present, no relation is found.
+  if (!handler1 || !handler2)
+    return;
+
   int_range<2> bool_one (boolean_true_node, boolean_true_node);
 
   relation_kind relation1 = handler1->op1_op2_relation (bool_one);
diff --git a/gcc/testsuite/gcc.dg/pr102463.c b/gcc/testsuite/gcc.dg/pr102463.c
new file mode 100644
index 00000000000..ca63f0b8767
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr102463.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+_Bool _bfd_elf_merge_symbol_h, _bfd_elf_merge_symbol_h_1;
+_Bool _bfd_elf_merge_symbol_olddef;
+_Bool bfd_is_com_section();
+
+void
+_bfd_elf_merge_symbol() {
+  _Bool newdef = bfd_is_com_section(), ntdef, tdef;
+  _bfd_elf_merge_symbol_olddef = _bfd_elf_merge_symbol_h;
+  if (_bfd_elf_merge_symbol_h_1) {
+    ntdef = newdef;
+    tdef = _bfd_elf_merge_symbol_h;
+  } else {
+    ntdef = _bfd_elf_merge_symbol_h;
+    tdef = newdef;
+  }
+  if (tdef && ntdef)
+    ;
+}
-- 
2.17.2