Bug 45623 - [4.5 Regression] GCC 4.5.[01] breaks our ffi on Linux64. ABI break?
Summary: [4.5 Regression] GCC 4.5.[01] breaks our ffi on Linux64. ABI break?
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.5.1
: P3 normal
Target Milestone: 4.5.2
Assignee: Richard Biener
URL:
Keywords: wrong-code
: 47712 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-09-09 21:44 UTC by Taras Glek
Modified: 2011-02-13 10:15 UTC (History)
8 users (show)

See Also:
Host:
Target: x86_64-*-linux
Build:
Known to work: 4.6.0
Known to fail: 4.5.1
Last reconfirmed: 2010-09-15 12:31:16


Attachments
Reduced testcase (269 bytes, text/x-csrc)
2010-09-15 11:45 UTC, Mike Hommey
Details
Reduced testcase (227 bytes, text/x-csrc)
2010-09-15 12:05 UTC, Mike Hommey
Details
patch (2.71 KB, patch)
2010-09-15 13:59 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Taras Glek 2010-09-09 21:44:42 UTC
See https://bugzilla.mozilla.org/show_bug.cgi?id=594611 and https://bugzilla.mozilla.org/show_bug.cgi?id=590683
 for more details. This breaks users of Firefox Sync on GCC 4.5. 
The bug isn't present in gcc 4.4 or trunk. What would it take to cherry-pick a fix for 4.5.x?
Comment 1 Dan Witte 2010-09-09 22:03:33 UTC
FWIW our libffi is basically libffi git head: http://github.com/atgreen/libffi

