public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: memcpy to an unaligned address
       [not found] <345be691050804025955c0b4ab@mail.gmail.com>
@ 2005-08-04 15:06 ` Shaun Jackman
  2005-08-04 15:09   ` Christian Joensson
  2005-08-05  8:41   ` Carl Whitwell
  0 siblings, 2 replies; 35+ messages in thread
From: Shaun Jackman @ 2005-08-04 15:06 UTC (permalink / raw)
  To: Carl Whitwell, gcc

On 8/4/05, Carl Whitwell <carl.whitwell@gmail.com> wrote:
> Hi, 
>     thought I'd drop you a mail, would put it on gcc mailing list but
> haven't got time to work out how to send it there at this moment. 

The gcc mailing list is gcc@sources.redhat.com.
   
> All testing here is done on x86 processors using gcc under cygwin. 

Are you using an x86 host and an arm target?

> Testing gcc 3.3.4 showed no problems with memcpy alignment.  Using your
> example, the structure s was aligned but the member variable b was
> unaligned. The assembler code produced for the direct copy s->a = p and the
> memcpy replacement were identical. 

Did it produce an open code memcpy, and was it correct?

> Testing gcc 4.0.1 I found the structure s was unaligned such that the member
> variable b was aligned, which was odd. 
> I discovered that the structure appears to be aligned based upon the natural
> alignment of the last element within that structure. 
> Of course this means that the memcpy is now acting on an aligned member
> rather than an unaligned member, and works perfectly well. 

Interesting. Can you post an assembler snippet of this?

> This means that to cause an unaligned element within the structure I had to
> add another element to the structure and retest. 
> On doing this though I found gcc appeared to correctly replace memcpy with
> an unaligned copy. 
>   
> I completely agree that gcc should be handling all the alignment issues
> here, but I'm not sure what it thinks it's doing moving the structure about
> in 4.0.1 
> It may be worth tracking the addresses of the members in all the tests to
> make sure the tests are comparable across gcc versions. 
>   
> Regards, 
> Carl Whitwell 

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-04 15:06 ` memcpy to an unaligned address Shaun Jackman
@ 2005-08-04 15:09   ` Christian Joensson
  2005-08-05  8:41   ` Carl Whitwell
  1 sibling, 0 replies; 35+ messages in thread
From: Christian Joensson @ 2005-08-04 15:09 UTC (permalink / raw)
  To: Shaun Jackman; +Cc: Carl Whitwell, gcc

On 8/4/05, Shaun Jackman <sjackman@gmail.com> wrote:

> The gcc mailing list is gcc@sources.redhat.com.

I'd say it's gcc@gcc.gnu.org though...

-- 
Cheers,

/ChJ

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-04 15:06 ` memcpy to an unaligned address Shaun Jackman
  2005-08-04 15:09   ` Christian Joensson
@ 2005-08-05  8:41   ` Carl Whitwell
  2005-08-05 16:09     ` Shaun Jackman
  1 sibling, 1 reply; 35+ messages in thread
From: Carl Whitwell @ 2005-08-05  8:41 UTC (permalink / raw)
  To: Shaun Jackman; +Cc: gcc

On 8/4/05, Shaun Jackman <sjackman@gmail.com> wrote:
> Are you using an x86 host and an arm target?
> 

Actually no, my major concern at the time was the large quantity of
legacy code with packed structures that we have on an embedded linux
x86 system. I was just testing that we didn't have an issue there with
the structure access.

> Did it produce an open code memcpy, and was it correct?
> 

I couldn't see any problems with the generated code - with no
optimisation memcpy was called as a normal function, under
optimisation the memcpy was replaced with the same code as the s->b =
n line produced.

> Interesting. Can you post an assembler snippet of this?
> 
I created an executable and made it report the alignment -
I used your test case and declared a variable of the packed structure then did
    printf("Address of a = %p\n", &test.a);
    printf("Address of b = %p\n", &test.b);
with interesting differences between gcc 3 and 4.

On further consideration i'd also add
    printf("Address of test = %p\n", &test);
just to see if it showed up anything interesting.

If I had more time I'd investigate where gcc 4 is putting this
variable in memory, I have a small concern that it may be leaving
padding bytes on the stack to align the structure, I'm not sure it's a
big issue though (it definitely isn't to me anyway since we're using
2.95.3 and the unmentionable 2.96 ;o) ).

Not sure any of this helps with the memcpy alignment issue though.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-05  8:41   ` Carl Whitwell
@ 2005-08-05 16:09     ` Shaun Jackman
  0 siblings, 0 replies; 35+ messages in thread
From: Shaun Jackman @ 2005-08-05 16:09 UTC (permalink / raw)
  To: Carl Whitwell; +Cc: gcc

On 8/5/05, Carl Whitwell <carl.whitwell@gmail.com> wrote:
> On 8/4/05, Shaun Jackman <sjackman@gmail.com> wrote:
> > Are you using an x86 host and an arm target?
> 
> Actually no, my major concern at the time was the large quantity of
> legacy code with packed structures that we have on an embedded linux
> x86 system. I was just testing that we didn't have an issue there with
> the structure access.

The x86 includes hardware to fetch a word from an unaligned address by
fetching from two aligned address and shifting and combining to
produce the correct result. So, unaligned accesses on the x86 might
effect a slight performance hit, but they will still act correctly.
The ARM on the other hand does not include such hardware, so a load
instruction fetching from an unaligned address will behave
incorrectly. My primary concern is really just code correctness.

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-03 18:00                   ` Richard Henderson
  2005-08-03 18:15                     ` Shaun Jackman
  2005-08-04  4:42                     ` Ian Lance Taylor
@ 2005-08-04 12:40                     ` Paul Koning
  2 siblings, 0 replies; 35+ messages in thread
From: Paul Koning @ 2005-08-04 12:40 UTC (permalink / raw)
  To: rth; +Cc: ian, pinskia, mrs, dave.korn, gcc, sjackman

