diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2018-01-31 10:03:06 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-01-31 10:03:06 +0000 |
commit | ae20d760b1ed69f631c3bf9351bf7e5005d52297 (patch) | |
tree | 74ff7d61b777917ffbe16c5ebde09800a71ae57b /gcc/combine.c | |
parent | b6fb257bd6fe6a4d03937a8c3cee6ff4dfa1002a (diff) | |
download | gcc-ae20d760b1ed69f631c3bf9351bf7e5005d52297.zip gcc-ae20d760b1ed69f631c3bf9351bf7e5005d52297.tar.gz gcc-ae20d760b1ed69f631c3bf9351bf7e5005d52297.tar.bz2 |
re PR rtl-optimization/84071 (wrong elimination of zero-extension after sign-extended load)
PR rtl-optimization/84071
* combine.c (record_dead_and_set_regs_1): Record the source unmodified
for a paradoxical SUBREG on a WORD_REGISTER_OPERATIONS target.
From-SVN: r257224
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 6adc0a7..b14b248 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13245,18 +13245,25 @@ record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data) if (REG_P (dest)) { /* If we are setting the whole register, we know its value. Otherwise - show that we don't know the value. We can handle SUBREG in - some cases. */ + show that we don't know the value. We can handle a SUBREG if it's + the low part, but we must be careful with paradoxical SUBREGs on + RISC architectures because we cannot strip e.g. an extension around + a load and record the naked load since the RTL middle-end considers + that the upper bits are defined according to LOAD_EXTEND_OP. */ if (GET_CODE (setter) == SET && dest == SET_DEST (setter)) record_value_for_reg (dest, record_dead_insn, SET_SRC (setter)); else if (GET_CODE (setter) == SET && GET_CODE (SET_DEST (setter)) == SUBREG && SUBREG_REG (SET_DEST (setter)) == dest - && known_le (GET_MODE_PRECISION (GET_MODE (dest)), BITS_PER_WORD) + && known_le (GET_MODE_PRECISION (GET_MODE (dest)), + BITS_PER_WORD) && subreg_lowpart_p (SET_DEST (setter))) record_value_for_reg (dest, record_dead_insn, - gen_lowpart (GET_MODE (dest), - SET_SRC (setter))); + WORD_REGISTER_OPERATIONS + && paradoxical_subreg_p (SET_DEST (setter)) + ? SET_SRC (setter) + : gen_lowpart (GET_MODE (dest), + SET_SRC (setter))); else record_value_for_reg (dest, record_dead_insn, NULL_RTX); } |