diff options
author | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-06 15:34:45 +0000 |
---|---|---|
committer | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-06 15:34:45 +0000 |
commit | 16a3f6b8532247ff67b23250c5bf588f6138cd07 (patch) | |
tree | a4d32cf8ff61e118247e78a10c552488a93ca876 /gcc/reload.c | |
parent | c6586120c02f926744ae783db4ce6401e0279d9a (diff) | |
download | gcc-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.c | 31 |
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; |