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

            Bug ID: 106470
           Summary: Subscribed access to __m256i casted to (uint16_t *)
                    produces garbage or a warning
           Product: gcc
           Version: 12.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vt at altlinux dot org
  Target Milestone: ---

It's appeared in liboqs in code imported from PQClean[1]. There is minimized
reproducer:
1.
```
$ cat test1.c
#include <immintrin.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main(void)
{
        __m256i tmp = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16);
        for (size_t i = 0; i < 16; i++) {
                printf(" %04x", ((uint16_t *)&tmp)[i]);
        }
        printf("\n");
        return 0;
}
$ gcc -O2 -Wall -mavx2 -o a test1.c
$ ./a
 c040 69a1 558e 0000 68da b7f6 7fb1 0000 87d0 b7f6 7fb1 0000 0000 0000 0001
0000
```
This should been printing:
 0010 000f 000e 000d 000c 000b 000a 0009 0008 0007 0006 0005 0004 0003 0002
0001

2. If we add `#pragma GCC unroll 16` it compiles with the warning, still
printing incorrect values.
```
$ cat test2.c
#include <immintrin.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main(void)
{
        __m256i tmp = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16);
#pragma GCC unroll 16
        for (size_t i = 0; i < 16; i++) {
                printf(" %04x", ((uint16_t *)&tmp)[i]);
        }
        printf("\n");
        return 0;
}

$ gcc -O2 -Wall -mavx2 -o b test2.c
test2.c: In function ‘main’:
test2.c:10:51: warning: ‘tmp’ is used uninitialized [-Wuninitialized]
   10 |                 printf(" %04x", ((uint16_t *)&tmp)[i]);
      |                                 ~~~~~~~~~~~~~~~~~~^~~
test2.c:7:17: note: ‘tmp’ was declared here
    7 |         __m256i tmp = _mm256_set_epi16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16);
      |                 ^~~
$ ./b
 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000
```

In comparison, clang produces correct output.


[1] https://github.com/open-quantum-safe/liboqs/issues/1244

Reply via email to