On 08/01/2018 02:25 PM, Marc Glisse wrote: > On Wed, 1 Aug 2018, Martin Liška wrote: > >> On 07/27/2018 02:38 PM, Marc Glisse wrote: >>> On Fri, 27 Jul 2018, Martin Liška wrote: >>> >>>> So answer is yes, the builtin can be then removed. >>> >>> Good, thanks. While looking at how widely it is going to apply, I noticed >>> that the default, throwing operator new has attribute malloc and >>> everything, but the non-throwing variant declared in <new> doesn't, so it >>> won't benefit from the new predictor. I don't know if there is a good >>> reason for this disparity... >>> >> >> Well in case somebody uses operator new: >> >> int* p1 = new int; >> if (p1) >> delete p1; >> >> we optimize out that to if (true), even when one has used defined >> operator new. Thus it's probably OK. > > Throwing new is returns_nonnull (errors are reported with exceptions) so > that's fine, but non-throwing new is not: > > int* p1 = new(std::nothrow) int; > > Here errors are reported by returning 0, so it is common to test if p1 is 0 > and this is precisely the case that could benefit from a predictor but does > not have the attribute to do so (there are also consequences on aliasing).
Then it can be handled with DECL_IS_OPERATOR_NEW, for those we can also set the newly introduced predictor. > > (Jan's remark about functions with an inferred malloc attribute reminds me > that at some point, the code was adding attribute malloc for functions that > always return 0...) > By inferred do you mean function that are marked as malloc in IPA pure-const (propagate_malloc)? Example would be appreciated. Martin