diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2013-11-20 13:55:04 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2013-11-20 13:55:04 +0000 |
commit | c34fb198320a6a433f5ad4c10b9d0c7e6f280e28 (patch) | |
tree | 5f5a0d090f1d60fe5038e9ff9ccdc5083ce8b87f /gcc/regcprop.c | |
parent | eb1d81598d4b4413ec5fe730036c16202afad6b6 (diff) | |
download | gcc-c34fb198320a6a433f5ad4c10b9d0c7e6f280e28.zip gcc-c34fb198320a6a433f5ad4c10b9d0c7e6f280e28.tar.gz gcc-c34fb198320a6a433f5ad4c10b9d0c7e6f280e28.tar.bz2 |
re PR rtl-optimization/54300 (regcprop incorrectly looks through parallel register swap operation)
PR rtl-optimization/54300
gcc/
PR rtl-optimization/54300
* regcprop.c (copyprop_hardreg_forward_1): Ensure any unused
outputs in a single-set are killed from the value chains.
gcc/testsuite:
PR rtl-optimization/54300
* gcc.target/arm/pr54300.C: New test.
From-SVN: r205117
Diffstat (limited to 'gcc/regcprop.c')
-rw-r--r-- | gcc/regcprop.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 0fa0afb..9b52a63 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -747,6 +747,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) int n_ops, i, alt, predicated; bool is_asm, any_replacements; rtx set; + rtx link; bool replaced[MAX_RECOG_OPERANDS]; bool changed = false; struct kill_set_value_data ksvd; @@ -815,6 +816,23 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) if (recog_op_alt[i][alt].earlyclobber) kill_value (recog_data.operand[i], vd); + /* If we have dead sets in the insn, then we need to note these as we + would clobbers. */ + for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) + { + if (REG_NOTE_KIND (link) == REG_UNUSED) + { + kill_value (XEXP (link, 0), vd); + /* Furthermore, if the insn looked like a single-set, + but the dead store kills the source value of that + set, then we can no-longer use the plain move + special case below. */ + if (set + && reg_overlap_mentioned_p (XEXP (link, 0), SET_SRC (set))) + set = NULL; + } + } + /* Special-case plain move instructions, since we may well be able to do the move from a different register class. */ if (set && REG_P (SET_SRC (set))) |