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

--- Comment #15 from Jan Hubicka <hubicka at ucw dot cz> ---
> As pointed out in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110035#c13 , 
> gcc
> already assume operator new's retuned pointer cannot alias any existing
> pointer. So no change is needed there.
Seems you are right, -fsane-operator-new is weaker than I assumed.
In addition to the assumption about modifying globals, one missed
optimization is removal of unused vectors (we have separate PR for that)

#include <vector>
void foo (int *);
int test()
{
        std::vector <int> a(1);
        return 0;
}
int test2(int size)
{
        int *a = new int;
        *a=0;
        delete a;
        return 0;
}
int test3(int size)
{
        int *a = (int *)::operator new (sizeof (int));
        *a=0;
        ::operator delete (a);
        return 0;
}
At -O2 Clang optimizes test and test2 "return 0", while we optimize only
test2.  libstdc++ uses clang's __builtin_operator_new that enables this
optimization based on claim that user's possibly insane new/delete can
not rely on internals of std::vector implementation and thus can not
reliably use memory being deleted.

I expected that -fassume-sane-operator-new should enable clang or GCC to
do the optimization for all three variants, but it does not (for clang).
I think it would be useful to have such a flag. There are number of
transformations we may want to do including
 - removal of dead stores to memory being deleted
 - removal of unnecesary reallocations i.e. when user creates empty
   vector and does sequence of push_backs.
 - avoiding new/delete for small vectors that fits to stack.
I believe those are sane for builtin_operator_new/delete. However since
clang does not define it this way, perhaps we will need
-fassume-really-sane-operator-new-delete for that?

It would be also nice to be able to determine functions that does paired
new/delete but no other side effects as pure/const etc.

BTW clang also does not optimize out load from global here:
int test3(int size)
{
        global = 0;
        int *a = (int *)::operator new (sizeof (int));
        *a=0;
        return global;
}
I would expect -fassume-sane-operator-new to make it possible?

Reply via email to