https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127926
liu zhenyu <lzy20000419 at outlook dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lzy20000419 at outlook dot com
--- Comment #3 from liu zhenyu <lzy20000419 at outlook dot com> ---
PR127926 covers the memcpy case of `vn_reference_lookup_3`. The memset case in
the same function has the same
missing `reverse_storage_order_for_component_p` guard (tree-ssa-sccvn.cc,
gcc-14 ~2924-3066). Constant / SSA /
vectorizer-internal store cases already check it; memset does not.
```c
struct __attribute__((scalar_storage_order ("big-endian"))) S { unsigned a : 5;
};
__attribute__((noipa)) unsigned
f (void)
{
struct S s;
__builtin_memset (&s, 0x5a, sizeof s);
return s.a; /* top 5 bits of 0x5a = 11 */
}
int main (void)
{
if (f () != 11)
__builtin_abort ();
return 0;
}
```
```
$ gcc -O0 t.c && ./a.out # ok
$ gcc -O1 t.c && ./a.out # Aborted (f returns 26 = low 5 bits / LE order)
```
Fails at -O1/-O2/-O3/-Os/-Og from GCC 10.1 through trunk (9.4 and older OK).
FRE replaces `s.a` with 26.
`-fno-tree-fre -fno-tree-pre` alone is not enough at -O2 (`-fcode-hoisting`
still folds it). No UB; the only
scalar access is through the big-endian struct itself (same pattern as
gcc.dg/sso and this PR's memcpy tests).
A whole-word masked form also fails (partial memset + `s.w & 1` prints 0
instead of 1), so a fix should not
punt only for non-byte-sized reads.
If the fix for this PR is only in the memcpy case, the memset path would still
need the same guard.
Disclaimer: This test case was generated by a fuzzer, and the report was
written with LLM assistance.