summaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authormatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-06 15:34:45 +0000
committermatz <matz@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-06 15:34:45 +0000
commit16a3f6b8532247ff67b23250c5bf588f6138cd07 (patch)
treea4d32cf8ff61e118247e78a10c552488a93ca876 /gcc/reload.c
parentc6586120c02f926744ae783db4ce6401e0279d9a (diff)
downloadgcc-16a3f6b8532247ff67b23250c5bf588f6138cd07.tar.gz
PR target/36613
* reload.c (push_reload): Merge in,out,in_reg,out_reg members for reused reload, instead of overwriting them. * gcc.target/i386/pr36613.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138807 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 93fff404569..5a79c44e874 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1403,13 +1403,36 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
else
remove_address_replacements (rld[i].in);
}
- rld[i].in = in;
- rld[i].in_reg = in_reg;
+ /* When emitting reloads we don't necessarily look at the in-
+ and outmode, but also directly at the operands (in and out).
+ So we can't simply overwrite them with whatever we have found
+ for this (to-be-merged) reload, we have to "merge" that too.
+ Reusing another reload already verified that we deal with the
+ same operands, just possibly in different modes. So we
+ overwrite the operands only when the new mode is larger.
+ See also PR33613. */
+ if (!rld[i].in
+ || GET_MODE_SIZE (GET_MODE (in))
+ > GET_MODE_SIZE (GET_MODE (rld[i].in)))
+ rld[i].in = in;
+ if (!rld[i].in_reg
+ || (in_reg
+ && GET_MODE_SIZE (GET_MODE (in_reg))
+ > GET_MODE_SIZE (GET_MODE (rld[i].in_reg))))
+ rld[i].in_reg = in_reg;
}
if (out != 0)
{
- rld[i].out = out;
- rld[i].out_reg = outloc ? *outloc : 0;
+ if (!rld[i].out
+ || (out
+ && GET_MODE_SIZE (GET_MODE (out))
+ > GET_MODE_SIZE (GET_MODE (rld[i].out))))
+ rld[i].out = out;
+ if (outloc
+ && (!rld[i].out_reg
+ || GET_MODE_SIZE (GET_MODE (*outloc))
+ > GET_MODE_SIZE (GET_MODE (rld[i].out_reg))))
+ rld[i].out_reg = *outloc;
}
if (reg_class_subset_p (rclass, rld[i].rclass))
rld[i].rclass = rclass;