public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
@ 2022-07-28 21:51 vt at altlinux dot org
  2022-07-28 21:54 ` [Bug middle-end/106470] " pinskia at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: vt at altlinux dot org @ 2022-07-28 21:51 UTC (permalink / raw)
  To: gcc-bugs

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

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
@ 2022-07-28 21:54 ` pinskia at gcc dot gnu.org
  2022-07-28 21:58 ` pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-07-28 21:54 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
You are violating C aliasing rules.
You need a uint16_t type which is marked as may_alias. Or use memcpy or use 
-fno-strict-aliasing etc.

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
  2022-07-28 21:54 ` [Bug middle-end/106470] " pinskia at gcc dot gnu.org
@ 2022-07-28 21:58 ` pinskia at gcc dot gnu.org
  2022-07-28 22:06 ` pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-07-28 21:58 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The easiest way to fix this is to use GNU-C vectors like:


        for (size_t i = 0; i < 16; i++) {
                typedef __attribute__((vector_size(sizeof(__m256i)) )) uint16_t
myvector_t;
                myvector_t t;
                t = (myvector_t)tmp;
                printf(" %04x", t[i]);
        }

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
  2022-07-28 21:54 ` [Bug middle-end/106470] " pinskia at gcc dot gnu.org
  2022-07-28 21:58 ` pinskia at gcc dot gnu.org
@ 2022-07-28 22:06 ` pinskia at gcc dot gnu.org
  2022-07-28 22:08 ` vt at altlinux dot org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-07-28 22:06 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The other fix is to use _mm256_extract_epi16.
E.g.


inline unsigned short extract_epi16(__m256i v, int pos) {
    switch(pos){
        case 0: return _mm256_extract_epi16(v, 0);
        case 1: return _mm256_extract_epi16(v, 1);
        case 2: return _mm256_extract_epi16(v, 2);
        case 3: return _mm256_extract_epi16(v, 3);
        case 4: return _mm256_extract_epi16(v, 4);
        case 5: return _mm256_extract_epi16(v, 5);
        case 6: return _mm256_extract_epi16(v, 6);
        case 7: return _mm256_extract_epi16(v, 7);
        case 8: return _mm256_extract_epi16(v, 8);
        case 9: return _mm256_extract_epi16(v, 9);
        case 10: return _mm256_extract_epi16(v, 10);
        case 11: return _mm256_extract_epi16(v, 11);
        case 12: return _mm256_extract_epi16(v, 12);
        case 13: return _mm256_extract_epi16(v, 13);
        case 14: return _mm256_extract_epi16(v, 14);
        case 15: return _mm256_extract_epi16(v, 15);
    }
    return 0;
}

...

        for (size_t i = 0; i < 16; i++) {
                printf(" %04x", extract_epi16(tmp, i));
        }

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
                   ` (2 preceding siblings ...)
  2022-07-28 22:06 ` pinskia at gcc dot gnu.org
@ 2022-07-28 22:08 ` vt at altlinux dot org
  2022-07-28 22:16 ` vt at altlinux dot org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: vt at altlinux dot org @ 2022-07-28 22:08 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Vitaly Chikunov <vt at altlinux dot org> ---
Andrew, thanks for the quick answer and example! I wish that warning was a bit
more enlightening, and in the first case it is not quietly compiles producing
incorrect code (which is only found by testing).

I also found two variants that's producing correct output:

        for (size_t i = 0; i < 16; i++) {
                printf(" %04x", ((__v16hu)tmp)[i]);
        }

(`__v16hu` is defined in `avxintrin.h`) and similar to how `__v16hu` is defined
there:

        for (size_t i = 0; i < 16; i++) {
                printf(" %04x", ((uint16_t __attribute__ ((__vector_size__
(32)))) tmp)[i] );
        }

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
                   ` (3 preceding siblings ...)
  2022-07-28 22:08 ` vt at altlinux dot org
@ 2022-07-28 22:16 ` vt at altlinux dot org
  2022-07-29  6:50 ` amonakov at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: vt at altlinux dot org @ 2022-07-28 22:16 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Vitaly Chikunov <vt at altlinux dot org> ---
I experimented with `_mm256_extract_epi16` too and loop liek this worked too:

```
# pragma GCC unroll 16
        for (size_t i = 0; i < 16; i++) {
                printf(" %04x", _mm256_extract_epi16(tmp, i));
        }
```

That's why I started to experiment with `#pragma GCC unroll 16` for the 2nd
test case.

Curiously, in `liboqs` adding the pragma removes the `‘tmp’ is used
uninitialized` warning (while w/o pragma it compiles with warning), but in
reproducer it acts contrary - with the pragma it causes warning and w/o pragma
it compiles quietly.

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
                   ` (4 preceding siblings ...)
  2022-07-28 22:16 ` vt at altlinux dot org
@ 2022-07-29  6:50 ` amonakov at gcc dot gnu.org
  2022-07-29  6:55 ` pinskia at gcc dot gnu.org
  2022-07-29  7:09 ` amonakov at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: amonakov at gcc dot gnu.org @ 2022-07-29  6:50 UTC (permalink / raw)
  To: gcc-bugs

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

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amonakov at gcc dot gnu.org

--- Comment #6 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
Andrew, surely the bogus -Wuninitialized warning is a GCC bug here?

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
                   ` (5 preceding siblings ...)
  2022-07-29  6:50 ` amonakov at gcc dot gnu.org
@ 2022-07-29  6:55 ` pinskia at gcc dot gnu.org
  2022-07-29  7:09 ` amonakov at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-07-29  6:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Alexander Monakov from comment #6)
> Andrew, surely the bogus -Wuninitialized warning is a GCC bug here?

No. It is just exposing the undefined behavior.

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

* [Bug middle-end/106470] Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning
  2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
                   ` (6 preceding siblings ...)
  2022-07-29  6:55 ` pinskia at gcc dot gnu.org
@ 2022-07-29  7:09 ` amonakov at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: amonakov at gcc dot gnu.org @ 2022-07-29  7:09 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
But that's the point of many warnings, isn't it? To help the user understand
what's wrong when the code is bad? And bogus warnings just confuse more.

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

end of thread, other threads:[~2022-07-29  7:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-28 21:51 [Bug c/106470] New: Subscribed access to __m256i casted to (uint16_t *) produces garbage or a warning vt at altlinux dot org
2022-07-28 21:54 ` [Bug middle-end/106470] " pinskia at gcc dot gnu.org
2022-07-28 21:58 ` pinskia at gcc dot gnu.org
2022-07-28 22:06 ` pinskia at gcc dot gnu.org
2022-07-28 22:08 ` vt at altlinux dot org
2022-07-28 22:16 ` vt at altlinux dot org
2022-07-29  6:50 ` amonakov at gcc dot gnu.org
2022-07-29  6:55 ` pinskia at gcc dot gnu.org
2022-07-29  7:09 ` amonakov at gcc dot gnu.org

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).