https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106101
--- Comment #10 from Andreas Krebbel <krebbel at gcc dot gnu.org> --- We generate the movstrict target operand with gen_lowpart. If the operand for gen_lowpart is already a paradoxical subreg the two subregs cancel each other out and we end up with a plain reg. I'm testing the following patch right now. It falls back to a normal move in that case and fixes the testcase: diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 5aaf76a9490..d90ec1a6de1 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -6523,6 +6523,14 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) rtx low_dest = gen_lowpart (smode, dest); rtx low_src = gen_lowpart (smode, src); + /* In case two subregs cancelled each other out, do a normal + move. */ + if (!SUBREG_P (low_dest)) + { + emit_move_insn (low_dest, low_src); + return true; + } + switch (smode) { case E_QImode: emit_insn (gen_movstrictqi (low_dest, low_src)); return true;