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
This commit is contained in:
Michael Matz 2008-08-06 15:34:45 +00:00 committed by Michael Matz
parent e94a448f66
commit 46662f25ea
4 changed files with 82 additions and 4 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}