https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89505
Bug ID: 89505 Summary: [9 Regression] LibreOffice miscompilation starting with r260383 Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- Created attachment 45823 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45823&action=edit rh1682941.ii.xz The attached testcase from LibreOffice is miscompiled starting with r260383 with -O2 -fPIC -std=c++2a, unfortunately don't have a smaller testcase so far and haven't succeeded in coming up with a reduced one. In the dumps, look for case 263392: or 263392 and in *.optimized dump it should look like: _59 = rtl_str_toInt32 (_58, 10); _148 = MIN_EXPR <_59, 1024>; _73 = MAX_EXPR <_148, 1>; this_12(D)->nColCount = _73; but starting with r260383 it is not. We have before dse1 code like: D.857771 = 1; ... _129 = rtl_str_toInt32 (_128, 10); D.857770 = _129; if (_129 <= 0) goto <bb 8>; [34.00%] else goto <bb 9>; [66.00%] <bb 8> : <bb 9> : # _119 = PHI <&D.857770(7), &D.857771(8)> _12 = *_119; this_29(D)->nColCount = _12; D.857770 ={v} {CLOBBER}; D.857771 ={v} {CLOBBER}; D.857772 = 1024; _13 = &this_29(D)->nColCount; if (_12 > 1024) goto <bb 10>; [34.00%] else goto <bb 11>; [66.00%] <bb 10> : <bb 11> : # _116 = PHI <_13(9), &D.857772(10)> _15 = *_116; this_29(D)->nColCount = _15; In *.mergephi1 with -alias-vops the difference (trunk vs. trunk with r260383 reverted) is: # .MEM_55 = VDEF <.MEM_23> D.857771 = 1; ... # .MEM_206 = VDEF <.MEM_55> - # USE = nonlocal null { D.112965 D.113017 D.857775 D.857777 D.857779 } (nonlocal, escaped, interposable) - # CLB = nonlocal null { D.112965 D.113017 D.857775 D.857777 D.857779 } (nonlocal, escaped, interposable) + # USE = nonlocal null { D.112965 D.113017 D.857775 D.857777 D.857779 D.1010617 } (nonlocal, escaped, restrict, interposable) + # CLB = nonlocal null { D.112965 D.113017 D.857775 D.857777 D.857779 D.1010617 } (nonlocal, escaped, restrict, interposable) _129 = rtl_str_toInt32 (_128, 10); # .MEM_57 = VDEF <.MEM_206> D.857770 = _129; if (_129 <= 0) goto <bb 8>; [34.00%] else goto <bb 9>; [66.00%] <bb 8> : <bb 9> : # PT = { D.857770 D.857771 } # ALIGN = 4, MISALIGN = 0 # _119 = PHI <&D.857770(7), &D.857771(8)> # VUSE <.MEM_57> - _12 = *_119; + _12 = MEM[(const int &)_119 clique 1 base 0]; # .MEM_59 = VDEF <.MEM_57> - this_29(D)->nColCount = _12; + MEM[(struct ScXMLTableColContext *)this_29(D) clique 1 base 1].nColCount = _12; # .MEM_60 = VDEF <.MEM_59> D.857770 ={v} {CLOBBER}; # .MEM_61 = VDEF <.MEM_60> D.857771 ={v} {CLOBBER}; # .MEM_62 = VDEF <.MEM_61> D.857772 = 1024; - # PT = nonlocal + # PT = { D.1010617 } (nonlocal, escaped) _13 = &this_29(D)->nColCount; if (_12 > 1024) goto <bb 10>; [34.00%] else goto <bb 11>; [66.00%] <bb 10> : <bb 11> : - # PT = nonlocal { D.857772 } + # PT = { D.857772 D.1010617 } (nonlocal, escaped) # _116 = PHI <_13(9), &D.857772(10)> # VUSE <.MEM_62> - _15 = *_116; + _15 = MEM[(const int &)_116 clique 1 base 0]; # .MEM_64 = VDEF <.MEM_62> - this_29(D)->nColCount = _15; + MEM[(struct ScXMLTableColContext *)this_29(D) clique 1 base 1].nColCount = _15; and DSE1 removes the nColCount store: <bb 9> : # _119 = PHI <&D.857770(7), &D.857771(8)> _12 = *_119; - this_29(D)->nColCount = _12; D.857770 ={v} {CLOBBER}; D.857771 ={v} {CLOBBER}; D.857772 = 1024; ... <bb 11> : # _116 = PHI <_13(9), &D.857772(10)> _15 = *_116; - this_29(D)->nColCount = _15; + *this_29(D).nColCount = _15; D.857772 ={v} {CLOBBER}; goto <bb 18>; [INV] I've tried to reduce this to: template<typename _Tp> constexpr inline const _Tp& min (const _Tp& __a, const _Tp& __b) { if (__b < __a) return __b; return __a; } template<typename _Tp> constexpr inline const _Tp& max (const _Tp& __a, const _Tp& __b) { if (__a < __b) return __b; return __a; } template<typename _Tp, typename _Compare> constexpr inline const _Tp& min (const _Tp& __a, const _Tp& __b, _Compare __comp) { if (__comp(__b, __a)) return __b; return __a; } template<typename _Tp, typename _Compare> constexpr inline const _Tp& max (const _Tp& __a, const _Tp& __b, _Compare __comp) { if (__comp(__a, __b)) return __b; return __a; } int foo () throw (); struct S { char pad[80]; int nColCount; S (); }; const signed short m = 1024; int v; S::S () { nColCount = 1; if (v) { nColCount = max<int> (foo (), 1); nColCount = min<int> (nColCount, m); } } but that doesn't reproduce this.