https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98834
Martin Jambor <jamborm at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at gcc dot gnu.org --- Comment #6 from Martin Jambor <jamborm at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #4) > Started with r10-3106-g46dfa8ad6c18feb45d35734eae38798edb7c38cd > Anyway, I wonder if this isn't similar to the cases where the inliner > optimistically assumed that __builtin_constant_p will fold to true but > didn't actually fold it that way, and then later on that didn't happen? It is exactly that. We have one __builtin_constant_p that is called if another, previous __builtin_constant_p returns false. Inlining assumes the previous one will be folded to true because it knows it is called on a constant, albeit one read from an aggregate, and therefore assumes the latter will never happen. But after inlining, the situation looks like this (some statements omitted): <bb 2> [local count: 1073741824]: MEM <intD.9> [(struct simdD.2582 *)&__xD.2752] = 0; MEM <intD.9> [(struct simdD.2582 *)&__xD.2752 + 4B] = 0; ... __xD.2820 = __xD.2752._M_dataD.2591; ... __xx_10 = MEM <intD.9> [(struct _TupleD.2456 *)&__xD.2820]; _11 = __builtin_constant_p (__xx_10); And we need a SRA + CCP to make the constant travel from the first assignment to the __builtin_constant_p (__xx_10). And SRA does take place only after VRP which already decides to fold __builtin_constant_p to false. A quick and dirty (and potentially regression causing) way to fix that is to declare __builtin_constant_p not working on aggregate values: diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 18bbae145b9..c319323b31e 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -1638,7 +1638,8 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, || gimple_call_num_args (set_stmt) != 1) return; op2 = gimple_call_arg (set_stmt, 0); - if (!decompose_param_expr (fbi, set_stmt, op2, &index, ¶m_type, &aggpos)) + if (!decompose_param_expr (fbi, set_stmt, op2, &index, ¶m_type, &aggpos) + || aggpos.agg_contents) return; if (!aggpos.by_ref) add_builtin_constant_p_parm (summary, index); (the last condition would then also need to be turned into a comment ...and possibly an assert). But it feels like too big a hammer. Alternatively, we could just resolve the builtin at IPA time. We'd need to store the predicate derived from its argument to ipa_call_summary and then at IPA time redirect it to some __builtin_true_p when IPA figures out it has to be true, which we would then redirect in cgraph_edge::redirect_call_stmt_to_callee. Honza, would that be a good idea?