>>>>> "Richard" == Richard Henderson <rth@redhat.com> writes:

 >> > No it is not, once you take the address (which should be
 >> rejected), it > is of type "unsigned int *" and not unaligned
 >> variable, passing it to > memcpy assumes the type alignment is the
 >> natural alignment.
 >> 
 >> That argument doesn't make sense to me.

 Richard> It is nevertheless correct.  Examine all of the parts of the
 Richard> expression.

 Richard> In particular, "&s->b".  What type does it have?  In an
 Richard> ideal world, it would be "pointer to unaligned integer".
 Richard> But we have no such type in our type system, so it is
 Richard> "pointer to integer".  This expression is ONLY THEN passed
 Richard> to memcpy.  At which point we query the argument for its
 Richard> alignment, and get the non-intuitive result.

The underlying problem is that the type system in GCC isn't right.

The C type system has data of various kinds, pointers to them,
structures made up of the above, etc.  GCC extends the type system by
introducing selectable alignment.  But it doesn't do it consistently.
We have int, we have *int, we have packed int, but we don't have 
*packed int.

So the outcome is "correct" only if you treat GCC's incomplete type
system as correct, which I don't agree with.  This does mean,
unfortunately, that the fix is to correct that incompleteness, which
was said to be a nontrivial task.

    paul

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-03 18:00                   ` Richard Henderson
  2005-08-03 18:15                     ` Shaun Jackman
@ 2005-08-04  4:42                     ` Ian Lance Taylor
  2005-08-04 12:40                     ` Paul Koning
  2 siblings, 0 replies; 35+ messages in thread
From: Ian Lance Taylor @ 2005-08-04  4:42 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Andrew Pinski, Mike Stump, Dave Korn, Paul Koning, gcc, Shaun Jackman

Richard Henderson <rth@redhat.com> writes:

> On Tue, Aug 02, 2005 at 01:45:01PM -0700, Ian Lance Taylor wrote:
> > Andrew Pinski <pinskia@physics.uc.edu> writes:
> > 
> > > > Yes, this is a compiler bug in the expansion of memcpy, please file a  
> > > > bug report.  The solution is for the compiler to notice the memory  
> > > > alignment of the destination and `do-the-right-thing' when it isn't  
> > > > aligned.
> > > 
> > > No it is not, once you take the address (which should be rejected), it
> > > is of type "unsigned int *" and not unaligned variable, passing it to
> > > memcpy assumes the type alignment is the natural alignment.
> > 
> > That argument doesn't make sense to me.
> 
> It is nevertheless correct.  Examine all of the parts of the expression.
> 
> In particular, "&s->b".  What type does it have?  In an ideal world, it
> would be "pointer to unaligned integer".  But we have no such type in
> our type system, so it is "pointer to integer".  This expression is ONLY
> THEN passed to memcpy.  At which point we query the argument for its
> alignment, and get the non-intuitive result.

That's a good explanation for what gcc is doing, and I do now
understand better than I did before.  But I thought Andrew was arguing
that gcc's behaviour is correct, and is not a compiler bug.  I still
think that gcc's behaviour here is not correct.  It is clear that if
gcc did not open code memcpy, the right thing would happen.  If gcc
open codes memcpy in such a way that it makes an incorrect assumption
about alignment, for whatever reason, I think that is a bug in the
compiler.

And so, since I think this is a bug which we want to fix, and since we
obviously want gcc to open code memcpy, I think that gcc has to
somehow notice the memory alignments involved.

Ian

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-03 18:15                     ` Shaun Jackman
  2005-08-03 18:19                       ` Dave Korn
@ 2005-08-03 21:26                       ` Richard Henderson
  1 sibling, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2005-08-03 21:26 UTC (permalink / raw)
  To: Shaun Jackman
  Cc: Ian Lance Taylor, Andrew Pinski, Mike Stump, Dave Korn, Paul Koning, gcc

On Wed, Aug 03, 2005 at 12:15:05PM -0600, Shaun Jackman wrote:
> I'm not sure I understood the last line. s is a structure, and its
> address is aligned. How would you pass it to memcpy, and why would it
> generate an unaligned copy?

In the example I was replying to, S is a pointer to a structure,
and it wasn't aligned.


r~

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: memcpy to an unaligned address
  2005-08-03 18:15                     ` Shaun Jackman
@ 2005-08-03 18:19                       ` Dave Korn
  2005-08-03 21:26                       ` Richard Henderson
  1 sibling, 0 replies; 35+ messages in thread
From: Dave Korn @ 2005-08-03 18:19 UTC (permalink / raw)
  To: 'Shaun Jackman', 'Richard Henderson'
  Cc: 'Ian Lance Taylor', 'Andrew Pinski',
	'Mike Stump', 'Paul Koning',
	gcc

----Original Message----
>From: Shaun Jackman
>Sent: 03 August 2005 19:15

> On 8/3/05, Richard Henderson <rth@redhat.com> wrote:
>> It is nevertheless correct.  Examine all of the parts of the expression.
>> 
>> In particular, "&s->b".  What type does it have?  In an ideal world, it
>> would be "pointer to unaligned integer".  But we have no such type in
>> our type system, so it is "pointer to integer".  This expression is ONLY
>> THEN passed to memcpy.  At which point we query the argument for its
>> alignment, and get the non-intuitive result.
>> 
>> If you instead pass "s" to memcpy, you should get the correct unaligned
>> copy.  If that isn't happening, that's a bug.
> 
> I'm not sure I understood the last line. s is a structure,

  Not if "&s->b" makes any sense it isn't!


    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-03 18:00                   ` Richard Henderson
@ 2005-08-03 18:15                     ` Shaun Jackman
  2005-08-03 18:19                       ` Dave Korn
  2005-08-03 21:26                       ` Richard Henderson
  2005-08-04  4:42                     ` Ian Lance Taylor
  2005-08-04 12:40                     ` Paul Koning
  2 siblings, 2 replies; 35+ messages in thread
From: Shaun Jackman @ 2005-08-03 18:15 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Ian Lance Taylor, Andrew Pinski, Mike Stump, Dave Korn, Paul Koning, gcc

On 8/3/05, Richard Henderson <rth@redhat.com> wrote:
> It is nevertheless correct.  Examine all of the parts of the expression.
> 
> In particular, "&s->b".  What type does it have?  In an ideal world, it
> would be "pointer to unaligned integer".  But we have no such type in
> our type system, so it is "pointer to integer".  This expression is ONLY
> THEN passed to memcpy.  At which point we query the argument for its
> alignment, and get the non-intuitive result.
> 
> If you instead pass "s" to memcpy, you should get the correct unaligned
> copy.  If that isn't happening, that's a bug.

I'm not sure I understood the last line. s is a structure, and its
address is aligned. How would you pass it to memcpy, and why would it
generate an unaligned copy?

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:45                 ` Ian Lance Taylor
  2005-08-02 21:30                   ` Mike Stump
@ 2005-08-03 18:00                   ` Richard Henderson
  2005-08-03 18:15                     ` Shaun Jackman
                                       ` (2 more replies)
  1 sibling, 3 replies; 35+ messages in thread
