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
>From fe4e6c824a580012bf9034cc33f0b440df93f56f Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@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