]> git.ipfire.org Git - thirdparty/gcc.git/commit
s390: Fix strict_low_part generation
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Thu, 12 Sep 2024 11:29:43 +0000 (13:29 +0200)
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Thu, 12 Sep 2024 11:29:43 +0000 (13:29 +0200)
commit9ebc9fbdddfe1ec85355b068354315a4da8e1ca0
tree19d081cac5444933f4c8dc48d22cf31af39bf6af
parent412c156d78c764d4aec3e94469ba5a4c068cee4c
s390: Fix strict_low_part generation

In s390_expand_insv(), if generating code for ICM et al. src is a MEM
and gen_lowpart might force src into a register such that we end up with
patterns which do not match anymore.  Use adjust_address() instead in
order to preserve a MEM.

Furthermore, it is not straight forward to enforce a subreg.  For
example, in case of a paradoxical subreg, gen_lowpart() may return a
register.  In order to compensate this, s390_gen_lowpart_subreg() emits
a reference to a pseudo which does not coincide with its definition
which is wrong.  Additionally, if dest is a paradoxical subreg, then do
not try to emit a strict_low_part since it could mean that dest was not
initialized even though this might be fixed up later by init-regs.

Splitter for insn *get_tp_64, *zero_extendhisi2_31,
*zero_extendqisi2_31, *zero_extendqihi2_31 are applied after reload.
Thus, operands[0] is a hard register and gen_lowpart (m, operands[0])
just returns the hard register for mode m which is fine to use as an
argument for strict_low_part, i.e., we do not need to enforce subregs
here since after reload subregs are supposed to be eliminated anyway.

This fixes gcc.dg/torture/pr111821.c.

gcc/ChangeLog:

* config/s390/s390-protos.h (s390_gen_lowpart_subreg): Remove.
* config/s390/s390.cc (s390_gen_lowpart_subreg): Remove.
(s390_expand_insv): Use adjust_address() and emit a
strict_low_part only in case of a natural subreg.
* config/s390/s390.md: Use gen_lowpart() instead of
s390_gen_lowpart_subreg().
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.cc
gcc/config/s390/s390.md