From: Richard Henderson @ 2005-08-03 18:00 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: Andrew Pinski, Mike Stump, Dave Korn, Paul Koning, gcc, Shaun Jackman

On Tue, Aug 02, 2005 at 01:45:01PM -0700, Ian Lance Taylor wrote:
> Andrew Pinski <pinskia@physics.uc.edu> writes:
> 
> > > Yes, this is a compiler bug in the expansion of memcpy, please file a  
> > > bug report.  The solution is for the compiler to notice the memory  
> > > alignment of the destination and `do-the-right-thing' when it isn't  
> > > aligned.
> > 
> > No it is not, once you take the address (which should be rejected), it
> > is of type "unsigned int *" and not unaligned variable, passing it to
> > memcpy assumes the type alignment is the natural alignment.
> 
> That argument doesn't make sense to me.

It is nevertheless correct.  Examine all of the parts of the expression.

In particular, "&s->b".  What type does it have?  In an ideal world, it
would be "pointer to unaligned integer".  But we have no such type in
our type system, so it is "pointer to integer".  This expression is ONLY
THEN passed to memcpy.  At which point we query the argument for its
alignment, and get the non-intuitive result.

If you instead pass "s" to memcpy, you should get the correct unaligned
copy.  If that isn't happening, that's a bug.


r~

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 22:17                   ` Shaun Jackman
@ 2005-08-03 17:16                     ` Paul Koning
  0 siblings, 0 replies; 35+ messages in thread
From: Paul Koning @ 2005-08-03 17:16 UTC (permalink / raw)
  To: sjackman; +Cc: pinskia, mrs, dave.korn, gcc

>>>>> "Shaun" == Shaun Jackman <sjackman@gmail.com> writes:

 Shaun> On 8/2/05, Paul Koning <pkoning@equallogic.com> wrote:
 >> It sounds like the workaround is to avoid memcpy, and just use
 >> variable assignment.  Alternatively, cast the pointers to char*,
 >> which should force memcpy to do the right thing.  Ugh.

 Shaun> I swear originally, back in the gcc 2.95 days, I used memcpy
 Shaun> because the memcpy function checked for unaligned pointers,
 Shaun> whereas storing to and loading from unaligned variables
 Shaun> generated a simple store/load instruction which wouldn't
 Shaun> work. It seems the tables have turned and the exact opposite
 Shaun> is true now with gcc 4, where memcpy doesn't work, but
 Shaun> unaligned variables do. I believe gcc 3 behaved the same as
 Shaun> gcc 2 -- memcpy worked, unaligned variables didn't work. Can
 Shaun> someone confirm this summary is correct?

I'm pretty sure I have used unaligned load/store with gcc 2 as well as
3 and it works correctly.  Certainly it should work correctly.  If you
tell GCC to pack stuff, and it does (assigning odd offsets in the
process) then GCC is responsible for generating code to cope with
that.  All this assuming you're not playing games with pointer
arithmetic to generate pointers that are less aligned than what GCC is
entitled to assume.  If you saw something else, that would have been a
GCC bug.

    paul

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 22:26                   ` Shaun Jackman
@ 2005-08-02 22:29                     ` Shaun Jackman
  0 siblings, 0 replies; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 22:29 UTC (permalink / raw)
  To: Paul Koning; +Cc: pinskia, mrs, dave.korn, gcc

On 8/2/05, Shaun Jackman <sjackman@gmail.com> wrote:
> operator. None of these examples produce an unaligned load:

I should clarify the wording I'm using here. By "an unaligned load" I
mean code to safely load from an unaligned pointer.

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:46                 ` Paul Koning
  2005-08-02 22:17                   ` Shaun Jackman
@ 2005-08-02 22:26                   ` Shaun Jackman
  2005-08-02 22:29                     ` Shaun Jackman
  1 sibling, 1 reply; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 22:26 UTC (permalink / raw)
  To: Paul Koning; +Cc: pinskia, mrs, dave.korn, gcc

On 8/2/05, Paul Koning <pkoning@equallogic.com> wrote:
> It sounds like the workaround is to avoid memcpy, and just use
> variable assignment.  Alternatively, cast the pointers to char*, which
> should force memcpy to do the right thing.  Ugh.

Casting to void* does not work either. gcc keeps the alignment
information -- but not the *unalignment* information, if that
distinction makes any sense -- of a particular variable around as long
as it can, through casts and even through assignment. The unalignment
information, on the other hand, is lost immediately after the &
operator. None of these examples produce an unaligned load:

	memcpy(&s->b, &n, sizeof n);

	memcpy((void*)&s->b, &n, sizeof n);

	void *p = &s->b;
	memcpy(p, &n, sizeof n);

But as pointed out by others, this does produce an unaligned load:

	s->b = n;

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:46                 ` Paul Koning
@ 2005-08-02 22:17                   ` Shaun Jackman
  2005-08-03 17:16                     ` Paul Koning
  2005-08-02 22:26                   ` Shaun Jackman
  1 sibling, 1 reply; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 22:17 UTC (permalink / raw)
  To: Paul Koning; +Cc: pinskia, mrs, dave.korn, gcc

On 8/2/05, Paul Koning <pkoning@equallogic.com> wrote:
> It sounds like the workaround is to avoid memcpy, and just use
> variable assignment.  Alternatively, cast the pointers to char*, which
> should force memcpy to do the right thing.  Ugh.

I swear originally, back in the gcc 2.95 days, I used memcpy because
the memcpy function checked for unaligned pointers, whereas storing to
and loading from unaligned variables generated a simple store/load
instruction which wouldn't work. It seems the tables have turned and
the exact opposite is true now with gcc 4, where memcpy doesn't work,
but unaligned variables do. I believe gcc 3 behaved the same as gcc 2
-- memcpy worked, unaligned variables didn't work. Can someone confirm
this summary is correct?

It seems to me there's an argument for a _memcpy_unaligned(3)
function, as ugly as that is.

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 21:11                   ` Joe Buck
@ 2005-08-02 22:15                     ` Shaun Jackman
  2005-08-02 22:12                       ` Joe Buck
  0 siblings, 1 reply; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 22:15 UTC (permalink / raw)
  To: Joe Buck; +Cc: Mike Stump, Andrew Pinski, Dave Korn, Paul Koning, gcc

