Bug 36339 - [4.3/4.4 Regression] not call clobbering variable for non common offset
Summary: [4.3/4.4 Regression] not call clobbering variable for non common offset
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: 4.3.1
Assignee: Richard Biener
URL:
Keywords: alias, wrong-code
Depends on: 36344 36519
Blocks:
  Show dependency treegraph
 
Reported: 2008-05-27 08:18 UTC by Mikael Pettersson
Modified: 2008-06-13 09:15 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 4.2.4 4.3.1 4.4.0
Known to fail: 4.3.0
Last reconfirmed: 2008-05-27 08:58:50


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mikael Pettersson 2008-05-27 08:18:01 UTC
/* gcc430-tagged-ptr-bug.c
 *
 * This program illustrates a miscompilation with gcc-4.3.0.
 *
 * The failing code (try_a() below) initialises a Lisp-like
 * CONS cell in an on-stack mini-heap, then passes a tagged
 * pointer to this object in a tail-recursive call.
 *
 * With gcc-4.3.0, the reservation of space on the stack and
 * the initialisation of it is REMOVED. Instead the code just
 * constructs a pointer as an offset from the stack pointer
 * and passes that in the call, causing failures in the callee.
 *
 * This error has been observed on x86_64, sparc64, and powerpc.
 * It still occurs with the gcc-4.3-20080515 snapshot.
 *
 * Compiling with -fno-strict-aliasing does NOT fix the problem.
 *
 * This code works with all older gccs up to and including 4.2.4.
 *
 * The functions try_a(), try_b(), and try_c() explore different
 * ways of passing the object reference:
 * - try_c() passes it as a tagged (offset by 3) void*
 *   this works
 * - try_b() passes it as an untagged uintptr_t
 *   this works
 * - try_a() passes it as a tagged uintptr_t
 *   this fails
 *
 * The original code which broke due to this problem is in the
 * virtual machine for the Erlang functional programming language,
 * specifically the ets_match_2() and ets_match_3() functions
 * in the erl_db.c module.
 */
#include <stdio.h>

typedef unsigned long my_uintptr_t;

int check_a(my_uintptr_t tagged_ptr);
int check_b(my_uintptr_t untagged_ptr);
int check_c(void *tagged_ptr);

int __attribute__((noinline)) try_a(my_uintptr_t x)
{
    my_uintptr_t heap[2];
    my_uintptr_t *hp = heap;

    hp[0] = x;
    hp[1] = 0;
    return check_a((my_uintptr_t)(void*)((char*)hp + 1));
}

int __attribute__((noinline)) check_a(my_uintptr_t tagged_ptr)
{
    my_uintptr_t *hp = (my_uintptr_t*)(void*)((char*)tagged_ptr - 1);

    if (hp[0] == 42 && hp[1] == 0)
        return 0;
    printf("try_a() is broken\n");
    return -1;
}

int __attribute__((noinline)) try_b(my_uintptr_t x)
{
    my_uintptr_t heap[2];
    my_uintptr_t *hp = heap;

    hp[0] = x;
    hp[1] = 0;
    return check_b((my_uintptr_t)(void*)hp + 0);
}

int __attribute__((noinline)) check_b(my_uintptr_t untagged_ptr)
{
    my_uintptr_t *hp = (my_uintptr_t*)(void*)(untagged_ptr - 0);

    if (hp[0] == 43 && hp[1] == 0)
        return 0;
    printf("try_b() is broken\n");
    return -1;
}

int __attribute__((noinline)) try_c(my_uintptr_t x)
{
    my_uintptr_t heap[2];
    my_uintptr_t *hp = heap;

    hp[0] = x;
    hp[1] = 0;
    return check_c((void*)((char*)hp + 3));
}

int __attribute__((noinline)) check_c(void *tagged_ptr)
{
    my_uintptr_t *hp = (my_uintptr_t*)((char*)tagged_ptr - 3);

    if (hp[0] == 27 && hp[1] == 0)
        return 0;
    printf("try_c() is broken\n");
    return -1;
}

int main(void)
{
    int ret = 0;

    if (try_a(42) < 0)  /* fails with gcc-4.3.0 */
        ret += 1;
    if (try_b(43) < 0)  /* works */
        ret += 2;
    if (try_c(27) < 0)  /* works */
        ret += 4;
    if (ret == 0)
        printf("OK\n");
    return ret;
}
Comment 1 Andrew Pinski 2008-05-27 08:52:07 UTC
Confirmed.
Comment 2 Richard Biener 2008-05-27 08:58:50 UTC
I'll have a look.
Comment 3 Richard Biener 2008-05-27 09:29:30 UTC
I have a patch.
Comment 4 Richard Biener 2008-05-27 13:21:53 UTC
Subject: Bug 36339

Author: rguenth
Date: Tue May 27 13:21:07 2008
New Revision: 136030

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136030
Log:
2008-05-27  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36339
	* tree-ssa-alias.c (set_initial_properties): Escaped pt_anything
	pointers cause all addressable variables to be call clobbered.

	* gcc.c-torture/execute/pr36339.c: New testcase.
	* gcc.dg/tree-ssa/loadpre8.c: XFAIL.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr36339.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c
    trunk/gcc/tree-ssa-alias.c

Comment 5 Richard Biener 2008-05-27 13:24:25 UTC
Subject: Bug 36339

Author: rguenth
Date: Tue May 27 13:23:34 2008
New Revision: 136031

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136031
Log:
2008-05-27  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36339
	* tree-ssa-alias.c (set_initial_properties): Escaped pt_anything
	pointers cause all addressable variables to be call clobbered.

	* gcc.c-torture/execute/pr36339.c: New testcase.
	* gcc.dg/tree-ssa/loadpre8.c: XFAIL.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gcc.c-torture/execute/pr36339.c
Modified:
    branches/gcc-4_3-branch/gcc/ChangeLog
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c
    branches/gcc-4_3-branch/gcc/tree-ssa-alias.c

Comment 6 Richard Biener 2008-05-27 13:24:51 UTC
Fixed.
Comment 7 Mikael Pettersson 2008-05-27 20:48:52 UTC
(In reply to comment #6)
> Fixed.
> 

I added the fix to the latest gcc-4.3 snapshot and bootstrapped it.
I then tested both the original application that failed (Erlang)
as well as the latest Linux kernel. Both built and worked fine.

Thank you for fixing this so quickly.
Comment 8 Richard Biener 2008-05-28 14:46:48 UTC
Subject: Bug 36339

Author: rguenth
Date: Wed May 28 14:45:57 2008
New Revision: 136100

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136100
Log:
2008-05-28  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36339
	* tree-ssa-alias.c (set_initial_properties): Move pt_anything
	and clobbering code out of the loop.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-ssa-alias.c

Comment 9 Richard Biener 2008-05-28 14:53:03 UTC
Subject: Bug 36339

Author: rguenth
Date: Wed May 28 14:52:07 2008
New Revision: 136101

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136101
Log:
2008-05-28  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36339
	* tree-ssa-alias.c (set_initial_properties): Move pt_anything
	and subvariable clobbering code out of the loop.

Modified:
    branches/gcc-4_3-branch/gcc/ChangeLog
    branches/gcc-4_3-branch/gcc/tree-ssa-alias.c