Hi, the problem here is that we propagate predicates inconsistently through inlining breaking the transitivity that is assumed by the size estimate.
Regtested/bootstrapped x86_64-linux, comitted. Honza PR tree-optimize/48929 * gcc.c-torture/compile/pr48929.c: New testcase. * ipa-inline-analysis.c (remap_edge_predicates): Fix handling of empty predicate. Index: testsuite/gcc.c-torture/compile/pr48929.c =================================================================== *** testsuite/gcc.c-torture/compile/pr48929.c (revision 0) --- testsuite/gcc.c-torture/compile/pr48929.c (revision 0) *************** *** 0 **** --- 1,32 ---- + /*{ dg-options "-O -findirect-inlining" }*/ + void bar (); + + static void + f4 (double di, double d, double *dd) + { + if (d == 0 && di == 0) + *dd = 0; + bar (); + } + + static inline void + f3 (int i, double d) + { + double di = i; + double dd; + f4 (di, d, &dd); + } + + static inline void + f2 (int i, double d) + { + if (d < 0) + f3 (i, d); + } + + void + f1 () + { + f2 (0, 1); + } + Index: ipa-inline-analysis.c =================================================================== *** ipa-inline-analysis.c (revision 174610) --- ipa-inline-analysis.c (working copy) *************** remap_edge_predicates (struct cgraph_nod *** 1949,1954 **** --- 1949,1956 ---- if (!e->inline_failed) remap_edge_predicates (e->callee, info, callee_info, operand_map, possible_truths, toplev_predicate); + else + edge_set_predicate (e, toplev_predicate); } for (e = node->indirect_calls; e; e = e->next_callee) { *************** remap_edge_predicates (struct cgraph_nod *** 1969,1974 **** --- 1971,1978 ---- e->frequency = 0; } } + else + edge_set_predicate (e, toplev_predicate); } } Index: ipa-prop.c ===================================================================