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 | |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/reload.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr36613.c | 44 |
4 files changed, 82 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a22491f..a08bd6e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-08-06 Michael Matz <matz@suse.de> + + PR target/36613 + * reload.c (push_reload): Merge in,out,in_reg,out_reg members + for reused reload, instead of overwriting them. + 2008-08-06 H.J. Lu <hongjiu.lu@intel.com> PR middle-end/37009 diff --git a/gcc/reload.c b/gcc/reload.c index 93fff404..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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ead9638..d5b229a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-08-06 Michael Matz <matz@suse.de> + + PR target/36613 + * gcc.target/i386/pr36613.c: New testcase. + 2008-08-06 H.J. Lu <hongjiu.lu@intel.com> PR middle-end/37009 diff --git a/gcc/testsuite/gcc.target/i386/pr36613.c b/gcc/testsuite/gcc.target/i386/pr36613.c new file mode 100644 index 0000000..e9d7d11 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr36613.c @@ -0,0 +1,44 @@ +/* { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && ilp32 } } } */ +/* { dg-options "-Os" } */ +/* PR target/36613 */ + +extern void abort (void); + +static inline int +lshifts (int val, int cnt) +{ + if (val < 0) + return val; + return val << cnt; +} + +static inline unsigned int +lshiftu (unsigned int val, unsigned int cnt) +{ + if (cnt >= sizeof (unsigned int) * __CHAR_BIT__ + || val > ((__INT_MAX__ * 2U) >> cnt)) + return val; + return val << cnt; +} + +static inline int +rshifts (int val, unsigned int cnt) +{ + if (val < 0 || cnt >= sizeof (int) * __CHAR_BIT__) + return val; + return val >> cnt; +} + +int +foo (unsigned int val) +{ + return rshifts (1 + val, lshifts (lshiftu (val, val), 1)); +} + +int +main (void) +{ + if (foo (1) != 0) + abort (); + return 0; +} |