Hello, This seems to be causing a build regression on the or1k port.
I have not quite figured it out yet but I have bisected to this commit. The failure is as below, this seems to be caused by the cstoresi4 instruction produced by or1k.md. So I think its likely something we are doing funny in the port. Thanks to Jeff for pointing this out. If you have any idea let me know. Log: during RTL pass: ce1 dump file: libgcc2.c.286r.ce1 /home/shorne/work/gnu-toolchain/gcc/libgcc/libgcc2.c: In function '__muldi3': /home/shorne/work/gnu-toolchain/gcc/libgcc/libgcc2.c:538:1: internal compiler error: in emit_move_multi_word, at expr.cc:4492 538 | } | ^ 0x1b094df internal_error(char const*, ...) /home/shorne/work/gnu-toolchain/gcc/gcc/diagnostic-global-context.cc:517 0x6459c1 fancy_abort(char const*, int, char const*) /home/shorne/work/gnu-toolchain/gcc/gcc/diagnostic.cc:1815 0x473a2e emit_move_multi_word /home/shorne/work/gnu-toolchain/gcc/gcc/expr.cc:4492 0x93fd7d emit_move_insn(rtx_def*, rtx_def*) /home/shorne/work/gnu-toolchain/gcc/gcc/expr.cc:4746 0x9175f1 copy_to_reg(rtx_def*) /home/shorne/work/gnu-toolchain/gcc/gcc/explow.cc:630 0xd18977 gen_lowpart_general(machine_mode, rtx_def*) /home/shorne/work/gnu-toolchain/gcc/gcc/rtlhooks.cc:56 0x9414c7 convert_mode_scalar /home/shorne/work/gnu-toolchain/gcc/gcc/expr.cc:818 0x9421a1 convert_modes(machine_mode, machine_mode, rtx_def*, int) /home/shorne/work/gnu-toolchain/gcc/gcc/expr.cc:961 0xc0afa0 prepare_operand(insn_code, rtx_def*, int, machine_mode, machine_mode, int) /home/shorne/work/gnu-toolchain/gcc/gcc/optabs.cc:4637 0xc0b33a prepare_cmp_insn /home/shorne/work/gnu-toolchain/gcc/gcc/optabs.cc:4538 0xc0f0dd emit_conditional_move(rtx_def*, rtx_comparison, rtx_def*, rtx_def*, machine_mode, int) /home/shorne/work/gnu-toolchain/gcc/gcc/optabs.cc:5098 0x192cc7b noce_emit_cmove /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:1777 0x193365b try_emit_cmove_seq /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:3410 0x193365b noce_convert_multiple_sets_1 /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:3705 0x1933c71 noce_convert_multiple_sets /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:3496 0x1938687 noce_process_if_block /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:4045 0x1938687 noce_find_if_block /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:4726 0x1938687 find_if_header /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:4931 0x1938687 if_convert /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:6078 0x1938d01 rest_of_handle_if_conversion /home/shorne/work/gnu-toolchain/gcc/gcc/ifcvt.cc:6143 -Stafford On Thu, May 15, 2025 at 10:33:49PM +0300, Dimitar Dimitrov wrote: > When a paradoxical subreg is detected, validate_subreg exits early, thus > skipping the important checks later in the function. > > Fix by continuing with the checks instead of declaring early that the > paradoxical subreg is valid. > > One of the newly allowed subsequent checks needed to be disabled for > paradoxical subregs. It turned out that combine attempts to create > a paradoxical subreg of mem even for strict-alignment targets. > That is invalid and should eventually be rejected, but is > temporarily left allowed to prevent regressions for > armv8l-unknown-linux-gnueabihf. > > Tests I did: > - No regressions were found for C and C++ for the following targets: > - native x86_64-pc-linux-gnu > - cross riscv64-unknown-linux-gnu > - cross riscv32-none-elf > - Sanity checked armv8l-unknown-linux-gnueabihf by cross-building > up to including libgcc. I'll monitor Linaro CI bot for the > full regression test results. > - Sanity checked powerpc64-unknown-linux-gnu by building native > toolchain, but could not setup qemu-user for DejaGnu testing. > > PR target/119966 > > gcc/ChangeLog: > > * emit-rtl.cc (validate_subreg): Do not exit immediately for > paradoxical subregs. Filter subsequent tests which are > not valid for paradoxical subregs. > > Co-authored-by: Richard Sandiford <richard.sandif...@arm.com> > Signed-off-by: Dimitar Dimitrov <dimi...@dinux.eu> > --- > gcc/emit-rtl.cc | 25 ++++++++++++++++++------- > 1 file changed, 18 insertions(+), 7 deletions(-) > > diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc > index 3e2c4309dee..e46b0f9eac4 100644 > --- a/gcc/emit-rtl.cc > +++ b/gcc/emit-rtl.cc > @@ -969,10 +969,10 @@ validate_subreg (machine_mode omode, machine_mode imode, > } > > /* Paradoxical subregs must have offset zero. */ > - if (maybe_gt (osize, isize)) > - return known_eq (offset, 0U); > + if (maybe_gt (osize, isize) && !known_eq (offset, 0U)) > + return false; > > - /* This is a normal subreg. Verify that the offset is representable. */ > + /* Verify that the offset is representable. */ > > /* For hard registers, we already have most of these rules collected in > subreg_offset_representable_p. */ > @@ -988,9 +988,13 @@ validate_subreg (machine_mode omode, machine_mode imode, > > return subreg_offset_representable_p (regno, imode, offset, omode); > } > - /* Do not allow SUBREG with stricter alignment than the inner MEM. */ > + /* Do not allow normal SUBREG with stricter alignment than the inner MEM. > + > + FIXME: Combine can create paradoxical mem subregs even for > + strict-alignment targets. Allow it until combine is fixed. */ > else if (reg && MEM_P (reg) && STRICT_ALIGNMENT > - && MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (omode)) > + && MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (omode) > + && known_le (osize, isize)) > return false; > > /* The outer size must be ordered wrt the register size, otherwise > @@ -999,7 +1003,7 @@ validate_subreg (machine_mode omode, machine_mode imode, > if (!ordered_p (osize, regsize)) > return false; > > - /* For pseudo registers, we want most of the same checks. Namely: > + /* For normal pseudo registers, we want most of the same checks. Namely: > > Assume that the pseudo register will be allocated to hard registers > that can hold REGSIZE bytes each. If OSIZE is not a multiple of > REGSIZE, > @@ -1008,8 +1012,15 @@ validate_subreg (machine_mode omode, machine_mode > imode, > otherwise it is at the lowest offset. > > Given that we've already checked the mode and offset alignment, > - we only have to check subblock subregs here. */ > + we only have to check subblock subregs here. > + > + For paradoxical little-endian registers, this check is redundant. The > + offset has already been validated to be zero. > + > + For paradoxical big-endian registers, this check is not valid > + because the offset is zero. */ > if (maybe_lt (osize, regsize) > + && known_le (osize, isize) > && ! (lra_in_progress && (FLOAT_MODE_P (imode) || FLOAT_MODE_P > (omode)))) > { > /* It is invalid for the target to pick a register size for a mode > -- > 2.49.0 >