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:
parent
e94a448f66
commit
46662f25ea
4 changed files with 82 additions and 4 deletions
|
@ -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
|
||||
|
|
31
gcc/reload.c
31
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;
|
||||
|
|
|
@ -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
|
||||
|
|
44
gcc/testsuite/gcc.target/i386/pr36613.c
Normal file
44
gcc/testsuite/gcc.target/i386/pr36613.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue