https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124429

            Bug ID: 124429
           Summary: Incorrect code generation for pointer-to-array access
                    under -O2 on x86_64
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: xiongzile99 at gmail dot com
  Target Milestone: ---

Created attachment 63865
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=63865&action=edit
dumped ir code

The following program produces incorrect output when compiled with -O2 using
GCC 11.3 and newer on x86_64.

When compiled with -O1 the output is correct.

The program accesses a 2D array through a pointer-to-array type (int (*)[4]).
This appears to be well-defined C: the pointer `p` has type `int (*)[4]`, which
matches the type of `array` (`int[4][4]`), and the expression `*(*(p + i) + j)`
is equivalent to `p[i][j]`.

However with -O2 the generated code produces incorrect results.

Test case
---------

#include <stdio.h>

int main() {
    int array[4][4] = {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12},
        {13,14,15,16}
    };

    int (*p)[4] = array;

    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%4d", *(*(p + i) + j));
        }
        printf("\n");
    }

    return 0;
}

Compile commands
----------------

gcc -O1 test.c
gcc -O2 test.c

Example reproduction:

gcc -O2 test.c && ./a.out

Expected output
---------------

   1   2   3   4
   5   6   7   8
   9  10  11  12
  13  14  15  16

Observed result
---------------

With -O1 the output is correct.

With -O2 incorrect values are printed.

Version testing
---------------

The issue was reproduced with the following versions of GCC:

gcc 11.3.0 : incorrect output with -O2  
gcc 12.x   : incorrect output with -O2  
gcc 13.x   : incorrect output with -O2  

The program produces correct output with:

gcc -O1 test.c
gcc -O2 -fno-strict-aliasing test.c

Additional observations
-----------------------

The issue disappears when disabling strict aliasing optimizations:

gcc -O2 -fno-strict-aliasing test.c

This suggests that the miscompilation may be related to alias analysis or a
later optimization pass relying on strict aliasing assumptions.

The program itself does not appear to violate the strict aliasing rules.  
The pointer `p` has type `int (*)[4]`, which is compatible with the type of
`array` (`int[4][4]`), and the expression

    *(*(p + i) + j)

is equivalent to

    p[i][j]

which directly indexes the original array.

Comparison with other compilers
-------------------------------

The same program produces the correct output when compiled with Clang using the
same optimization level:

clang -O2 test.c

System information
------------------

Architecture: x86_64  
Operating system: Linux  
Compiler: gcc (Debian) 11.3.0  

Full compiler version output:

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-linux-gnu/11.3.0/lto-wrapper
Target: x86_64-linux-gnu
Configured with: /usr/src/gcc/configure --build=x86_64-linux-gnu
--disable-multilib --enable-languages=c,c++,fortran,go
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.3.0 (GCC)

Notes
-----

The program does not trigger any warnings with:

gcc -O2 -Wall -Wextra -Wpedantic test.c

and does not appear to rely on undefined behavior.

The issue was observed on multiple x86_64 Linux systems.

Reply via email to