https://gcc.gnu.org/g:80f13430350276a8c932d068c971cc00d5e43b78

commit r14-10771-g80f13430350276a8c932d068c971cc00d5e43b78
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Oct 1 09:52:20 2024 +0200

    range-cache: Fix ranger ICE if number of bbs increases [PR116899]
    
    Ranger cache during initialization reserves number of basic block slots
    in the m_workback vector (in an inefficient way by doing create (0)
    and safe_grow_cleared (n) and truncate (0) rather than say create (n)
    or reserve (n) after create).  The problem is that some passes split bbs 
and/or
    create new basic blocks and so when one is unlucky, the quick_push into that
    vector can ICE.
    
    The following patch replaces those 4 quick_push calls with safe_push.
    
    I've also gathered some statistics from compiling 63 gcc sources (picked 
those
    that dependent on gimple-range-cache.h just because I had to rebuild them 
once
    for the instrumentation), and that showed that in 81% of cases nothing has
    been pushed into the vector at all (and note, not everything was small, 
there
    were even cases with 10000+ basic blocks), another 18.5% of cases had just 
1-4
    elements in the vector at most, 0.08% had 5-8 and 19 out of 305386 cases
    had at most 9-11 elements, nothing more.  So, IMHO reserving number of basic
    block in the vector is a waste of compile time memory and with the safe_push
    calls, the patch just initializes the vector to vNULL.
    
    2024-10-01  Jakub Jelinek  <ja...@redhat.com>
    
            PR middle-end/116899
            * gimple-range-cache.cc (ranger_cache::ranger_cache): Set m_workback
            to vNULL instead of creating it, growing and then truncating.
            (ranger_cache::fill_block_cache): Use safe_push rather than 
quick_push
            on m_workback.
            (ranger_cache::range_from_dom): Likewise.
    
            * gcc.dg/bitint-111.c: New test.
    
    (cherry picked from commit de25f1729d212c11d6e2955130f4eb1d272b5ce7)

Diff:
---
 gcc/gimple-range-cache.cc         | 12 +++++-------
 gcc/testsuite/gcc.dg/bitint-111.c | 16 ++++++++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 0a5754139308..73fc178b30c9 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -953,9 +953,7 @@ ranger_cache::ranger_cache (int not_executable_flag, bool 
use_imm_uses)
                                                : m_gori (not_executable_flag),
                                                  m_exit (use_imm_uses)
 {
-  m_workback.create (0);
-  m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun));
-  m_workback.truncate (0);
+  m_workback = vNULL;
   m_temporal = new temporal_cache;
   // If DOM info is available, spawn an oracle as well.
   if (dom_info_available_p (CDI_DOMINATORS))
@@ -1510,7 +1508,7 @@ ranger_cache::fill_block_cache (tree name, basic_block 
bb, basic_block def_bb)
   // Visit each block back to the DEF.  Initialize each one to UNDEFINED.
   // m_visited at the end will contain all the blocks that we needed to set
   // the range_on_entry cache for.
-  m_workback.quick_push (bb);
+  m_workback.safe_push (bb);
   undefined.set_undefined ();
   m_on_entry.set_bb_range (name, bb, undefined);
   gcc_checking_assert (m_update->empty_p ());
@@ -1584,7 +1582,7 @@ ranger_cache::fill_block_cache (tree name, basic_block 
bb, basic_block def_bb)
          // the list.
          gcc_checking_assert (!m_on_entry.bb_range_p (name, pred));
          m_on_entry.set_bb_range (name, pred, undefined);
-         m_workback.quick_push (pred);
+         m_workback.safe_push (pred);
        }
     }
 
@@ -1679,7 +1677,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, 
basic_block start_bb,
 
       // This block has an outgoing range.
       if (m_gori.has_edge_range_p (name, bb))
-       m_workback.quick_push (prev_bb);
+       m_workback.safe_push (prev_bb);
       else
        {
          // Normally join blocks don't carry any new range information on
@@ -1703,7 +1701,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, 
basic_block start_bb,
                    break;
                  }
              if (all_dom)
-               m_workback.quick_push (prev_bb);
+               m_workback.safe_push (prev_bb);
            }
        }
 
diff --git a/gcc/testsuite/gcc.dg/bitint-111.c 
b/gcc/testsuite/gcc.dg/bitint-111.c
new file mode 100644
index 000000000000..3cc23684c844
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-111.c
@@ -0,0 +1,16 @@
+/* PR middle-end/116899 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O2" } */
+
+float f;
+_BitInt(255) b;
+
+void
+foo (signed char c)
+{
+  for (;;)
+    {
+      c %= (unsigned _BitInt(512)) 0;  /* { dg-warning "division by zero" } */
+      f /= b >= c;
+    }
+}

Reply via email to