http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59630
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #2) > Started with my r182761 but say: > _Bool foo (int x) > { > _Bool (*f)(int) = __builtin_abs; > return f(x); > } > ICEs at -O2 already since the gimple_call_fntype introduction in r172310. > Since the r172310 change we also without any warnings happily inline: > inline int fn1 (int x, int y) { return x + y; } > int > fn2 (void) > { > int (*fn) (long long) = (void *) fn1; > return fn (5LL); > } > inline int fn3 (long long x) { return x; } > int > fn4 (void) > { > int (*fn) (int x, int y) = (void *) fn3; > return fn (5, 6); > } > (well, for fn1 into fn2 we complain about uninitialized y). > This is also related to PR59622. Even with gimple_call_fntype, I'd say we > should never propagate an indirect call into a gimple_call_fndecl if it > doesn't satisfy some minimal consistency predicate (something along the > lines of what I wrote in PR59622, basically if the stmt has lhs, then the > return types need to be compatible, and TYPE_ARG_TYPES should be compatible > (perhaps an exception can be made for the C () vs. (void) arguments). > Because if the conversion between fn return type and/or arguments types is > non-useless, I'm afraid tons of issues can happen everywhere. At minimum we > should disallow it if the fndecl we want to propagate is a builtin, and we > should not inline it, or perhaps clone. Not at all. The bug is how we identify a call stmt to be a builtin call vs. a call to a builtin function. gimple_call_arg_fn specifies the function address we call and gimple_call_fntype specifies the function signature the caller expects. There shouldn't be many places to fix, and in most cases a proper predicate can be used / introduced. useless_type_conversion_p (TREE_TYPE (fndecl), fntype) should work here to guard the builtins.c folding. We really want to aggressively make indirect calls direct ones.