On Tue, Nov 19, 2024 at 09:35:06AM +0100, Richard Biener wrote: > > This all seems excessively complicated; can't it be simplified a bit? > > I'd like to second this - I don't see value in adding the "intermediate" > state which we never had. We for quite some time had two extremes, if > we want to have a separate flag controlling this besides -fallocation-dce > the go with dual-state please. I'd even say we don't need any new > flag but can use the -fallocation-dce umbrella to control how the > middle-end interprets new/delete semantically since the ability to > elide new/delete implies that the user at least doesn't care about > side-effects. Documenting the behavior clearly is of course good.
The problem with the two states we had/have is that they are too extreme. Our old one (i.e. those "mC" etc.) is too strong and doesn't have any backup in the standard, I think the PR101480 testcase is perfectly valid C++ and so it probably isn't a good idea to enable such behavior by default; with an extra switch sure, user promises not to rely on it and the optimization can be done. The current one (i.e. those "m " etc.) are too weak, otherwise we wouldn't be discussing this PR, it really penalizes too much code in the wild. The proposed intermediate one is what LLVM clearly implements and as I wrote my reading of the standard is that while the user replaced global operators certainly can modify visible global state, the callers can't really rely on it because there is no guarantee it will be called at all and so I hope we can do that by default. I think the step from the no optimizations to the intermediate state is much more important for C++ code in the wild, by making the operators have pure-ish behavior one doesn't need to reread everything from memory, typical C++ has data in classes, many of those escape somewhere and having to reread everything after every new/delete operator just in case those have changed those is expensive. The step from intermediate state to the full optimization one is primarily about DSE of global stores before the operators, but I think the most important from those (stores to the memory actually being deleted) we can already delete anyway if it is call from delete because there are destructors happening before that and so the operators can't expect some particular values in that memory. Anyway, I wonder what Jason/Jonathan think about this from the C++ standard POV. Jakub