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