diff options
author | Michael Matz <matz@suse.de> | 2008-08-06 15:34:45 +0000 |
---|---|---|
committer | Michael Matz <matz@gcc.gnu.org> | 2008-08-06 15:34:45 +0000 |
commit | 46662f25ea011aa367beab9b6dd6276a47c4e48a (patch) | |
tree | a4d32cf8ff61e118247e78a10c552488a93ca876 /gcc/reload.c | |
parent | e94a448f66945080611074fc7859bea46e6fc688 (diff) | |
download | gcc-46662f25ea011aa367beab9b6dd6276a47c4e48a.zip gcc-46662f25ea011aa367beab9b6dd6276a47c4e48a.tar.gz gcc-46662f25ea011aa367beab9b6dd6276a47c4e48a.tar.bz2 |
re PR target/36613 (likely codegen bug)
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.
From-SVN: r138807
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 93fff40..5a79c44 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; |