https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110137
--- Comment #27 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
This is somewhat weird testcase which makes two allocations which compiler can
track as non-escaping and tests its ability to disambiguate them:
int test3(int *data)
{
int *val = new int;
*val = 12345;
#ifdef NEW
int *a = new int [1000];
#else
int *a = (int *)::operator new (1000 * sizeof (int));
#endif
for (int i = 0; i < 1000; i++)
data[i]=0;
for (int i = 0; i < 1000; i++)
a[data[i]]=1;
int sum = 0;
for (int i = 0; i < 1000; i++)
sum += a[i];
#ifdef NEW
delete[] a;
#else
::operator delete ((void *)val);
#endif
return *val + sum;
}
If I use the operator new I get:
jan@padlo:/tmp> clang -O2 tt2.C -fassume-sane-operator-new tt2.C -S -DNEW ;
grep 12345 tt2.s
addl $12345, %ebx # imm = 0x3039
jan@padlo:/tmp> clang -O2 tt2.C -fno-assume-sane-operator-new tt2.C -S -DNEW ;
grep 12345 tt2.s
movl $12345, (%rax) # imm = 0x3039
jan@padlo:/tmp> clang -O2 tt2.C tt2.C -S -DNEW ; grep 12345 tt2.s
addl $12345, %ebx # imm = 0x3039
so clang assumes sanity by default and needs it to determine that there is no
aliasing between the two returned blocks. As discussed in Comment #14 without
sane operator new, clang is even more conservative then we do about aliasing of
return value.
jan@padlo:/tmp> clang -O2 tt2.C -fassume-sane-operator-new tt2.C -S ; grep
12345 tt2.s
movl $12345, (%rax) # imm = 0x3039
jan@padlo:/tmp> clang -O2 tt2.C -fno-assume-sane-operator-new tt2.C -S ; grep
12345 tt2.s
movl $12345, (%rax) # imm = 0x3039
jan@padlo:/tmp> clang -O2 tt2.C tt2.C -S ; grep 12345 tt2.s
movl $12345, (%rax) # imm = 0x3039
If functions are called directly, flag has no effect.
jan@padlo:/tmp> gcc -O2 tt2.C tt2.C -S -DNEW ; grep 12345 tt2.s
leal 12345(%rbx), %eax
jan@padlo:/tmp> gcc -O2 tt2.C tt2.C -S ; grep 12345 tt2.s
movl $12345, (%rax)
GCC also disambiguates only with sane operator new. I can see we can not
optimize out the store but it is not quite clear to me why we do not propagate
the constant.