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.