https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117439

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
There are multiple issues.

One is that we uselessly use the sub_byte_op_p case for empty_ctor_p even if it
starts and ends on byte boundary.  The need for int_mode_for_size (bitlen, 0)
check is native_encode_expr which uses TYPE_MODE, for empty_ctor_p we don't use
it, so for that case all we care about is whether it starts/ends on byte
boundary.

--- gimple-ssa-store-merging.cc.jj1     2024-10-25 10:00:29.467767871 +0200
+++ gimple-ssa-store-merging.cc 2024-11-04 18:40:14.667260621 +0100
@@ -1934,14 +1934,15 @@ encode_tree_to_bitpos (tree expr, unsign
                       unsigned int total_bytes)
 {
   unsigned int first_byte = bitpos / BITS_PER_UNIT;
-  bool sub_byte_op_p = ((bitlen % BITS_PER_UNIT)
-                       || (bitpos % BITS_PER_UNIT)
-                       || !int_mode_for_size (bitlen, 0).exists ());
   bool empty_ctor_p
     = (TREE_CODE (expr) == CONSTRUCTOR
        && CONSTRUCTOR_NELTS (expr) == 0
        && TYPE_SIZE_UNIT (TREE_TYPE (expr))
-                      && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE
(expr))));
+       && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (expr))));
+  bool sub_byte_op_p = ((bitlen % BITS_PER_UNIT)
+                       || (bitpos % BITS_PER_UNIT)
+                       || (!int_mode_for_size (bitlen, 0).exists ()
+                           && !empty_ctor_p));

   if (!sub_byte_op_p)
     {


improves it and fixes the ICE on this testcase (which is caused by XALLOCAVEC
for 64MB or so).

Second case is that
  bool invalid = (base_addr == NULL_TREE
                  || (maybe_gt (bitsize,
                                (unsigned int) MAX_BITSIZE_MODE_ANY_INT)
                      && TREE_CODE (rhs) != INTEGER_CST
                      && (TREE_CODE (rhs) != CONSTRUCTOR
                          || CONSTRUCTOR_NELTS (rhs) != 0)));
doesn't impose any size restrictions on the {} and {CLOBBER} cases.  We don't
really
need to have a limit of MAX_BITSIZE_MODE_ANY_INT for that casewe can handle a
couple of kilobytes just fine, but the code isn't prepared to handle really
huge cases.
E.g. encode_tree_to_bitpos uses int to represent bit size and bit positions or
unsigned int to represent total bytes, also uses XALLOCAVEC (sure, we could use
XNEWVEC, or use both depending on size), plus apply_stores uses XNEWVEC for the
whole buffer.
While the int and unsigned types could be changed to unsigned HOST_WIDE_INT,
similarly clear_bit_region* and dump_char_array etc., building even just 64MB
buffer (perhaps several times) here seems to be a total waste of compile time
and memory.
So, I think instead of the type changes and conditionally using XNEWVEC instead
of XALLOCAVEC we just should put some reasonable upper limit, say 256KB.

Reply via email to