From 9ded9b80c111559ece589197a17d6e7e512dd449 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 31 Oct 2025 13:08:05 +0100 Subject: [PATCH] Make FOR_EACH_IMM_USE_STMT work w/o fake imm use node This is an attempt to fix PR122502 by making a FOR_EACH_IMM_USE_FAST with in an FOR_EACH_IMM_USE_STMT on _the same_ VAR work without the former running into the FOR_EACH_IMM_USE_STMT inserted marker use operand. It does this by getting rid of the marker. The downside is that this in principle restricts the set of operations that can be done on the immediate use list of VAR. Where previously almost anything was OK (but technically not well-defined what happens to the iteration) after this patch you may only remove immediate uses of VAR on the current stmt from the FOR_EACH_IMM_USE_STMT iteration. In particular things will break if you happen to remove the one immediate use of VAR on the stmt immediately following the set of immediate uses on the currrent stmt. Additional checking to combat such cases is implemented in a followup. PR tree-optimization/122502 * ssa-iterators.h (imm_use_iterator::iter_node): Remove. (imm_use_iterator::next_stmt_use): New. (next_readonly_imm_use): Adjust checking code. (end_imm_use_stmt_traverse): Simplify. (link_use_stmts_after): Likewise. Return the last use with the same stmt. (first_imm_use_stmt): Simplify. Set next_stmt_use. (next_imm_use_stmt): Likewise. (end_imm_use_on_stmt_p): Adjust. * gcc.dg/torture/pr122502-2.c: New testcase. --- gcc/ssa-iterators.h | 50 +++++++++-------------- gcc/testsuite/gcc.dg/torture/pr122502-2.c | 23 +++++++++++ 2 files changed, 43 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr122502-2.c diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h index 47220c5ce25..8fcc9b8a55f 100644 --- a/gcc/ssa-iterators.h +++ b/gcc/ssa-iterators.h @@ -53,8 +53,9 @@ struct imm_use_iterator ssa_use_operand_t *imm_use; /* This marks the last use in the list (use node from SSA_NAME) */ ssa_use_operand_t *end_p; - /* This node is inserted and used to mark the end of the uses for a stmt. */ - ssa_use_operand_t iter_node; + /* This is the next ssa_name to visit in an outer FOR_EACH_IMM_USE_STMT. + Also used for fast imm use iterator checking. */ + ssa_use_operand_t *next_stmt_use; /* This is the next ssa_name to visit. IMM_USE may get removed before the next one is traversed to, so it must be cached early. */ ssa_use_operand_t *next_imm_name; @@ -350,7 +351,7 @@ first_readonly_imm_use (imm_use_iterator *imm, tree var) { imm->end_p = &(SSA_NAME_IMM_USE_NODE (var)); imm->imm_use = imm->end_p->next; - imm->iter_node.next = imm->imm_use->next; + imm->next_stmt_use = imm->imm_use->next; if (end_readonly_imm_use_p (imm)) return NULL_USE_OPERAND_P; return imm->imm_use; @@ -368,8 +369,8 @@ next_readonly_imm_use (imm_use_iterator *imm) using the SAFE version of the iterator. */ if (flag_checking) { - gcc_assert (imm->iter_node.next == old->next); - imm->iter_node.next = old->next->next; + gcc_assert (imm->next_stmt_use == old->next); + imm->next_stmt_use = old->next->next; } imm->imm_use = old->next; @@ -845,9 +846,8 @@ end_imm_use_stmt_p (const imm_use_iterator *imm) placeholder node from the list. */ inline void -end_imm_use_stmt_traverse (imm_use_iterator *imm) +end_imm_use_stmt_traverse (imm_use_iterator *) { - delink_imm_use (&(imm->iter_node)); } /* Immediate use traversal of uses within a stmt require that all the @@ -880,10 +880,11 @@ move_use_after_head (use_operand_p use_p, use_operand_p head, /* This routine will relink all uses with the same stmt as HEAD into the list - immediately following HEAD for iterator IMM. */ + immediately following HEAD for iterator IMM and returns the last use on + that stmt. */ -inline void -link_use_stmts_after (use_operand_p head, imm_use_iterator *imm) +inline use_operand_p +link_use_stmts_after (use_operand_p head, imm_use_iterator *) { use_operand_p use_p; use_operand_p last_p = head; @@ -915,10 +916,7 @@ link_use_stmts_after (use_operand_p head, imm_use_iterator *imm) last_p = move_use_after_head (use_p, head, last_p); } } - /* Link iter node in after last_p. */ - if (imm->iter_node.prev != NULL) - delink_imm_use (&imm->iter_node); - link_imm_use_to_list (&(imm->iter_node), last_p); + return last_p; } /* Initialize IMM to traverse over uses of VAR. Return the first statement. */ @@ -929,18 +927,14 @@ first_imm_use_stmt (imm_use_iterator *imm, tree var) imm->imm_use = imm->end_p->next; imm->next_imm_name = NULL_USE_OPERAND_P; - /* iter_node is used as a marker within the immediate use list to indicate - where the end of the current stmt's uses are. Initialize it to NULL - stmt and use, which indicates a marker node. */ - imm->iter_node.prev = NULL_USE_OPERAND_P; - imm->iter_node.next = NULL_USE_OPERAND_P; - imm->iter_node.loc.stmt = NULL; - imm->iter_node.use = NULL; + /* next_stmt_use is used to point to the immediate use node after + the set of uses for the current stmt. */ + imm->next_stmt_use = NULL_USE_OPERAND_P; if (end_imm_use_stmt_p (imm)) return NULL; - link_use_stmts_after (imm->imm_use, imm); + imm->next_stmt_use = link_use_stmts_after (imm->imm_use, imm)->next; return USE_STMT (imm->imm_use); } @@ -950,15 +944,11 @@ first_imm_use_stmt (imm_use_iterator *imm, tree var) inline gimple * next_imm_use_stmt (imm_use_iterator *imm) { - imm->imm_use = imm->iter_node.next; + imm->imm_use = imm->next_stmt_use; if (end_imm_use_stmt_p (imm)) - { - if (imm->iter_node.prev != NULL) - delink_imm_use (&imm->iter_node); - return NULL; - } + return NULL; - link_use_stmts_after (imm->imm_use, imm); + imm->next_stmt_use = link_use_stmts_after (imm->imm_use, imm)->next; return USE_STMT (imm->imm_use); } @@ -977,7 +967,7 @@ first_imm_use_on_stmt (imm_use_iterator *imm) inline bool end_imm_use_on_stmt_p (const imm_use_iterator *imm) { - return (imm->imm_use == &(imm->iter_node)); + return (imm->imm_use == imm->next_stmt_use); } /* Bump to the next use on the stmt IMM refers to, return NULL if done. */ diff --git a/gcc/testsuite/gcc.dg/torture/pr122502-2.c b/gcc/testsuite/gcc.dg/torture/pr122502-2.c new file mode 100644 index 00000000000..36a114d97b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr122502-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +typedef struct { + int mant; + int exp; +} SoftFloat; +SoftFloat __trans_tmp_8, main___trans_tmp_5; +static SoftFloat av_normalize_sf(SoftFloat a) { + while (a.mant + 536870911 < 1073741823) { + a.mant += a.mant; + a.exp -= 1; + } + return a; +} +void main() { + main___trans_tmp_5 = av_normalize_sf((SoftFloat){1, 29 + 1}); + SoftFloat sf1 = main___trans_tmp_5; + for (;;) { + int t = main___trans_tmp_5.exp - sf1.exp; + if (t < 2) + sf1 = __trans_tmp_8; + } +} -- 2.47.3