This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/12799] New: cmov is confused by a intervening inc that bashes flags.
- From: "pratap at vmware dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 27 Oct 2003 23:19:51 -0000
- Subject: [Bug c/12799] New: cmov is confused by a intervening inc that bashes flags.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12799
Summary: cmov is confused by a intervening inc that bashes flags.
Product: gcc
Version: 3.3
Status: UNCONFIRMED
Severity: critical
Priority: P1
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: pratap at vmware dot com
CC: gcc-bugs at gcc dot gnu dot org
The following program returns 1 (denotes failure), instead of 0 (which
denotes success) when compiled with the following compiler flags,
using gcc 3.0.3, but passes with the same flags on gcc 3.3.
I'm still filing this as a bug on gcc 3.3 since all my bugzilla searches
did not convince me that the bug has indeed been fixed in 3.3.
Here are the flags:
-O2 -g3 -march=i686 -fno-strict-aliasing -pipe
-mpreferred-stack-boundary=2 -fno-strict-aliasing
-march=i686 -mcpu=i686 -malign-jumps=2 -malign-functions=2
-malign-loops=2 -mregparm=3 -Wmissing-prototypes'
________________________________________________________________________
int loo = 1;
__inline__ char InlineFunc(void);
int FooBar(void);
__inline__ char InlineFunc(void)
{
return __builtin_expect(!!(loo == 1), 1);
}
int FooBar(void)
{
int i;
int var1 = InlineFunc() ? 2046 : 1023;
int var2 = InlineFunc() ? 512 : 1024;
for (i = 0; i < var1; i++) {};
if (InlineFunc() && var2 != 512) {
return 1;
}
return 0;
}
int main() {
return FooBar();
}
________________________________________________________________________
Here is the assembly generated by the 3.0.3 compiler:
<stuff snipped>
movl $1023, %eax
movl $2046, %ecx
movl %esp, %ebp
pushl %ebx
cmpl $1, %edx
movl $512, %ebx
cmovne %eax, %ecx
incl %eax <<<< bashes flags
cmovne %eax, %ebx <<<< needs those old flags!
<stuff snipped>
It seems that an "add %eax = %eax + 1" in the intermediate graph
was replaced incorrectly with an "inc %eax".
When I try this with the 3.3 compiler, I see:
sete %al
testb $1, %al
movl $1023, %eax
cmove %eax, %ecx
cmpl $1, %edx
sete %al
testb $1, %al
movl $1024, %eax <<< this is fine, it doenst bash flags.
cmove %eax, %ebx
testl %ecx, %ecx
It is comforting to know that gcc 3.3 does not exhibit problem. What I
want to know is if 3.3 really fixes the problem, or is it some accident
of compiler phase ordering. I did a deep search of the gcc.gnu.org
bugzilla database but did not find any reported bugs that seemed like
this one. If I have missed it, could you point me to a bug report, bug
id?
We would like to move to 3.3 with the confidence that the bug has been
fixed, or else we may be forced to turn off cmov synthesis, which will
be unfortunate since it is a good performance win.
Please advice.