https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128213
Bug ID: 128213
Summary: [16/17 Regression] phiprop speculates a load wider
than the object it points to
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: lzy20000419 at outlook dot com
Target Milestone: ---
_Alignas (int) char ch[1] = { 1 };
int iv = 7;
__attribute__((noipa)) int
f (int c, int d)
{
int *p = c ? (int *) ch : &iv;
if (d)
return *p;
return 0;
}
int
main (void)
{
volatile int c = 1, d = 0;
return f (c, d);
}
*p only runs when d != 0, and main passes d = 0, so the program never
dereferences p.
$ gcc -O1 -fsanitize=address t.c && ./a.out ERROR: AddressSanitizer:
global-buffer-overflow ... READ of size 4 ... 0 bytes after global variable
'ch' ... of size 1
Expected: no error, exit 0. -fno-tree-phiprop makes it go away; clang and gcc
15.3 are clean with the same flags. Without the sanitizer, trunk -O2 loads
*(int *)ch unconditionally:
f: test edi,edi ; mov edx,OFFSET iv ; mov eax,OFFSET ch ; cmove rax,rdx
xor edx,edx ; test esi,esi ; mov eax,DWORD PTR [rax] ; cmove eax,edx ; ret
If ch sits at the end of a page, this can fault.
It works with 14.4 and 15.3 and fails with 16.1, 16.2 and trunk.
https://godbolt.org/z/f8KKWW9Y4 (left gcc 15.3, right trunk)
Disclaimer: This test case was generated by a fuzzer, and the report was
written with LLM assistance.