User account creation filtered due to spam.

Bug 45704 - [4.5 Regression] load byte instruction is used for volatile int
Summary: [4.5 Regression] load byte instruction is used for volatile int
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:
: 46762 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-09-17 14:49 UTC by Atsushi Nemoto
Modified: 2011-02-03 18:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-09-17 15:45:01


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Atsushi Nemoto 2010-09-17 14:49:03 UTC
A cast to volatile int pointer is ignored on gcc 4.5 with this test case.

struct st {
	int ptr;
};

int foo(struct st *st)
{
	int v = *(volatile int *)&st->ptr;
	return v & 0xff;
}

mipsel-linux-gcc-4.5.1 -O2 foo.c -S output:
	lbu	$2,0($4)
	j	$31
	nop

It seems the cast are ignored and "load int and mask" was optimized to "load byte".
gcc 4.4.4 works fine.
mipsel-linux-gcc-4.4.4 -O2 foo.c -S output:
	lw	$2,0($4)
	j	$31
	andi	$2,$2,0x00ff

git-bisect tell me 0d9f1189f3df5ce5c0efc3ecadc7c0a4f75b202d is the first bad commit.
URL: http://gcc.gnu.org/viewcvs?view=revision&revision=156571
The commit is fix for Bug 42956.

The PR 42956 bugzilla shows same fix was applied to both 4.5.0 and 4.4.4,
but they behave differently on this test case.

Comparing patches for 4.4 branch and 4.5, I see the latter contains two more changes for gimplify.c:
A STRIP_NOP line and lines starting with "/* *(foo *)&complexfoo => __real__ complexfoo */" comment.

I do not know gcc internal at all but it seems reverting this change fixes this problem.

-  STRIP_USELESS_TYPE_CONVERSION (sub);
+  STRIP_NOPS (sub);

Hope this helps.
Comment 1 Richard Biener 2010-09-17 15:45:01 UTC
Confirmed.  Mine.
Comment 2 Richard Biener 2010-09-20 15:54:23 UTC
Subject: Bug 45704

Author: rguenth
Date: Mon Sep 20 15:54:03 2010
New Revision: 164439

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

	PR middle-end/45704
	* gimplify.c (gimplify_modify_expr_rhs): Preserve volatileness.

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

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr45704.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimplify.c
    trunk/gcc/testsuite/ChangeLog

Comment 3 Richard Biener 2010-09-21 10:47:37 UTC
Fixed.
Comment 4 Richard Biener 2010-09-21 10:47:51 UTC
Subject: Bug 45704

Author: rguenth
Date: Tue Sep 21 10:47:28 2010
New Revision: 164475

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

	PR middle-end/45704
	* gimplify.c (gimplify_modify_expr_rhs): Preserve volatileness.

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

Added:
    branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/torture/pr45704.c
Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/gimplify.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog

Comment 5 Atsushi Nemoto 2010-09-27 15:48:32 UTC
Here is a similar test case with "packed" attribute, which still produces bad result.
Four load-byte instructions are generated instead of one load-word.

struct st {
	int ptr;
} __attribute__ ((packed));

int foo(struct st *st)
{
	int v = *(volatile int *)&st->ptr;
	return v & 0xff;
}

gcc 4.4.4 works fine (same result with the first test case)

gcc 4.6.0 20100927 (or 4.5.2 20100927) generates:
	lbu	$2,0($4)
	lbu	$3,1($4)
	andi	$2,$2,0x00ff
	lbu	$3,2($4)
	lbu	$3,3($4)
	j	$31
	nop

I do not know this should be another PR or not.
Comment 6 rguenther@suse.de 2010-09-27 15:54:06 UTC
On Mon, 27 Sep 2010, anemo at mba dot ocn.ne.jp wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45704
> 
> --- Comment #5 from Atsushi Nemoto <anemo at mba dot ocn.ne.jp> 2010-09-27 15:48:32 UTC ---
> Here is a similar test case with "packed" attribute, which still produces bad
> result.
> Four load-byte instructions are generated instead of one load-word.
> 
> struct st {
>     int ptr;
> } __attribute__ ((packed));
> 
> int foo(struct st *st)
> {
>     int v = *(volatile int *)&st->ptr;
>     return v & 0xff;
> }
> 
> gcc 4.4.4 works fine (same result with the first test case)
> 
> gcc 4.6.0 20100927 (or 4.5.2 20100927) generates:
>     lbu    $2,0($4)
>     lbu    $3,1($4)
>     andi    $2,$2,0x00ff
>     lbu    $3,2($4)
>     lbu    $3,3($4)
>     j    $31
>     nop
> 
> I do not know this should be another PR or not.

It should be as this is likely a problem with unaligned access
support.  I think you can't generally expect unaligned volatile
accesses to work (on ia64 for example they certainly wouldn't).
Comment 7 Atsushi Nemoto 2010-09-28 15:34:59 UTC
(In reply to comment #6)
> It should be as this is likely a problem with unaligned access
> support.  I think you can't generally expect unaligned volatile
> accesses to work (on ia64 for example they certainly wouldn't).

OK, filed as PR 45819.
ARM linux kernel depends on this unaligned volatile access.
Comment 8 Atsushi Nemoto 2010-09-30 13:59:34 UTC
(In reply to comment #0)
> The PR 42956 bugzilla shows same fix was applied to both 4.5.0 and 4.4.4,
> but they behave differently on this test case.
> 
> Comparing patches for 4.4 branch and 4.5, I see the latter contains two more
> changes for gimplify.c:
> A STRIP_NOP line and lines starting with "/* *(foo *)&complexfoo => __real__
> complexfoo */" comment.

In the first place, why PR 42956 fixes are different for 4.4 and 4.5?
The commit logs are same, but actual changes for gimplify.c were differ.

Is that "two more changes" are not bugfix but improvement?
Comment 9 rguenther@suse.de 2010-09-30 14:14:13 UTC
On Thu, 30 Sep 2010, anemo at mba dot ocn.ne.jp wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45704
> 
> --- Comment #8 from Atsushi Nemoto <anemo at mba dot ocn.ne.jp> 2010-09-30 13:59:34 UTC ---
> (In reply to comment #0)
> > The PR 42956 bugzilla shows same fix was applied to both 4.5.0 and 4.4.4,
> > but they behave differently on this test case.
> > 
> > Comparing patches for 4.4 branch and 4.5, I see the latter contains two more
> > changes for gimplify.c:
> > A STRIP_NOP line and lines starting with "/* *(foo *)&complexfoo => __real__
> > complexfoo */" comment.
> 
> In the first place, why PR 42956 fixes are different for 4.4 and 4.5?
> The commit logs are same, but actual changes for gimplify.c were differ.
> 
> Is that "two more changes" are not bugfix but improvement?

Yes.
Comment 10 Atsushi Nemoto 2010-10-01 12:48:47 UTC
(In reply to comment #9)
> > Is that "two more changes" are not bugfix but improvement?
> 
> Yes.

I see, thank you for clarification.
Comment 11 Thomas Schwinge 2011-02-03 18:27:10 UTC
*** Bug 46762 has been marked as a duplicate of this bug. ***