[Bug c/32327] New: Incorrect stack sharing causing removal of live code
dnovillo at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Wed Jun 13 19:57:00 GMT 2007
Given the following code:
------------------------------------------------------------------------------
typedef unsigned int size_t;
typedef unsigned long long uint64;
extern "C" {
extern void *memcpy (void *__restrict __dest,
__const void *__restrict __src, size_t __n) /*throw ()*/;
}
extern void foo (void* p);
inline uint64
ghtonll(uint64 x)
{
// __r is allocated the same stack slot as dest below
union { unsigned long long int __ll;
unsigned long int __l[2]; } __w, __r;
__w.__ll = x;
__r.__l[0] = (
{
register unsigned int __v;
__asm__ __volatile__ ("bswap %0" : "=r" (__v) :
"0" ((unsigned int) (__w.__l[1])));
__v; });
__r.__l[1] = (
{
register unsigned int __v;
__asm__ __volatile__ ("bswap %0" : "=r" (__v) :
"0" ((unsigned int) (__w.__l[0])));
__v; });
return __r.__ll;
}
inline uint64
double_2_uint64 (const double *source)
{
uint64 dest; // allocated the same stack slot as __r above
memcpy(&dest, source, sizeof(dest));
return dest;
}
inline void
KeyFromUint64(uint64 fp) {
uint64 norder;
norder = ghtonll (fp);
foo((char*)(&norder));
}
void
KeyFromDouble(double x) {
uint64 n = double_2_uint64 (&x);
if (n >= 42) {
n += 1;
}
KeyFromUint64(n);
}
---
Here is what gcc -O2 -fdump-tree-all (version 4.2) in at the end of the tree
passes.
Please take note of the assignment to dest after that of norder.
;; Function void KeyFromDouble(double) (_Z13KeyFromDoubled)
void KeyFromDouble(double) (x)
{
uint64 n.50;
char * norder.2;
uint64 norder;
register unsigned int __v;
register unsigned int __v;
union ._0 __r;
union ._0 __w;
uint64 dest;
uint64 n;
<bb 2>:
n.50 = VIEW_CONVERT_EXPR<uint64>(x);
if (n.50 > 41) goto <L0>; else goto <L5>;
<L5>:;
n = n.50;
goto <bb 5> (<L1>);
<L0>:;
n = n.50 + 1;
<L1>:;
__w.__ll = n;
__asm__ __volatile__("bswap %0":"=r" __v:"0" __w.__l[1]);
__r.__l[0] = __v;
__asm__ __volatile__("bswap %0":"=r" __v:"0" __w.__l[0]);
__r.__l[1] = __v;
norder = __r.__ll;
norder.2 = (char *) &norder;
dest = n.50;
foo (norder.2);
return;
}
----
Here is part of the RTL expansion:
(insn 45 43 47 9 (set (mem/c/i:DI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -8 [0xfffffff8])) [3 norder+0 S8 A32])
(reg/v:DI 64 [ __r ])) -1 (nil)
(nil))
(insn 47 45 49 9 (parallel [
(set (reg:SI 59 [ norder.2 ])
(plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -8 [0xfffffff8])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 49 47 51 9 (set (mem/c/i:DI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -8 [0xfffffff8])) [3 dest+0 S8 A32])
(reg/v:DI 58 [ n.50 ])) -1 (nil)
(nil))
Both dest & norder are assigned the same memory location
(virtual-stack-vars - 8). So later lifeness analysis thinks that the
first assignment is dead and it removes it. norder contains results of
bswap but gcc cannot remove the asm statement. However, since the
output of the asms are dead so they both got eax as the output
register.
--
Summary: Incorrect stack sharing causing removal of live code
Product: gcc
Version: 4.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: dnovillo at gcc dot gnu dot org
GCC build triplet: x86_64-unknown-linux-gnu
GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32327
More information about the Gcc-bugs
mailing list