On 8/2/05, Joe Buck <Joe.Buck@synopsys.com> wrote:
> I suppose we could make & on an unaligned project return a void*.  That
> isn't really right, but it would at least prevent the cases that we know
> don't work from compiling.

That sounds like a dangerous idea only because I'd expect...
	int *p = &packed_struct.unaligned_member;
... to fail if unaligned_member is not an int, but if the & operator
returns a void*, it would suddenly become very permissive.

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 22:15                     ` Shaun Jackman
@ 2005-08-02 22:12                       ` Joe Buck
  0 siblings, 0 replies; 35+ messages in thread
From: Joe Buck @ 2005-08-02 22:12 UTC (permalink / raw)
  To: Shaun Jackman; +Cc: Mike Stump, Andrew Pinski, Dave Korn, Paul Koning, gcc

On Tue, Aug 02, 2005 at 04:07:00PM -0600, Shaun Jackman wrote:
> On 8/2/05, Joe Buck <Joe.Buck@synopsys.com> wrote:
> > I suppose we could make & on an unaligned project return a void*.  That
> > isn't really right, but it would at least prevent the cases that we know
> > don't work from compiling.
> 
> That sounds like a dangerous idea only because I'd expect...
> 	int *p = &packed_struct.unaligned_member;
> ... to fail if unaligned_member is not an int, but if the & operator
> returns a void*, it would suddenly become very permissive.

Ah.  I was thinking as a C++ programmer, where void* cannot be assigned to
int* without an explicit cast.  The decision to allow this in C was the
worst mistake the standards committee made.

The problem is that the type returned by malloc is not just any void*,
but a special pointer that is guaranteed to have alignment sufficient
to store any type.  This is very different from the type of the arguments
to memcpy, which is assumed to have no alignment that can be counted on.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 21:30                   ` Mike Stump
@ 2005-08-02 21:34                     ` Joe Buck
  0 siblings, 0 replies; 35+ messages in thread
From: Joe Buck @ 2005-08-02 21:34 UTC (permalink / raw)
  To: Mike Stump
  Cc: Ian Lance Taylor, Andrew Pinski, Dave Korn, Paul Koning, gcc,
	Shaun Jackman

On Tue, Aug 02, 2005 at 02:29:44PM -0700, Mike Stump wrote:
> On Aug 2, 2005, at 1:45 PM, Ian Lance Taylor wrote:
> >That argument doesn't make sense to me.  memcpy takes a void*
> >argument, which has no presumed alignment.
> 
> The memcpy builtin uses the static type of the actual argument  
> (before conversion to void*), to gain hints about the alignments of  
> the data coming in.  This is so that we can producing nice fast code  
> for 1-16 bytes objects.  This is actually good.  The real problem is  
> formation of the address of the member doesn't produce a pointer to  
> unaligned type, but rather a pointer to aligned type, this is the  
> part that is wrong.  We'd have to add pointers to unaligned data to  
> our type system to fix it.  That should be done, but is a hard/big  
> job, and no one has stepped forward to do it.

So my suggestion to just make pointers to unaligned objects void* would
work in this case, then.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:45                 ` Ian Lance Taylor
@ 2005-08-02 21:30                   ` Mike Stump
  2005-08-02 21:34                     ` Joe Buck
  2005-08-03 18:00                   ` Richard Henderson
  1 sibling, 1 reply; 35+ messages in thread
From: Mike Stump @ 2005-08-02 21:30 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: Andrew Pinski, Dave Korn, Paul Koning, gcc, Shaun Jackman

On Aug 2, 2005, at 1:45 PM, Ian Lance Taylor wrote:
> That argument doesn't make sense to me.  memcpy takes a void*
> argument, which has no presumed alignment.

The memcpy builtin uses the static type of the actual argument  
(before conversion to void*), to gain hints about the alignments of  
the data coming in.  This is so that we can producing nice fast code  
for 1-16 bytes objects.  This is actually good.  The real problem is  
formation of the address of the member doesn't produce a pointer to  
unaligned type, but rather a pointer to aligned type, this is the  
part that is wrong.  We'd have to add pointers to unaligned data to  
our type system to fix it.  That should be done, but is a hard/big  
job, and no one has stepped forward to do it.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 21:05                 ` Mike Stump
@ 2005-08-02 21:11                   ` Joe Buck
  2005-08-02 22:15                     ` Shaun Jackman
  0 siblings, 1 reply; 35+ messages in thread
From: Joe Buck @ 2005-08-02 21:11 UTC (permalink / raw)
  To: Mike Stump; +Cc: Andrew Pinski, Dave Korn, Paul Koning, gcc, Shaun Jackman

On Tue, Aug 02, 2005 at 02:04:16PM -0700, Mike Stump wrote:
> Shaun, want to do up an entry in the manual describing this?  We have  
> known about this for years and years, but, we don't do a good job  
> communicating it to users.  Essentially, & doesn't work as one would  
> expect on unaligned data, as it produces a pointer to an aligned  
> object instead of a pointer to unaligned object.

I suppose we could make & on an unaligned project return a void*.  That
isn't really right, but it would at least prevent the cases that we know
don't work from compiling.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:38               ` Andrew Pinski
  2005-08-02 20:45                 ` Ian Lance Taylor
  2005-08-02 20:46                 ` Paul Koning
@ 2005-08-02 21:05                 ` Mike Stump
  2005-08-02 21:11                   ` Joe Buck
  2 siblings, 1 reply; 35+ messages in thread
From: Mike Stump @ 2005-08-02 21:05 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Dave Korn, Paul Koning, gcc, Shaun Jackman

On Aug 2, 2005, at 1:37 PM, Andrew Pinski wrote:
> No it is not,

:-)  Ah, yes, the old, we don't have pointers to unaligned types  
problem...  anyway, we can at least agree that this is a gapping hole  
people can drive trucks though in the type system, but I'm still  
claiming it isn't a feature on theoretic grounds.

