public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/39093] New: inline code optimized wrong with -O3
@ 2009-02-04 3:50 ricardo at teli dot org
2009-02-04 9:34 ` [Bug c/39093] " schwab at suse dot de
0 siblings, 1 reply; 2+ messages in thread
From: ricardo at teli dot org @ 2009-02-04 3:50 UTC (permalink / raw)
To: gcc-bugs
The problem happens when I try to optimize this procedure:
------------------------------------------------
inline void*
bcAtomCompareExchange(void **destination,
void *exchange,
void *compare)
{
void* old = *destination;
if (old == compare)
*destination = exchange;
return old;
}
-------------------------------------------------
when old == compare *destination changes, but the optimizer keeps using the old
value. Here is the source code (has just stdio.h), and yes, I know the names
are "Atom" are irrelevant here, it is not thread-safe, but that's not the
issue, there are no threads here, straight C code
------------- test.c ---------------------
#include <stdio.h>
inline void*
bcAtomCompareExchange(void **destination,
void *exchange,
void *compare)
{
void* old = *destination;
if (old == compare)
*destination = exchange;
return old;
}
inline void*
bcAtomExchange(void **target,
void *exchange)
{
void* old = *target;
*target = exchange;
return old;
}
int
main()
{
const char* first = "uno";
const char* second = "duo";
const char* third = "tre";
char *px = (char*) first, *py = (char*) second, *pz = (char*) third;
fprintf(stdout, "px= %s py= %s pz= %s\n", px, py, pz);
pz = px;
char* pw = (char*) bcAtomCompareExchange((void**) &px, py, pz);
fprintf(stdout, "pz= px; pw= bcAtomCompareExchange(&px, py, pz); px= %s
py= %s pz= %s pw= %s\n",
px, py, pz, pw);
py = (char*) third; py = (char*) bcAtomExchange((void**) &px, py);
fprintf(stdout, "py= tre; py= bcAtomExchange(&px, py); px= %s py= %s pz=
%s pw= %s\n",
px, py, pz, pw);
return 0;
}
--------------------end of test.c ----------------------
without optimization the output is correct:
px= uno py= duo pz= tre
pz= px; pw= bcAtomCompareExchange(&px, py, pz); px= duo py= duo pz= uno pw=
uno
py= tre; py= bcAtomExchange(&px, py); px= tre py= duo pz= uno pw= uno
but with optimization (-O3) the output is WRONG!
px= uno py= duo pz= tre
pz= px; pw= bcAtomCompareExchange(&px, py, pz); px= uno py= duo pz= uno pw=
uno
py= tre; py= bcAtomExchange(&px, py); px= duo py= duo pz= uno pw= uno
to help, I looked at the generated object code, and spotted the source of the
probelm, as explained in the following:
----------------- relevand parts of the disassemble using objdump ----
Contents of section .rodata:
400818 ....uno.duo.tre. # uno is 40081c (initial px)
400828 px= %s py= %s p # duo is 400820 (initial py)
400838 z= %s...pz= px; # tre is 400824 (initial pz)
400848 pw= bcAtomCompar # msg1 is 400828
400858 eExchange(&px, p # msg2 is 400840
400868 y, pz); px= %s # msg3 is 400890
400878 py= %s pz= %s pw
400888 = %s....py= tre;
400898 py= bcAtomExcha
4008a8 nge(&px, py); px
4008b8 = %s py= %s pz=
4008c8 %s pw= %s......
0000000000400660 <main>:
main():
400660: mov %rbx,-0x18(%rsp)
400665: mov %rbp,-0x10(%rsp)
40066a: xor %eax,%eax
40066c: mov %r12,-0x8(%rsp)
400671: sub $0x28,%rsp
400675: mov 0x2009b4(%rip),%rdi # 601030 <stdout@@GLIBC_2.2.5>
40067c: mov $0x400824,%r8d # %r8 gets pz (5th arg ABI)
400682: mov $0x400820,%ecx # %rcx gets py (4th arg ABI)
400687: mov $0x40081c,%edx # %rdx gets px (3rd arg ABI)
40068c: mov $0x400828,%esi # %esi gets msg1 (2nd arg ABI)
400691: movq $0x40081c,0x8(%rsp) # 0x8(%rsp) is &px
400698:
40069a: lea 0x8(%rsp),%r12
40069f: callq 400560 <fprintf@plt> # print first message fine
4006a4: mov 0x8(%rsp),%rbx # %rbx gets px (old = *dest)
4006a9: cmp %rbx,%rbx # inline the comparison old ==
comp
4006ac: mov %rbx,%rbp # inline return pw = old
4006af: je 400718 <main+0xb8> # jump executed, back next line
4006b1: mov 0x200978(%rip),%rdi # 601030 <stdout@@GLIBC_2.2.5>
4006b8: mov %rbp,%r9 # %r9 gets pw (6th arg ABI)
4006bb: mov %rbx,%r8 # %r8 gets pz (5th arg ABI)
4006be: mov %rbx,%rdx # << ERROR >> (3rd arg ABI)
mov 0x8(%rsp),%rdx <<<<<<<< should be that with updated px
<<<<<<<< but instead it ignored the fact
<<<<<<<< that *destination changed !!
4006c1: mov $0x400820,%ecx # %rcx untouched py (4th arg ABI)
4006c6: mov $0x400840,%esi # %esi gets msg2 (2nd arg ABI)
4006cb: xor %eax,%eax
4006cd: callq 400560 <fprintf@plt> # message prints WRONG!!!!!
4006d2: mov (%r12),%rcx
4006d6: mov 0x8(%rsp),%rdx
4006db: mov %rbp,%r9
4006de: mov 0x20094b(%rip),%rdi # 601030 <stdout@@GLIBC_2.2.5>
4006e5: mov %rbx,%r8
4006e8: mov $0x400890,%esi
4006ed: xor %eax,%eax
4006ef: movq $0x400824,(%r12)
4006f6:
4006f7: callq 400560 <fprintf@plt>
4006fc: xor %eax,%eax
4006fe: mov 0x10(%rsp),%rbx
400703: mov 0x18(%rsp),%rbp
400708: mov 0x20(%rsp),%r12
40070d: add $0x28,%rsp
400711: retq
400712: nopw 0x0(%rax,%rax,1)
400718: movq $0x400820,0x8(%rsp) # px reference is correct but
not used
40071f:
400721: jmp 4006b1 <main+0x51>
400723: nop
------------------------------------------------------------------------------
I think I have a workaround, instead of using void* as generic pointer, using a
typedef like
typedef char * addr_t like in the old days when void did not exist, but not
sure under what conditions the compiler will generate wrong code.
Thanks,
Ricardo
--
Summary: inline code optimized wrong with -O3
Product: gcc
Version: 4.3.2
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: ricardo at teli dot org
GCC build triplet: gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE
Linux)
GCC target triplet: x86_64-suse-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39093
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Bug c/39093] inline code optimized wrong with -O3
2009-02-04 3:50 [Bug c/39093] New: inline code optimized wrong with -O3 ricardo at teli dot org
@ 2009-02-04 9:34 ` schwab at suse dot de
0 siblings, 0 replies; 2+ messages in thread
From: schwab at suse dot de @ 2009-02-04 9:34 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from schwab at suse dot de 2009-02-04 09:33 -------
> char* pw = (char*) bcAtomCompareExchange((void**) &px, py, pz);
This is violating the C aliasing rules. Declare px as void* to fix that.
*** This bug has been marked as a duplicate of 21920 ***
--
schwab at suse dot de changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |DUPLICATE
Summary|inline code optimized wrong |inline code optimized wrong
|with -O3 |with -O3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39093
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-02-04 9:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-04 3:50 [Bug c/39093] New: inline code optimized wrong with -O3 ricardo at teli dot org
2009-02-04 9:34 ` [Bug c/39093] " schwab at suse dot de
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).