aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-01-31 10:03:06 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2018-01-31 10:03:06 +0000
commitae20d760b1ed69f631c3bf9351bf7e5005d52297 (patch)
tree74ff7d61b777917ffbe16c5ebde09800a71ae57b /gcc/combine.c
parentb6fb257bd6fe6a4d03937a8c3cee6ff4dfa1002a (diff)
downloadgcc-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.c17
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);
}