Which is regularly synced to gcc libffi.
Comment 2 Andrew Pinski 2010-09-09 22:17:51 UTC
There have been no ABI changes in 4.5 that I know of for PowerPC64 or even differences between the trunk and 4.5.
Comment 3 H.J. Lu 2010-09-10 00:38:16 UTC
Mozilla bugs say "Platform: x86 Linux". But gcc bug says
"powerpc64-*-linux". What is going on?
Comment 4 Dan Witte 2010-09-10 00:46:28 UTC
This is on x86_64. (I can't change the field, though. Can someone else?)
Comment 5 H.J. Lu 2010-09-10 00:51:56 UTC
I am not ware any x86-64 psABI changes in gcc 4.5. Please provide
a testcase.
Comment 6 Andrew Pinski 2010-09-10 01:40:57 UTC
(In reply to comment #3)
> Mozilla bugs say "Platform: x86 Linux". But gcc bug says
> "powerpc64-*-linux". What is going on?

I must have missed since I saw Linux64 I was thinking powerpc64 :).  Really there have been none x86_64 ones either.  Though the normal thing here that might happen is strict aliasing issues.  Can you try -fno-strict-aliasing.  Also maybe look for buffer overflows which might cause issues you think are compiler related.
Comment 7 Taras Glek 2010-09-10 02:37:43 UTC
-fno-strict-aliasing makes no difference.
Comment 8 H.J. Lu 2010-09-10 02:56:54 UTC
(In reply to comment #0)
> See https://bugzilla.mozilla.org/show_bug.cgi?id=594611 and
> https://bugzilla.mozilla.org/show_bug.cgi?id=590683
>  for more details. This breaks users of Firefox Sync on GCC 4.5. 
> The bug isn't present in gcc 4.4 or trunk. What would it take to cherry-pick a
> fix for 4.5.x?
> 

You either identify which checkin fixes it or find a testcase so that
I can use it to find the fix.
Comment 9 Mike Hommey 2010-09-15 11:45:39 UTC
Created attachment 21798 [details]
Reduced testcase

Both issues Taras mentioned are actually separated. One is an actual bug in ffi (to be filed), the other one is an optimization issue with gcc. I reduced the problematic code to the attached code, which prints "foo" with -O1 (and more), and "bar" with -O0, with gcc 4.5.1. gcc 4.4 compiled code correctly prints "bar" with any optimization level.
Comment 10 Mike Hommey 2010-09-15 11:53:35 UTC
Please note this actually only happens on x86. (I would change the summary and target if I could)
Comment 11 Mike Hommey 2010-09-15 12:05:41 UTC
Created attachment 21799 [details]
Reduced testcase

Inlining JSVAL_TO_PRIVATE by hand still makes it break, and reduces the testcase further.
Comment 12 Mike Hommey 2010-09-15 12:11:46 UTC
FWIW, it's still broken on a gcc trunk snapshot from the 28th of august.
Comment 13 Richard Biener 2010-09-15 12:16:05 UTC
Confirmed and investigating.
Comment 14 Richard Biener 2010-09-15 12:31:15 UTC
You are accessing a pointer of type char *s1 via an lvalue of type void *
(*data).  Or speaking in C++, you are accessing an object of dynamic type
void * (stored to via *data) by an lvalue of type char * (s1).

Thus your testcase invokes undefined behavior.

That it is miscompiled at -O1 is a bug.

With GCC 4.6 we now assign the same alias-set to all pointers, hiding
this issue.

data_4 is a non-pointer variable,ignoring constraint:*data_4 = s2.1_5
data_4, points-to vars: { }

oops.  I will have a look at the points-to bug.
Comment 15 Mike Hommey 2010-09-15 12:47:31 UTC
Note that the original code doesn't use char *. I used char * to make it easily visible with a printf. Actually, just writing

void foo(jsval_layout l, void *s2) {
    jsval_layout m;
    m.asBits = l.asBits;
    void ** data = (void**)m.ptr; 
    *data = s2;
}

exhibits the problem, afaics.
Comment 17 Richard Biener 2010-09-15 13:03:57 UTC
points-to analysis does not honor GCCs type-punning through union extension
(it works on x86_64 because ptr and asBits match in size and thus SRA
cleans the code up before pointer-analysis).  So PTA sees

  ss1.0_1 = ss1;
  l.ptr = ss1.0_1;
  D.3244_2 = l.asBits;
  m.asBits = D.3244_2;
  D.3245_3 = m.ptr;
  data_4 = (void * *) D.3245_3;

and it considers both D.3244_2 = l.asBits and m.asBits = D.3244_2 as
irrelevant (as they do not involve pointers).  Thus, m.ptr is never
assigned to and the points-to set of data_4 ends up as empty which
makes us remove the store *data_4 = s2.1_5.

Thus, as a workaround you should make sure the asBits field matches
pointer-size (so for example use uintptr_t isntead of uint64_t).
Comment 18 Mike Hommey 2010-09-15 13:14:41 UTC
(In reply to comment #17)
> Thus, as a workaround you should make sure the asBits field matches
> pointer-size (so for example use uintptr_t isntead of uint64_t).

which is not possible in the original code, as the union is a bit more complicated than in the reduced testcase:
http://mxr.mozilla.org/mozilla-central/source/js/src/jsval.h#274
Comment 19 Richard Biener 2010-09-15 13:24:54 UTC
Another workaround is to use -fno-tree-pta.
Comment 20 Mike Hommey 2010-09-15 13:41:05 UTC
(In reply to comment #19)
> Another workaround is to use -fno-tree-pta.

Doesn't work here.
Comment 21 Richard Biener 2010-09-15 13:50:03 UTC
(In reply to comment #20)
> (In reply to comment #19)
> > Another workaround is to use -fno-tree-pta.
> 
> Doesn't work here.

For the original code?  Then your reduced testcase is different from the
original problem.
Comment 22 Mike Hommey 2010-09-15 13:52:27 UTC
(In reply to comment #21)
> For the original code?  Then your reduced testcase is different from the
> original problem.

It doesn't work for the reduced testcase here, with gcc 4.5.1
Comment 23 rguenther@suse.de 2010-09-15 13:56:17 UTC
Subject: Re:  [4.5/4.6 Regression] GCC 4.5.[01]
 breaks our ffi on Linux64. ABI break?

On Wed, 15 Sep 2010, mh+gcc at glandium dot org wrote:

> ------- Comment #22 from mh+gcc at glandium dot org  2010-09-15 13:52 -------
> (In reply to comment #21)
> > For the original code?  Then your reduced testcase is different from the
> > original problem.
> 
> It doesn't work for the reduced testcase here, with gcc 4.5.1

It does fix the PTA problem (thus makes it work at -O1).  Still
fails at -O2 for some reason (but can't reproduce that on
the tip of the branch, only with the 4.5.1 release).  Alias-correct 
testcase:

#include <stdint.h>

extern void abort (void);

char *s1 = "foo";
char *s2 = "bar";

char **ss1 = &s1;

typedef union jsval_layout
{
    uint64_t asBits;
    char **ptr;
} jsval_layout;

int main()
{
  jsval_layout l, m;
  l.ptr = ss1;
  m.asBits = l.asBits;
  char ** data = m.ptr;
  *data = s2;
  if (s1 != s2)
    abort ();
  return 0;
}

Comment 24 Richard Biener 2010-09-15 13:59:38 UTC
Created attachment 21801 [details]
patch

I am testing this patch (for 4.5 branch).
Comment 25 Mike Hommey 2010-09-15 14:01:31 UTC
Oh, I was trying with -O2, yes, it works with -O1 -fno-tree-pta. Let me try on the original code, too.
Comment 26 Richard Biener 2010-09-16 11:06:41 UTC
Subject: Bug 45623

Author: rguenth
Date: Thu Sep 16 11:06:25 2010
New Revision: 164333

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164333
Log:
2010-09-16  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/45623
	* tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust.
	(get_constraint_for_component_ref): If computing a constraint
	for the rhs handle type punning through unions.
	(get_constraint_for_address_of): Adjust.
	(get_constraint_for_1): Likewise.
	(get_constraint_for): Likewise.
	(get_constraint_for_rhs): New function.
	(do_structure_copy): Adjust.
	(make_constraint_to): Likewise.
	(handle_const_call): Likewise.
	(find_func_aliases): Likewise.
	(process_ipa_clobber): Likewise.
	(create_variable_info_for): Likewise.

	* gcc.dg/torture/pr45623.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr45623.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-structalias.c

Comment 27 Richard Biener 2010-09-16 11:07:13 UTC
Fixed for trunk sofar.
Comment 28 Taras Glek 2010-09-16 20:46:22 UTC
(In reply to comment #27)
> Fixed for trunk sofar.

Is there an eta for 4.5 backport? We need this to switch Firefox to 4.5 on Linux.
Comment 29 Richard Biener 2010-09-17 09:09:37 UTC
(In reply to comment #28)
> (In reply to comment #27)
> > Fixed for trunk sofar.
> 
> Is there an eta for 4.5 backport? We need this to switch Firefox to 4.5 on
> Linux.

I just want to play safe and see if there is any fallout on trunk.  You can
use the attachment in comment #24 for the 4.5 branch (and I'd appreciate
testing if this fixes your original problem)
Comment 30 Richard Biener 2010-09-20 08:33:54 UTC
Fixed.
Comment 31 Richard Biener 2010-09-20 08:34:01 UTC
Subject: Bug 45623

Author: rguenth
Date: Mon Sep 20 08:33:46 2010
New Revision: 164430

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164430
Log:
2010-09-20  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/45623
	* tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust.
	(get_constraint_for_component_ref): If computing a constraint
	for the rhs handle type punning through unions.
	(get_constraint_for_address_of): Adjust.
	(get_constraint_for_1): Likewise.
	(get_constraint_for): Likewise.
	(get_constraint_for_rhs): New function.
	(do_structure_copy): Adjust.
	(make_constraint_to): Likewise.
	(handle_const_call): Likewise.
	(find_func_aliases): Likewise.

	* gcc.dg/torture/pr45623.c: New testcase.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/torture/pr45623.c
Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_5-branch/gcc/tree-ssa-structalias.c

Comment 32 Richard Biener 2011-02-13 10:15:57 UTC
*** Bug 47712 has been marked as a duplicate of this bug. ***