https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93258
Bug ID: 93258 Summary: [10 regression] Missed constant folding from constructor Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: hubicka at gcc dot gnu.org Target Milestone: --- In the testcase (reduced from folly by Mark Williams): typedef int a; template <typename b, b c> struct d { static constexpr b e = c; }; template <bool c> using f = d<bool, c>; template <typename...> struct g; template <typename h, typename i> struct g<h, i> : h {}; template <typename> struct j : f<!bool()> {}; template <bool> struct an; class m { struct n {}; public: using bm = an<g<j<int>, int>::e>; using bn = n; template <typename bo> m(bn, bo); }; class o { m bq; using bn = m::bn; bn k; o(o &&) : bq(k, 0) {} }; namespace bw { template <class bx> class by { public: constexpr by(bx ca, a cb) : cc(ca), cd(ca + cb) {} long cb() { return cd - cc; } bx cc, cd; }; typedef by<const char *> ch; class ci { public: static o cj(void *, long); static o cj(by<const char *> p) { long l = p.cb(); cj(0, l); } }; } constexpr bw::ch ck{"", 6}; auto fn1() { bw::ci::cj(ck); } compiled with -O3 both GCC 9 and 10 arrive to the following code before fre3: ;; Function fn1 (_Z3fn1v, funcdef_no=9, decl_uid=2560, cgraph_uid=8, symbol_order=8) (executed once) fn1 () { struct o D.2587; struct by p; const char * _3; const char * _4; long int _5; <bb 2> [local count: 1073741824]: p = ck; _3 = MEM[(const char * *)&p]; _4 = MEM[(const char * *)&p + 8B]; _5 = _4 - _3; D.2587 = bw::ci::cj (0B, _5); [return slot optimization] D.2587 ={v} {CLOBBER}; __builtin_unreachable (); } Now GCC9 optimizes in fre3 to: fn1 () { struct o D.2585; struct by p; <bb 2> [local count: 1073741824]: p = ck; D.2585 = bw::ci::cj (0B, 6); [return slot optimization] D.2585 ={v} {CLOBBER}; __builtin_unreachable (); } and GCC10: fn1 () { struct o D.2587; struct by p; const char * _4; long int _5; <bb 2> [local count: 1073741824]: p = ck; _4 = MEM[(const char * *)&p + 8B]; _5 = _4 - ""; D.2587 = bw::ci::cj (0B, _5); [return slot optimization] D.2587 ={v} {CLOBBER}; __builtin_unreachable (); } This seems to be caused by fact that the constructor gets is not formed as valid min invariant: (gdb) p debug_generic_stmt (res) (const char *) "" + 6; $19 = void (gdb) n 1487 if (is_gimple_min_invariant (res)) (gdb) 1501 return NULL_TREE; Is this missed gimplification? GCC9 gets it as &MEM[(void *)"" + 6B] Mark bisected it to the following: commit 7a429a9d52a77e4db2eac6d23d8edb69d26d4f9b (HEAD, refs/bisect/good-7a429a9d52a77e4db2eac6d23d8edb69d26d4f9b) Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> AuthorDate: Mon Jun 10 19:31:49 2019 +0000 Commit: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> CommitDate: Mon Jun 10 19:31:49 2019 +0000 Reduce constexpr_call memory consumption. * constexpr.c (cxx_bind_parameters_in_call): Use TREE_VEC rather than TREE_LIST. (constexpr_call_hasher::equal, cxx_bind_parameters_in_call) (cxx_eval_call_expression): Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272125 138bc75d-0d04-0410-961f-82ee72b054a4