:-(

Shaun, want to do up an entry in the manual describing this?  We have  
known about this for years and years, but, we don't do a good job  
communicating it to users.  Essentially, & doesn't work as one would  
expect on unaligned data, as it produces a pointer to an aligned  
object instead of a pointer to unaligned object.  Essentially, we  
don't have a type system that contains pointer to unaligned types.   
The compiler then goes on to make codegen choices based upon the fact  
that the data are known to be aligned, and bad things happen.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:38               ` Andrew Pinski
  2005-08-02 20:45                 ` Ian Lance Taylor
@ 2005-08-02 20:46                 ` Paul Koning
  2005-08-02 22:17                   ` Shaun Jackman
  2005-08-02 22:26                   ` Shaun Jackman
  2005-08-02 21:05                 ` Mike Stump
  2 siblings, 2 replies; 35+ messages in thread
From: Paul Koning @ 2005-08-02 20:46 UTC (permalink / raw)
  To: pinskia; +Cc: mrs, dave.korn, gcc, sjackman

>>>>> "Andrew" == Andrew Pinski <pinskia@physics.uc.edu> writes:

 >> Yes, this is a compiler bug in the expansion of memcpy, please
 >> file a bug report.  The solution is for the compiler to notice the
 >> memory alignment of the destination and `do-the-right-thing' when
 >> it isn't aligned.

 Andrew> No it is not, once you take the address (which should be
 Andrew> rejected), it is of type "unsigned int *" and not unaligned
 Andrew> variable, passing it to memcpy assumes the type alignment is
 Andrew> the natural alignment.

That seems like a misfeature.

It sounds like the workaround is to avoid memcpy, and just use
variable assignment.  Alternatively, cast the pointers to char*, which
should force memcpy to do the right thing.  Ugh.

       paul

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:38               ` Andrew Pinski
@ 2005-08-02 20:45                 ` Ian Lance Taylor
  2005-08-02 21:30                   ` Mike Stump
  2005-08-03 18:00                   ` Richard Henderson
  2005-08-02 20:46                 ` Paul Koning
  2005-08-02 21:05                 ` Mike Stump
  2 siblings, 2 replies; 35+ messages in thread
From: Ian Lance Taylor @ 2005-08-02 20:45 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Mike Stump, Dave Korn, Paul Koning, gcc, Shaun Jackman

Andrew Pinski <pinskia@physics.uc.edu> writes:

> > Yes, this is a compiler bug in the expansion of memcpy, please file a  
> > bug report.  The solution is for the compiler to notice the memory  
> > alignment of the destination and `do-the-right-thing' when it isn't  
> > aligned.
> 
> No it is not, once you take the address (which should be rejected), it
> is of type "unsigned int *" and not unaligned variable, passing it to
> memcpy assumes the type alignment is the natural alignment.

That argument doesn't make sense to me.  memcpy takes a void*
argument, which has no presumed alignment.  The builtin should work
the same way.  That is, there is an implicit cast to void* in the
argument to memcpy.  The compiler can certainly take advantage of any
knowledge it has about the alignment, but it can't assume anything
about the alignment that it doesn't already know.

Ian

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:29             ` Mike Stump
@ 2005-08-02 20:38               ` Andrew Pinski
  2005-08-02 20:45                 ` Ian Lance Taylor
                                   ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Andrew Pinski @ 2005-08-02 20:38 UTC (permalink / raw)
  To: Mike Stump; +Cc: Dave Korn, Paul Koning, gcc, Shaun Jackman

> 
> On Aug 2, 2005, at 1:15 PM, Shaun Jackman wrote:
> > There is no padding. The structure is defined as
> > __attribute__((packed)) to explicitly remove the padding. The result
> > is that gcc knows the unaligned four byte member is at an offset of
> > two bytes from the base of the struct, but uses a four byte load at
> > the unaligned address of base+2. I don't expect...
> >     p->unaligned = n;
> > ... to work,
> 
> Actually, that works just fine, with:
> 
> typedef struct {
>    unsigned short int a;
>    unsigned int b;
> } __attribute__((packed)) st;
> 
> void foo(st *s, int n)
> {
>    s->b = n;
> }
> 
> Ah, I was having trouble getting it to fail for me...  Now I can:
> 
> #include <memory.h>
> 
> typedef struct {
>    unsigned short int a;
>    unsigned int b;
> } __attribute__((packed)) st;
> 
> void foo(st *s, int n)
> {
>    memcpy(&s->b, &n, sizeof n);
> }
> 
> Yes, this is a compiler bug in the expansion of memcpy, please file a  
> bug report.  The solution is for the compiler to notice the memory  
> alignment of the destination and `do-the-right-thing' when it isn't  
> aligned.

No it is not, once you take the address (which should be rejected), it
is of type "unsigned int *" and not unaligned variable, passing it to
memcpy assumes the type alignment is the natural alignment.

-- Pinski

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:15           ` Shaun Jackman
@ 2005-08-02 20:29             ` Mike Stump
  2005-08-02 20:38               ` Andrew Pinski
  2005-08-02 20:29             ` Paul Koning
  1 sibling, 1 reply; 35+ messages in thread
From: Mike Stump @ 2005-08-02 20:29 UTC (permalink / raw)
  To: Shaun Jackman; +Cc: Dave Korn, Paul Koning, gcc

On Aug 2, 2005, at 1:15 PM, Shaun Jackman wrote:
> There is no padding. The structure is defined as
> __attribute__((packed)) to explicitly remove the padding. The result
> is that gcc knows the unaligned four byte member is at an offset of
> two bytes from the base of the struct, but uses a four byte load at
> the unaligned address of base+2. I don't expect...
>     p->unaligned = n;
> ... to work,

Actually, that works just fine, with:

typedef struct {
   unsigned short int a;
   unsigned int b;
} __attribute__((packed)) st;

void foo(st *s, int n)
{
   s->b = n;
}

I get:

_foo:
         @ args = 0, pretend = 0, frame = 0
         @ frame_needed = 0, uses_anonymous_args = 0
         @ link register save eliminated.
         mov     r3, r1, lsr #24
         mov     r2, r1, lsr #8
         mov     ip, r1, lsr #16
         @ lr needed for prologue
         strb    r3, [r0, #5]
         strb    r2, [r0, #3]
         strb    ip, [r0, #4]
         strb    r1, [r0, #2]
         mov     pc, lr

> but I definitely expect
>     memcpy(&p->unaligned, &n, sizeof p->unaligned);
> to work.

Ah, I was having trouble getting it to fail for me...  Now I can:

#include <memory.h>

typedef struct {
   unsigned short int a;
   unsigned int b;
} __attribute__((packed)) st;

void foo(st *s, int n)
{
   memcpy(&s->b, &n, sizeof n);
}

_foo:
         @ args = 0, pretend = 0, frame = 4
         @ frame_needed = 0, uses_anonymous_args = 0
         @ link register save eliminated.
         sub     sp, sp, #4
         @ lr needed for prologue
         str     r1, [r0, #2]
         add     sp, sp, #4
         bx      lr

Yes, this is a compiler bug in the expansion of memcpy, please file a  
bug report.  The solution is for the compiler to notice the memory  
alignment of the destination and `do-the-right-thing' when it isn't  
aligned.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 20:15           ` Shaun Jackman
  2005-08-02 20:29             ` Mike Stump
@ 2005-08-02 20:29             ` Paul Koning
  1 sibling, 0 replies; 35+ messages in thread
From: Paul Koning @ 2005-08-02 20:29 UTC (permalink / raw)
  To: sjackman; +Cc: dave.korn, gcc

>>>>> "Shaun" == Shaun Jackman <sjackman@gmail.com> writes:

 >> 2) Is there padding between the struct members to maintain their
 >> natural alignments (on the assumption that the struct's base
 >> address is aligned.)

 Shaun> There is no padding. The structure is defined as
 Shaun> __attribute__((packed)) to explicitly remove the padding. The
 Shaun> result is that gcc knows the unaligned four byte member is at
 Shaun> an offset of two bytes from the base of the struct, but uses a
 Shaun> four byte load at the unaligned address of base+2. I don't
 Shaun> expect...
 Shaun>		 p-> unaligned = n;
 Shaun> ... to work, ...

I would.  If you tell gcc that a thing is unaligned, it is responsible
for doing unaligned references to it.  That very definitely includes
direct references to the content in expressions.  And in general that
works.  Clearly there is a GCC bug here; GCC put the field at an
unaligned offset, but did not do unaligned references to it.

	  paul

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 19:40         ` Dave Korn
  2005-08-02 19:48           ` Paul Koning
@ 2005-08-02 20:15           ` Shaun Jackman
  2005-08-02 20:29             ` Mike Stump
  2005-08-02 20:29             ` Paul Koning
  1 sibling, 2 replies; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 20:15 UTC (permalink / raw)
  To: Dave Korn; +Cc: Paul Koning, gcc

On 8/2/05, Dave Korn <dave.korn@artimi.com> wrote:
>   There are two separate issues here:
> 
> 1)  Is the base of the struct aligned to the natural alignment, or can the
> struct be based at any address

The base of the struct is aligned to the natural alignment, four bytes
in this case.
 
> 2)  Is there padding between the struct members to maintain their natural
> alignments (on the assumption that the struct's base address is aligned.)

There is no padding. The structure is defined as
__attribute__((packed)) to explicitly remove the padding. The result
is that gcc knows the unaligned four byte member is at an offset of
two bytes from the base of the struct, but uses a four byte load at
the unaligned address of base+2. I don't expect...
	p->unaligned = n;
... to work, but I definitely expect
	memcpy(&p->unaligned, &n, sizeof p->unaligned);
to work. The second case is being optimised to the first case though
and generating and unaligned store.

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: memcpy to an unaligned address
  2005-08-02 19:40         ` Dave Korn
@ 2005-08-02 19:48           ` Paul Koning
  2005-08-02 20:15           ` Shaun Jackman
  1 sibling, 0 replies; 35+ messages in thread
From: Paul Koning @ 2005-08-02 19:48 UTC (permalink / raw)
  To: dave.korn; +Cc: sjackman, gcc

>>>>> "Dave" == Dave Korn <dave.korn@artimi.com> writes:

 Dave> ----Original Message----
 >> From: Shaun Jackman Sent: 02 August 2005 20:26

 >> On 8/2/05, Paul Koning <pkoning@equallogic.com> wrote:
 >>> One of the things that continues to baffle me (and my colleagues)
 >>> is the bizarre way in which attributes such as "packed" work when
 >>> applied to structs.
 >>> 
 >>> It would be natural to assume, as Shaun did, that marking a
 >>> struct "packed" (or, for that matter, "packed,aligned(2)") would
 >>> apply that attribute to the fields of the struct.
 >>  This is exactly the behaviour suggested by the info docs:
 >> 
 >> $ info gcc 'C Ext' 'Type Attr' ...  Specifying this attribute for
 >> `struct' and `union' types is equivalent to specifying the
 >> `packed' attribute on each of the structure or union members.
 >> 


 Dave> There are two separate issues here:

 Dave> 1) Is the base of the struct aligned to the natural alignment,
 Dave> or can the struct be based at any address

 Dave> 2) Is there padding between the struct members to maintain
 Dave> their natural alignments (on the assumption that the struct's
 Dave> base address is aligned.)

Sure.  But in Shaun's case it looks like (2) has been applied, except
that the compiler doesn't adjust the generated code correctly.  I
would argue that "packed" applied to a whole struct should produce
BOTH effects 1 and 2.

There's a third case for which there appears to be no notation:

3) A pointer to a T that doesn't have the normal alignment of 
   the type T.

For example, as far as I can tell, GCC offers no way to say "pointer
to unaligned int" -- short of creating a one-member struct.

   paul

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: memcpy to an unaligned address
  2005-08-02 19:26       ` Shaun Jackman
@ 2005-08-02 19:40         ` Dave Korn
  2005-08-02 19:48           ` Paul Koning
  2005-08-02 20:15           ` Shaun Jackman
  0 siblings, 2 replies; 35+ messages in thread
From: Dave Korn @ 2005-08-02 19:40 UTC (permalink / raw)
  To: 'Shaun Jackman', 'Paul Koning'; +Cc: gcc

----Original Message----
>From: Shaun Jackman
>Sent: 02 August 2005 20:26

> On 8/2/05, Paul Koning <pkoning@equallogic.com> wrote:
>> One of the things that continues to baffle me (and my colleagues) is
>> the bizarre way in which attributes such as "packed" work when applied
>> to structs. 
>> 
>> It would be natural to assume, as Shaun did, that marking a struct
>> "packed" (or, for that matter, "packed,aligned(2)") would apply that
>> attribute to the fields of the struct.
> 
> This is exactly the behaviour suggested by the info docs:
> 
> $ info gcc 'C Ext' 'Type Attr'
> ...
>      Specifying this attribute for `struct' and `union' types is
>      equivalent to specifying the `packed' attribute on each of the
>      structure or union members.
> 


  There are two separate issues here:

1)  Is the base of the struct aligned to the natural alignment, or can the
struct be based at any address

2)  Is there padding between the struct members to maintain their natural
alignments (on the assumption that the struct's base address is aligned.)

  I think this is where some of the ambiguity in the docs comes from.  But
I'm about to leave the office now, so I can't go into depth with this thread
right now....


    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 19:19     ` Paul Koning
@ 2005-08-02 19:26       ` Shaun Jackman
  2005-08-02 19:40         ` Dave Korn
  0 siblings, 1 reply; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 19:26 UTC (permalink / raw)
  To: Paul Koning; +Cc: dave.korn, gcc

On 8/2/05, Paul Koning <pkoning@equallogic.com> wrote:
> One of the things that continues to baffle me (and my colleagues) is
> the bizarre way in which attributes such as "packed" work when applied
> to structs.
> 
> It would be natural to assume, as Shaun did, that marking a struct
> "packed" (or, for that matter, "packed,aligned(2)") would apply that
> attribute to the fields of the struct.

This is exactly the behaviour suggested by the info docs:

$ info gcc 'C Ext' 'Type Attr'
...
     Specifying this attribute for `struct' and `union' types is
     equivalent to specifying the `packed' attribute on each of the
     structure or union members.

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 19:13   ` Shaun Jackman
@ 2005-08-02 19:19     ` Paul Koning
  2005-08-02 19:26       ` Shaun Jackman
  0 siblings, 1 reply; 35+ messages in thread
From: Paul Koning @ 2005-08-02 19:19 UTC (permalink / raw)
  To: sjackman; +Cc: dave.korn, gcc

One of the things that continues to baffle me (and my colleagues) is
the bizarre way in which attributes such as "packed" work when applied
to structs.

It would be natural to assume, as Shaun did, that marking a struct
"packed" (or, for that matter, "packed,aligned(2)") would apply that
attribute to the fields of the struct.

But it doesn't work that way.  To get the right results, you have to
stick attributes all over the structure fields, one by one.  This is
highly counterintuive.

Worse yet, in this example the attribute is applied to the structure
elements to some extent but not consistently -- it causes the fields
to be packed -- hence unaligned -- but it does not do unaligned
accesses to the fields.

This sure looks like a bug.

     paul

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 17:43 ` Dave Korn
@ 2005-08-02 19:13   ` Shaun Jackman
  2005-08-02 19:19     ` Paul Koning
  0 siblings, 1 reply; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 19:13 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

On 8/2/05, Dave Korn <dave.korn@artimi.com> wrote:
>   In order for anyone to answer your questions about the alignment of
> various types in a struct, don't you think you should perhaps have told us a
> little about what those types actually are and how the struct is laid out?

Of course, my apologies. I was clearly overly terse. I declare the
structure packed as follows:

typedef struct {
	uint16_t a;
	uint32_t b;
} __attribute__((packed)) st;

void foo(st *s, int n)
{
	memcpy(&s->b, &n, sizeof n);
}

This code generates the unaligend store:
$ arm-elf-objdump -d packed.o
...
   0:   e24dd004        sub     sp, sp, #4      ; 0x4
   4:   e5801002        str     r1, [r0, #2]
   8:   e28dd004        add     sp, sp, #4      ; 0x4
   c:   e12fff1e        bx      lr
$ arm-elf-gcc --version | head -1
arm-elf-gcc (GCC) 4.0.1

Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 17:32 Shaun Jackman
  2005-08-02 17:43 ` Dave Korn
  2005-08-02 17:48 ` Falk Hueffner
@ 2005-08-02 18:03 ` Mike Stump
  2 siblings, 0 replies; 35+ messages in thread
From: Mike Stump @ 2005-08-02 18:03 UTC (permalink / raw)
  To: Shaun Jackman; +Cc: GCC Development

On Aug 2, 2005, at 10:32 AM, Shaun Jackman wrote:
> In a typical Ethernet/IP ARP header the source IP address is
> unaligned. Instead of using...
>     out->srcIPAddr = in->dstIPAddr;
> ... I used...
>     memcpy(&out->srcIPAddr, &in->dstIPAddr, sizeof(uint32_t));
> ... to account for the unaligned destination. This worked until gcc 4,
> which now generates a simple load/store.
>     ldr     r3, [r6, #24]
>     adds    r2, r4, #0
>     adds    r2, #14
>     str     r3, [r2, #0]
> A nice optimisation, but in this case it's incorrect. $r4 is aligned,
> and the result of adding #14 to $r4 is an unaligned pointer.
>
> Should gcc know better, or do I need to give it a little more
> information to help it out?

gcc-help is the correct list to ask this question on.  Anyway, I  
suspect people would be aided in helping you by seeing the source  
code and knowing what version of gcc you're using...  I suspect you  
don't mark the structure as packed and as using 1 or 2 byte  
alignment.  If you do that, then the compiler should generate the  
correct code, for example:

mrs $ cat t1.c
struct {
   char a[14];
   int i __attribute__((aligned(1), packed));
} s, d;

main() {
   d.i = s.i;
}


$ arm-gcc -O4 t1.c -S

gives:

_main:
         @ args = 0, pretend = 0, frame = 0
         @ frame_needed = 0, uses_anonymous_args = 0
         @ link register save eliminated.
         str     sl, [sp, #-4]!
         ldr     sl, .L3
         ldr     r2, .L3+4
.L2:
         add     sl, pc, sl
         ldr     ip, [sl, r2]
         ldr     r0, .L3+8
         ldrh    r1, [ip, #16]
         ldr     r2, [sl, r0]
         ldrh    r3, [ip, #14]
         @ lr needed for prologue
         strh    r1, [r2, #16]   @ movhi
         strh    r3, [r2, #14]   @ movhi
         ldmfd   sp!, {sl}
         mov     pc, lr

for me.  Notice the adding of 14, notice the two 16 bit moves instead  
of one 4 byte move.  If you lie to the compiler, it will make your  
life rough.  Telling it that it is aligned, when the data isn't  
aligned, is a lie.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: memcpy to an unaligned address
  2005-08-02 17:32 Shaun Jackman
  2005-08-02 17:43 ` Dave Korn
@ 2005-08-02 17:48 ` Falk Hueffner
  2005-08-02 18:03 ` Mike Stump
  2 siblings, 0 replies; 35+ messages in thread
From: Falk Hueffner @ 2005-08-02 17:48 UTC (permalink / raw)
  To: Shaun Jackman; +Cc: gcc

Shaun Jackman <sjackman@gmail.com> writes:

> In a typical Ethernet/IP ARP header the source IP address is
> unaligned. Instead of using...
> 	out->srcIPAddr = in->dstIPAddr;
> ... I used...
> 	memcpy(&out->srcIPAddr, &in->dstIPAddr, sizeof(uint32_t));
> ... to account for the unaligned destination. This worked until gcc 4,
> which now generates a simple load/store.
> 	ldr     r3, [r6, #24]
> 	adds    r2, r4, #0
> 	adds    r2, #14
> 	str     r3, [r2, #0]
> A nice optimisation, but in this case it's incorrect. $r4 is aligned,
> and the result of adding #14 to $r4 is an unaligned pointer.

It isn't incorrect; gcc can assume that pointers are always correctly
aligned for their type. Anything else would result in horrible code.
If your program forms a pointer that is not properly aligned, it is
already invalid, and later breakage is only a symptom of that.

-- 
	Falk

^ permalink raw reply	[flat|nested] 35+ messages in thread

* RE: memcpy to an unaligned address
  2005-08-02 17:32 Shaun Jackman
@ 2005-08-02 17:43 ` Dave Korn
  2005-08-02 19:13   ` Shaun Jackman
  2005-08-02 17:48 ` Falk Hueffner
  2005-08-02 18:03 ` Mike Stump
  2 siblings, 1 reply; 35+ messages in thread
From: Dave Korn @ 2005-08-02 17:43 UTC (permalink / raw)
  To: 'Shaun Jackman', gcc

----Original Message----
>From: Shaun Jackman
>Sent: 02 August 2005 18:33

> In a typical Ethernet/IP ARP header the source IP address is
> unaligned. Instead of using...
> 	out->srcIPAddr = in->dstIPAddr;
> ... I used...
> 	memcpy(&out->srcIPAddr, &in->dstIPAddr, sizeof(uint32_t));
> ... to account for the unaligned destination. This worked until gcc 4,
> which now generates a simple load/store.
> 	ldr     r3, [r6, #24]
> 	adds    r2, r4, #0
> 	adds    r2, #14
> 	str     r3, [r2, #0]
> A nice optimisation, but in this case it's incorrect. $r4 is aligned,
> and the result of adding #14 to $r4 is an unaligned pointer.
> 
> Should gcc know better, or do I need to give it a little more
> information to help it out?

  In order for anyone to answer your questions about the alignment of
various types in a struct, don't you think you should perhaps have told us a
little about what those types actually are and how the struct is laid out?
[*]


    cheers,
      DaveK

[*] - See debugging, psychic ;)
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 35+ messages in thread

* memcpy to an unaligned address
@ 2005-08-02 17:32 Shaun Jackman
  2005-08-02 17:43 ` Dave Korn
                   ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Shaun Jackman @ 2005-08-02 17:32 UTC (permalink / raw)
  To: gcc

In a typical Ethernet/IP ARP header the source IP address is
unaligned. Instead of using...
	out->srcIPAddr = in->dstIPAddr;
... I used...
	memcpy(&out->srcIPAddr, &in->dstIPAddr, sizeof(uint32_t));
... to account for the unaligned destination. This worked until gcc 4,
which now generates a simple load/store.
	ldr     r3, [r6, #24]
	adds    r2, r4, #0
	adds    r2, #14
	str     r3, [r2, #0]
A nice optimisation, but in this case it's incorrect. $r4 is aligned,
and the result of adding #14 to $r4 is an unaligned pointer.

Should gcc know better, or do I need to give it a little more
information to help it out?

Please cc me in your reply. Cheers,
Shaun

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2005-08-05 16:09 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <345be691050804025955c0b4ab@mail.gmail.com>
2005-08-04 15:06 ` memcpy to an unaligned address Shaun Jackman
2005-08-04 15:09   ` Christian Joensson
2005-08-05  8:41   ` Carl Whitwell
2005-08-05 16:09     ` Shaun Jackman
2005-08-02 17:32 Shaun Jackman
2005-08-02 17:43 ` Dave Korn
2005-08-02 19:13   ` Shaun Jackman
2005-08-02 19:19     ` Paul Koning
2005-08-02 19:26       ` Shaun Jackman
2005-08-02 19:40         ` Dave Korn
2005-08-02 19:48           ` Paul Koning
2005-08-02 20:15           ` Shaun Jackman
2005-08-02 20:29             ` Mike Stump
2005-08-02 20:38               ` Andrew Pinski
2005-08-02 20:45                 ` Ian Lance Taylor
2005-08-02 21:30                   ` Mike Stump
2005-08-02 21:34                     ` Joe Buck
2005-08-03 18:00                   ` Richard Henderson
2005-08-03 18:15                     ` Shaun Jackman
2005-08-03 18:19                       ` Dave Korn
2005-08-03 21:26                       ` Richard Henderson
2005-08-04  4:42                     ` Ian Lance Taylor
2005-08-04 12:40                     ` Paul Koning
2005-08-02 20:46                 ` Paul Koning
2005-08-02 22:17                   ` Shaun Jackman
2005-08-03 17:16                     ` Paul Koning
2005-08-02 22:26                   ` Shaun Jackman
2005-08-02 22:29                     ` Shaun Jackman
2005-08-02 21:05                 ` Mike Stump
2005-08-02 21:11                   ` Joe Buck
2005-08-02 22:15                     ` Shaun Jackman
2005-08-02 22:12                       ` Joe Buck
2005-08-02 20:29             ` Paul Koning
2005-08-02 17:48 ` Falk Hueffner
2005-08-02 18:03 ` Mike Stump

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).