[COMMITTED] PR tree-optimization/126845 - Add new relation before starting search
Andrew MacLeod <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Whena new relation is registered on a statement, the oracle does a dom search of relations reaching this block to potentially combine with this new relation. During this dom search, it also attempts to recompute relations involving the same 2 ssa-names on outgoing edges to see if we know something new on this path. This require calculating ranges, and can result in other updates before returning. Turns out there are edge cases where the check if there is a relation in the current block return false, and then the dom query does some calculations and requires some values from a back edge which trigger creating this same relation... then when we try to create the relation in this block, itt riggers the new assert that there is no relation in the block. This was masked previously, so didnt realize it was there. This patch removes that gap by creating the relation immeidately, then making the dom query and if it comes back with a value, we intersect it into the object that was created. Bootstrapped on x86_64-pc-linux-gnu with no regressions. pushed. Andrew
0004-Add-new-relation-before-starting-search.patch
(text/x-patch, 3.2 KB)
From e11bad1900aa9afd6efe8292abd38656748123eb Mon Sep 17 00:00:00 2001 From: Andrew MacLeod <[email protected]> Date: Thu, 13 Aug 2026 13:44:09 -0400 Subject: [PATCH 4/4] Add new relation before starting search Create a new relation immediately. Then Calculate any known range and intersect the result. PR tree-optimization/126845 gcc/ * value-relation.cc (dom_oracle::search_and_merge_relation): Create relation immediately and update it later. gcc/testsuite/ * gcc.dg/pr126845.c: New. --- gcc/testsuite/gcc.dg/pr126845.c | 19 +++++++++++++++++++ gcc/value-relation.cc | 27 ++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr126845.c diff --git a/gcc/testsuite/gcc.dg/pr126845.c b/gcc/testsuite/gcc.dg/pr126845.c new file mode 100644 index 00000000000..0ae91d9a773 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr126845.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-move-loop-stores" } */ + +int a, c, d, e, **f, *g, h; +static int i() {} +void j() { + do { + f = &g; + c = 1 + (1 >> a); + if (2 + c >= c - a) + goto k; + g = &c; + } while (i()); + c = a + c + c; +k: + e = **f; + for (int b = 0; b < 3; b++) + h = d = d ^ e; +} diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 04e9cc19843..cc9e8e56c67 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -1241,22 +1241,22 @@ dom_oracle::search_and_merge_relation (basic_block bb, relation_kind k, { gcc_checking_assert (k != VREL_VARYING && k != VREL_EQ); - int bbi = bb->index; - - relation_kind curr; relation_chain *ptr; - curr = find_relation_block (bbi, op1, op2, &ptr); - // There is an existing relation in this block, just intersect with it. + relation_kind curr = find_relation_block (bb->index, op1, op2, &ptr); + + // If there is an existing relation in this block, just intersect with it. if (curr != VREL_VARYING) { - // Check into whether we can simply replace the relation rather than - // intersecting it. This may help with some optimistic iterative - // updating algorithms. If there was no change, return no record.. + // If there was no change, return no record. value_relation vr (k, op1, op2); if (!ptr->intersect (vr)) return NULL; + return ptr; } - else + + // Create the relation in this block. + ptr = create_relation_in_bb (bb, k, op1, op2); + if (ptr) { // Check for an existing relation further up the DOM chain. // By including dominating relations, The first one found in any search @@ -1264,8 +1264,13 @@ dom_oracle::search_and_merge_relation (basic_block bb, relation_kind k, curr = find_relation_dom (get_immediate_dominator (CDI_DOMINATORS, bb), op1, op2); if (curr != VREL_VARYING) - k = relation_intersect (curr, k); - ptr = create_relation_in_bb (bb, k, op1, op2); + { + curr = relation_intersect (curr, k); + // Intersect the new relation with the existing one, unless the + // result is UNDEFINED. Then just leave it. + if (curr != k && curr != VREL_UNDEFINED) + ptr->set_relation (curr, op1, op2); + } } return ptr; } -- 2.45.0