Bug 45695

Summary: [4.5/4.6 Regression] -O1 wrong-code by cmove
Product: gcc Reporter: Jan Kratochvil <jan.kratochvil>
Component: rtl-optimizationAssignee: Jakub Jelinek <jakub>
Status: RESOLVED FIXED    
Severity: blocker CC: ebotcazou, gcc-bugs, jakub
Priority: P1 Keywords: wrong-code
Version: 4.5.2   
Target Milestone: 4.5.2   
Host: Target: x86_64-unknown-linux-gnu
Build: Known to work: 4.5.1
Known to fail: Last reconfirmed: 2010-09-16 21:57:25
Attachments: gcc46-pr45695.patch

Description Jan Kratochvil 2010-09-16 21:38:07 UTC
FSF GDB HEAD by FSF GCC 4.5.HEAD errors on `print 0|0' with -O1 and higher.

source below compiles to:
0000000000400455 <f>:
  400455:       53                      push   %rbx
  400456:       39 fa                   cmp    %edi,%edx
  400458:       0f 44 de                cmove  %esi,%ebx

but $ebx is left uninitialized for not-equal comparison.

Compilation flags: -O1
it passes = exit code 0 = with -O0
it fails  = exit code 1 = with -O1

PASS: gcc (GCC) 4.4.5 20100916 (prerelease)
FAIL: gcc (GCC) 4.5.2 20100916 (prerelease)
PASS: gcc (GCC) 4.6.0 20100916 (experimental)
FAIL: gcc-4.5.1-3.fc14.x86_64
not re-verified but PASS: gcc-4.5.1-1.fc14.x86_64


__attribute__((noinline, noclone)) void
g (int x)
{ 
  asm volatile ("");
}
__attribute__((noinline, noclone)) int
f (int a, int b, int d)
{
  int r = -1;
  b += d;
  if (d == a)
    r = b - d;
  g (b);
  return r; 
}
int 
main (void)
{ 
  asm volatile ("mov $42, %%rbx" : : : "rbx");
  return f (0, 1, 4) == 42 ? 1 : 0;
}
Comment 1 Jakub Jelinek 2010-09-16 21:57:25 UTC
Caused by my http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163555
change, so will look into it tomorrow.
http://gcc.gnu.org/bugzilla/attachment.cgi?id=21560&action=view
doesn't break it, only the version that tries harder and tries it the other way around.
Comment 2 Jakub Jelinek 2010-09-17 12:05:37 UTC
Created attachment 21817 [details]
gcc46-pr45695.patch

Untested fix.
Comment 3 Jakub Jelinek 2010-09-20 13:24:38 UTC
Subject: Bug 45695

Author: jakub
Date: Mon Sep 20 13:24:23 2010
New Revision: 164431

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164431
Log:
	PR rtl-optimization/45695
	* combine.c (try_combine): When splitting a two set pattern,
	make sure the pattern which will be put into i2 doesn't use REGs
	or MEMs set by insns in between i2 and i3.

	* gcc.c-torture/execute/pr45695.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr45695.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/combine.c
    trunk/gcc/testsuite/ChangeLog

Comment 4 Jakub Jelinek 2010-09-20 22:37:54 UTC
Subject: Bug 45695

Author: jakub
Date: Mon Sep 20 22:37:32 2010
New Revision: 164467

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164467
Log:
	PR rtl-optimization/45695
	* combine.c (try_combine): Don't try to swap the two patterns, if the
	chosen order is not possible, just give up.  For HAVE_cc0 targets,
	check if XVECEXP (newpat, 0, 0) doesn't use REGs or MEMs set by insns
	in between i2 and i3.

	* gcc.c-torture/execute/pr45695.c: New test.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr45695.c
Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/combine.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog

Comment 5 Jakub Jelinek 2010-09-20 22:39:53 UTC
Fixed.