During the base register initialization, when we are eliminating the load instruction, we were calling `emit_move_insn` on registers of the same size but of different mode in some cases, causing an ICE.
We update the base register initialization to use `lowpart_subreg` instead of zero-extending the register's value, as the zero-extension was wrong in the first place. There was an underlying issue, caused by having multiple stores in the sequence with the same offset as the load. We fix this by removing stores that contribute nothing and are followed by later ones that overwrite the values that they have written. We use a bitmap to keep track of the bytes that each store writes to. In order to simplify this process we are updating sbitmap with a function that checks if all the bits in a range of the bitmap are set (similar to `bitmap_bit_in_range_p` which checks for any byte in a range) and use this to check if all the bytes that a store writes to have already been written (the store sequence is reversed at that stage, starting from the stores that are closer to the load instruction). Changes in v3: - Remove redundant stores, instead of generating a register move for the first store that has the same offset as the load only. Changes in v2: - Use `lowpart_subreg` for the base register initialization, but only for the first store that has the same offset as the load. Changes in v1: - Add a check for the register modes to match before calling `emit_mov_insn`. Konstantinos Eleftheriou (3): sbitmap: Add bitmap_bit_in_range_p_1 helper function sbitmap: Add bitmap_is_range_set_p function asf: Fix calling of emit_move_insn on registers of different modes [PR119884] gcc/avoid-store-forwarding.cc | 45 ++++++++++++++++++------ gcc/sbitmap.cc | 35 ++++++++++++++---- gcc/sbitmap.h | 1 + gcc/testsuite/gcc.target/i386/pr119884.c | 13 +++++++ 4 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr119884.c -- 2.49.0