https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78041
--- Comment #4 from Wilco <wdijkstr at arm dot com> --- (In reply to Bernd Edlinger from comment #3) > (In reply to Wilco from comment #2) > > (In reply to Bernd Edlinger from comment #1) > > > some background about this bug can be found here: > > > > > > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg01561.html > > > > The <shift>di3_neon pattern does not constrain the input not to overlap with > > the output for immediate shifts, and the arm_emit_coreregs_64bit_shift code > > does not handle partial overlaps. However it is feasible to fix that by > > swapping the order for the various cases. > > from <shift>di3_neon: > > if (INTVAL (operands[2]) < 1) > { > emit_insn (gen_movdi (operands[0], operands[1])); > DONE; > } > > Will the movdi pattern work with partial overlaps? > It does basically this: > > emit_move_insn (gen_lowpart (SImode, operands[0]), > gen_lowpart (SImode, operands[1])); > emit_move_insn (gen_highpart (SImode, operands[0]), > gen_highpart (SImode, operands[1])); I think it's OK - that code only triggers if a movdi has a physical register that is not a valid DI register which is not the case we're dealing with. movdi has a split that does check for partial overlap around line 5900 in arm.md: /* Handle a partial overlap. */ if (rtx_equal_p (operands[0], operands[3])) ... However dealing with partial overlaps is complex so maybe the best option would be to add alternatives to <shift>di3_neon to either allow full overlap "r 0 X X X" or no overlap "&r r X X X". The shift code works with full overlap.