Bug 48661 - [4.6/4.7 Regression] wrong-code regression with devirtualization
Summary: [4.6/4.7 Regression] wrong-code regression with devirtualization
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: 4.6.1
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2011-04-18 10:05 UTC by scott snyder
Modified: 2011-04-19 12:18 UTC (History)
3 users (show)

See Also:
Host:
Target: i?86-*-*
Build:
Known to work: 4.5.2
Known to fail: 4.6.0
Last reconfirmed: 2011-04-18 10:35:45


Attachments
test case (424 bytes, text/x-c++src)
2011-04-18 10:05 UTC, scott snyder
Details
gcc46-pr48661.patch (1.50 KB, patch)
2011-04-18 16:55 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description scott snyder 2011-04-18 10:05:47 UTC
Created attachment 24029 [details]
test case

hi -

gcc 4.6 miscompiles the attached code with -O2.
This was observed in the 4.6.0 release, and also in
4.6.1 20110415 from svn.  I see it both with x86 and x86_64 targets.
I did not see this problem with gcc 4.5.

Example of compiling and running:

$ g++ -m32 -o y -O2 y.cc
$ ./y
123
134514336
$

I expect it to print `123' on the second line as well.

Here's the generated code for testSetters.
Note that an uninitialized value is being passed to the
second printf() call.

	.cfi_startproc
	subl	$44, %esp
	.cfi_def_cfa_offset 48
	leal	28(%esp), %eax
	movl	$_ZTV6P4Impl+12, 20(%esp)
	movl	$_ZTV6P4Impl+36, 28(%esp)
	movl	$123, 24(%esp)
	movl	%eax, (%esp)
	call	_ZTv0_n12_NK6P4Impl2ptEv
	movl	$.LC0, (%esp)
	movl	%eax, 4(%esp)
	call	printf
	movl	32(%esp), %eax  ; this value has not been initialized.
	movl	$.LC0, (%esp)
	movl	%eax, 4(%esp)
	call	printf
	addl	$44, %esp
	.cfi_def_cfa_offset 4
	ret
	.cfi_endproc


Interestingly, the presence of the testGetters() function is required
to trigger the bug, even though it is not called.

Looking at the dumps, a difference seems to show up at the
056t.ehdisp stage.

When the code is being miscompiled, i see this:

  D.2397_35 = MEM[(const struct P4Impl *)&pp + 8B].m_pt;
  D.2396_44 = D.2397_35;
  D.2394_30 = D.2396_44;
  p.m_pt = D.2394_30;
  ...
  D.2297_5 = p.m_pt;
  printf ("%d\n", D.2297_5);


But if i comment out the P4Impl declaration in testGetters(),
i instead see this for testSetters():

  D.2384_34 = MEM[(const struct I4Momentum *)&pp].D.2131._vptr.I4Momentum;
  D.2385_35 = *D.2384_34;
  D.2386_36 = OBJ_TYPE_REF(D.2385_35;&pp.D.2131->0) (&pp.D.2131);

<bb 5>:
  p.m_pt = D.2386_36;
  ...
  D.2267_5 = p.m_pt;
  printf ("%d\n", D.2267_5);

sss
Comment 1 Jakub Jelinek 2011-04-18 10:35:45 UTC
Goes away with -fno-devirtualize, works with -m64 too.
Comment 2 Richard Biener 2011-04-18 10:44:02 UTC
On trunk it ICEs with

t.C:71:1: error: a call to thunk improperly represented in the call graph:
# VUSE <.MEM_11>
D.1963_3 = (int I4Momentum::<T2aa> (const struct I4Momentum *))P4Impl::_ZTv0_n12_NK6P4Impl2ptEv (&pp.D.1798);

void testSetters()/24(12) @0x7ffff5b784a0 (asm: _Z11testSettersv) availability:available analyzed needed reachable body externally_visible finalized
  called by: int main()/25 (1.00 per call) (can throw external) 
  calls: int printf(const char*, ...)/30 (1.00 per call) int printf(const char*, ...)/30 (1.00 per call) virtual int P4Impl::pt() const/13 (1.00 per call) P4Impl::P4Impl(const Hep3Vector&)/12 (1.00 per call) 
  References: 
  Refering this function: 
  has 3 outgoing edges for indirect calls.
t.C:71:1: internal compiler error: verify_cgraph_node failed
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

4.6 brach head also fails.
Comment 3 Jakub Jelinek 2011-04-18 10:58:56 UTC
Can't reproduce the ICE on the trunk myself, the testcase works for me on the trunk starting with
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172023
Comment 4 Jakub Jelinek 2011-04-18 16:55:58 UTC
Created attachment 24036 [details]
gcc46-pr48661.patch

Untested fix.
Comment 5 Jakub Jelinek 2011-04-18 21:58:05 UTC
Author: jakub
Date: Mon Apr 18 21:58:03 2011
New Revision: 172676

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172676
Log:
	PR middle-end/48661
	* gimple-fold.c (gimple_get_virt_method_for_binfo): Return NULL
	if TREE_TYPE (v) is non-NULL.

	* gimple-fold.c (gimple_get_virt_method_for_binfo): Renamed from
	gimple_get_virt_mehtod_for_binfo.
	* gimple.h (gimple_get_virt_method_for_binfo): Likewise.
	* ipa-cp.c (ipcp_process_devirtualization_opportunities): Adjust
	callers.
	* ipa-prop.c (try_make_edge_direct_virtual_call): Likewise.

	* g++.dg/torture/pr48661.C: New test.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/torture/pr48661.C
Modified:
    branches/gcc-4_6-branch/gcc/ChangeLog
    branches/gcc-4_6-branch/gcc/gimple-fold.c
    branches/gcc-4_6-branch/gcc/gimple.h
    branches/gcc-4_6-branch/gcc/ipa-cp.c
    branches/gcc-4_6-branch/gcc/ipa-prop.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 6 scott snyder 2011-04-18 21:58:51 UTC
Thanks Jakob!

I can confirm that that patch also fixes the problem in the original
source from which i derived that test case.
Comment 7 Jakub Jelinek 2011-04-18 21:58:53 UTC
Author: jakub
Date: Mon Apr 18 21:58:51 2011
New Revision: 172677

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172677
Log:
	PR middle-end/48661
	* gimple-fold.c (gimple_get_virt_method_for_binfo): Return NULL
	if TREE_TYPE (v) is non-NULL.

	* gimple-fold.c (gimple_get_virt_method_for_binfo): Renamed from
	gimple_get_virt_mehtod_for_binfo.
	* gimple.h (gimple_get_virt_method_for_binfo): Likewise.
	* ipa-cp.c (ipcp_process_devirtualization_opportunities): Adjust
	callers.
	* ipa-prop.c (try_make_edge_direct_virtual_call): Likewise.

	* g++.dg/torture/pr48661.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/torture/pr48661.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimple-fold.c
    trunk/gcc/gimple.h
    trunk/gcc/ipa-cp.c
    trunk/gcc/ipa-prop.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2011-04-19 12:18:05 UTC
Fixed.  On the trunk the yesterday introduced problems are tracked in PR48674.