ext-dce had: if (SUBREG_P (dst) && SUBREG_BYTE (dst).is_constant ()) { bit = subreg_lsb (dst).to_constant (); if (bit >= HOST_BITS_PER_WIDE_INT) bit = HOST_BITS_PER_WIDE_INT - 1; dst = SUBREG_REG (dst);
But a constant SUBREG_BYTE doesn't guarantee a constant subreg_lsb. If the SUBREG_REG is a pair of N-bit registers on a big-endian target, the most significant end has a SUBREG_BYTE of 0 but a subreg_lsb of N. This N would then be non-constant for variable-length registers. The patch fixes gcc.dg/torture/pr120276.c and other failures on aarch64_be-elf. Tested on aarch64-linux-gnu & aarch64_be-elf. OK to install? Richard gcc/ * ext-dce.cc (ext_dce_process_uses): Apply is_constant directly to the subreg_lsb. --- gcc/ext-dce.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc index afe7afe21fd..e7635fb7a39 100644 --- a/gcc/ext-dce.cc +++ b/gcc/ext-dce.cc @@ -651,9 +651,8 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, /* ?!? How much of this should mirror SET handling, potentially being shared? */ - if (SUBREG_P (dst) && SUBREG_BYTE (dst).is_constant ()) + if (SUBREG_P (dst) && subreg_lsb (dst).is_constant (&bit)) { - bit = subreg_lsb (dst).to_constant (); if (bit >= HOST_BITS_PER_WIDE_INT) bit = HOST_BITS_PER_WIDE_INT - 1; dst = SUBREG_REG (dst); -- 2.43.0