aboutsummaryrefslogtreecommitdiff
path: root/gcc/regcprop.c
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2013-11-20 13:55:04 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2013-11-20 13:55:04 +0000
commitc34fb198320a6a433f5ad4c10b9d0c7e6f280e28 (patch)
tree5f5a0d090f1d60fe5038e9ff9ccdc5083ce8b87f /gcc/regcprop.c
parenteb1d81598d4b4413ec5fe730036c16202afad6b6 (diff)
downloadgcc-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.c18
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)))