Bug 45600

Summary: gcc generates illegal AVX aligned moves
Product: gcc Reporter: David Greene <greened>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: gcc-bugs, greened
Priority: P3    
Version: 4.5.1   
Target Milestone: ---   
Host: x86_64-unknown-linux-gnu Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu Known to work:
Known to fail: Last reconfirmed:
Attachments: Reduced testcase

Description David Greene 2010-09-08 16:08:12 UTC
For the attached testcase, gcc generates a vmovapd for the store to llvm_cbe__24__StackDv_P53.  The latest Intel sde generates an alignment error:

SDE ERROR: ALIGN32 FAILED PC=40048b MEMEA=7ffffff057d0 vmovapd ymmword ptr [rax], ymm0

It looks like gcc is considering 16-byte aligned data to be suitable for a 256-bit vmovapd, which it isn't.
Comment 1 David Greene 2010-09-08 16:08:36 UTC
Compile with -c -mavx reduced.c.
Comment 2 David Greene 2010-09-08 16:09:18 UTC
Created attachment 21740 [details]
Reduced testcase
Comment 3 Andrew Pinski 2010-09-08 17:39:49 UTC
I think this code is undefined with respect of alignment requirements.
Comment 4 Andrew Pinski 2010-09-08 17:43:21 UTC
Yes this is invalid with respect of alignment requirements.

It becomes obvious from the optimized at -O0 on the trunk.

  v4df llvm_cbe_r5585;
  v4df llvm_cbe_r5584;
  struct l_DV1 llvm_cbe__24__StackDv_P53;
  unsigned int * D.3215;
  struct l_DV1 * llvm_cbe__24__StackDv_P53.0;

<bb 2>:
  llvm_cbe__24__StackDv_P53.0_1 = &llvm_cbe__24__StackDv_P53;
  MEM[(v4df *)llvm_cbe__24__StackDv_P53.0_1] = llvm_cbe_r5584_2(D); // requires v4df alignment
  D.3215_3 = &llvm_cbe__24__StackDv_P53.field1.field5;
  MEM[(struct  *)D.3215_3].data = llvm_cbe_r5585_4(D); // requires v4df alignment

Comment 5 David Greene 2010-09-08 18:52:37 UTC
Why is the code undefined?  Can you explain in terms of the original test source?  I don't immediately see anything undefined there.
Comment 6 Andrew Pinski 2010-09-08 18:55:24 UTC
The alignment of llvm_cbe__24__StackDv_P53 is only 64bits so you are casting to a greater aligned type and then dereferencing it.

That being said, the LLVM C back-end produces crazy c code that is also undefined because of aliasing.
Comment 7 David Greene 2010-09-08 18:58:37 UTC
(In reply to comment #5)
> Why is the code undefined?  Can you explain in terms of the original test
> source?  I don't immediately see anything undefined there.

Ah, the cast from int field5 to v4df?  Yes, that doesn't look right to me.  Is this what you're talking about?

It seems to me that gcc should emit a warning about this and/or not assume that &field5 is aligned to 32 bytes, as there is nothing in the source specifying such alignment.

If it's an illegal program, gcc should at least emit a warning, if not an error.
Comment 8 David Greene 2010-09-08 18:59:57 UTC
(In reply to comment #6)
> The alignment of llvm_cbe__24__StackDv_P53 is only 64bits so you are casting to
> a greater aligned type and then dereferencing it.

I didn't know that typing something as a vector guaranteed alignment.  I don't see anything in the gcc manual about that.  Isn't that why we have __attribute(aligned())__?
Comment 9 Andrew Pinski 2010-09-08 19:01:03 UTC
>If it's an illegal program, gcc should at least emit a warning, if not an
error.


It is not an invalid program, it is just undefined at runtime.  There was a defect report against the C standard asking if a diagnostic can be required for undefined behavior and it was rejected.  Oh there is a patch to enable warnings for this case already.
Comment 10 Andrew Pinski 2010-09-08 19:01:38 UTC
vector types are naturally aligned just like integer types.  That is they are aligned on their size.
Comment 11 David Greene 2010-09-08 19:16:03 UTC
(In reply to comment #9)
> >If it's an illegal program, gcc should at least emit a warning, if not an
> error.
> 
> 
> It is not an invalid program,

Yes, you are quite right.  I will take this up with the LLVM folks.  :)