[Bug tree-optimization/93891] CSE where clobber writes the same value
glisse at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sun Feb 23 15:11:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93891
--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> ---
On the original code (I can attach it if needed, but it is large, it is
resizing a std::vector with reference-counted elements) FRE3 fails to simplify
MEM[(struct Handle_for *)__cur_16] ={v} {CLOBBER};
_17 = MEM[(const struct Handle_for &)__first_15].ptr_;
MEM[(struct Handle_for *)__cur_16].ptr_ = _17;
_18 = *_17.count;
_19 = _18 + 1;
*_17.count = _19;
_20 = &__first_15->D.202020;
_31 = MEM[(struct Handle_for *)__first_15].ptr_;
while FRE4 sees
MEM[(struct Handle_for *)__cur_3] ={v} {CLOBBER};
_17 = MEM[base: __first_20, offset: 0B];
MEM[base: __cur_3, offset: 0B] = _17;
_18 = *_17.count;
_19 = _18 + 1;
*_17.count = _19;
_31 = MEM[base: __first_20, offset: 0B];
and replaces _31 with _17. That's confusing, since the main difference between
the 2 is removing a statement without VOP.
(optimizing in FRE4 is way too late in this case, I want the simplified version
before ldist, and it still requires at least DSE, some pass detecting a
self-assignment, and DCE before that)
Here is another simplified version of the testcase, but you need to compile it
with -fno-early-inlining to see the issue:
void g();
struct A {
int*p;
A(A const&a)noexcept:p(a.p){if(*p<=0)__builtin_unreachable();++*p;}
~A(){if(--*p==0)g();}
};
#include <vector>
void f(std::vector<A>&v){
v.reserve(1<<20);
}
At the end of gimple, we still have
_92 = *_91;
*_91 = _92;
in the main loop, while I would want that gone before ldist.
More information about the Gcc-bugs
mailing list