Bug 116357 - [12/13/14/15 Regression] The item's address of the array is not correct if aligned is used
Summary: [12/13/14/15 Regression] The item's address of the array is not correct if al...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 10.2.0
: P3 normal
Target Milestone: 12.5
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2024-08-13 05:40 UTC by Alwin Zhang
Modified: 2024-09-19 03:06 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.5.0
Known to fail: 7.1.0
Last reconfirmed: 2024-09-17 00:00:00


Attachments
Test code to reproduce the issue. (260 bytes, text/x-csrc)
2024-08-13 05:40 UTC, Alwin Zhang
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alwin Zhang 2024-08-13 05:40:12 UTC
Created attachment 58922 [details]
Test code to reproduce the issue.

The item's address of the array is not correct if aligned is used on the type of array item. The debug version (without gcc optimization) doesn't have the issue, but if we enable optimization like -O1/O2, all the items of the array are using the same address.
Attached file is the test code to reproduce the issue. This issue could be reproduced from gcc 7.1 to latest 14.2.

From following asm code we can see that the items of the array are using the same address.

C code is -
------------------
u64 * l1;
u64 * l2;
void align_test(chn_t * p)
{
        l1 = (u64*)(&(p->lock[0]));
        l2 = (u64*)(&(p->lock[99]));
        printf("addr is [0]=%llu, [99]=%llu\n", l1, l2);
}
------------------

asm code is -
------------------
align_test:
        sub     rsp, 8
        mov     rsi, rdi
        mov     QWORD PTR l1[rip], rdi
        mov     QWORD PTR l2[rip], rdi
        mov     rdx, rdi
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        add     rsp, 8
        ret
------------------

Please download the test code and compile with gcc optimization like -O2 to check the issue.

Bug 65204 appears to be the same as this issue, but it's resolved. 

Thanks!
Comment 1 Andrew Pinski 2024-08-13 06:43:56 UTC
This was rejected in GCC 5.4-4.7.0 .
But produced wrong code at -O1 and above starting in GCC 7.1.0.
Comment 2 Andrew Pinski 2024-08-13 06:49:44 UTC
The linked PRs kinda of point out this is invalid code and should be rejected ...
Comment 3 Alwin Zhang 2024-08-14 01:34:11 UTC
Hi Andrew,
Do you mean that gcc should give an error like old version?
For example,
error: alignment of array elements is greater than element size
Comment 4 Alwin Zhang 2024-08-15 05:18:22 UTC
Hello experts,
What do you think about the fact that it only happens when using -O1/2/3?
It seems like the other issues linked have nothing to do with that fact.
Comment 5 Richard Biener 2024-09-17 08:36:26 UTC
The optimization issue is because we have an element type that looks like

 <integer_type 0x7ffff69b27e0 spinlock_t volatile unsigned SI
    size <integer_cst 0x7ffff6824198 type <integer_type 0x7ffff68220a8 bitsizetype> constant 32>
    unit-size <integer_cst 0x7ffff68241b0 type <integer_type 0x7ffff6822000 sizetype> constant 4>
    user align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff69b2738 precision:32 min <integer_cst 0x7ffff68241c8 0> max <integer_cst 0x7ffff6824180 4294967295>
    pointer_to_this <pointer_type 0x7ffff69dd540>>

in particular with TYPE_ALIGN > TYPE_SIZE which is a "cannot happen".  Because
ARRAY_REF records the element size in units of element alignment this ends
up as zero ...

In this case value-numbering makes ARRAY_REF OP2 explicit while keeping it
implicit ends up being "fine" (fine as in still densely packing
spinlock_t and thus giving elements wrong alignment).

I wonder whether the bug is that sizeof (spinlock_t) is 4, but of course
that might be difficult to change.  But I suppose this is also how C works;
possibly the C frontend should build a variant type of the element type
if over-alignment should be ignored - putting in the over-aligned type
most definitely breaks the middle-end with regard to how ARRAY_REF is
defined.

This is a C frontend issue, it produces wrong GENERIC.
Comment 6 Alwin Zhang 2024-09-19 01:58:08 UTC
Thank you Richard for your detailed elaboration.