From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13914 invoked by alias); 13 Jun 2007 19:57:34 -0000 Received: (qmail 13651 invoked by uid 48); 13 Jun 2007 19:57:22 -0000 Date: Wed, 13 Jun 2007 19:57:00 -0000 Subject: [Bug c/32327] New: Incorrect stack sharing causing removal of live code X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "dnovillo at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-06/txt/msg01046.txt.bz2 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; : n.50 = VIEW_CONVERT_EXPR(x); if (n.50 > 41) goto ; else goto ; :; n = n.50; goto (); :; n = n.50 + 1; :; __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