Hi, PR70457 shows that we ICE if a call to pow() has only one argument, or more generally doesn't match its expected signature. This can happen both during the widen-mult phase and the tree-inline phase. As suggested by Jakub, this patch uses gimple_call_combined_fn to test for this, similarly to what is done elsewhere in tree-ssa-math-opts.c.
Bootstrapped and tested on powerpc64le-unknown-linux-gnu, with no regressions. Is this ok for trunk, as well as for backport to 5 and 4.9? Thanks, Bill [gcc] 2016-04-03 Bill Schmidt <wschm...@linux.vnet.ibm.com> Jakub Jelinek <ja...@redhat.com> * tree-inline.c (estimate_num_insn): Use gimple_call_combined_fn to ensure a call statement is compatible with a built-in's prototype. * tree-ssa-math-opts.c (pass_optimize_windening_mul::execute): Likewise. [gcc/testsuite] 2016-04-03 Bill Schmidt <wschm...@linux.vnet.ibm.com> Jakub Jelinek <ja...@redhat.com> * gcc.dg/torture/pr70457.c: New. Index: testsuite/gcc.dg/torture/pr70457.c =================================================================== --- testsuite/gcc.dg/torture/pr70457.c (revision 0) +++ testsuite/gcc.dg/torture/pr70457.c (working copy) @@ -0,0 +1,32 @@ +/* { dg-do compile } */ + +/* This formerly ICEd when trying to expand pow as a built-in with + the wrong number of arguments. */ + +extern double pow (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); +extern double __pow (double __x, double __y) __attribute__ ((__nothrow__ , __leaf__)); + +typedef int int64_t __attribute__ ((__mode__ (__DI__))); + +typedef struct { + int64_t data; + int tag; +} Object; + +extern Object Make_Flonum (double); +extern Object P_Pow (Object, Object); + +Object General_Function (Object x, Object y, double (*fun)()) { + double d, ret; + + d = 1.0; + + if (y.tag >> 1) + ret = (*fun) (d); + else + ret = (*fun) (d, 0.0); + + return Make_Flonum (ret); +} + +Object P_Pow (Object x, Object y) { return General_Function (x, y, pow); } Index: tree-inline.c =================================================================== --- tree-inline.c (revision 234702) +++ tree-inline.c (working copy) @@ -57,8 +57,8 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "builtins.h" #include "tree-chkp.h" +#include "case-cfn-macros.h" - /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -4070,11 +4070,9 @@ estimate_num_insns (gimple *stmt, eni_weights *wei /* We canonicalize x * x to pow (x, 2.0) with -ffast-math, so specialize the cheap expansion we do here. ??? This asks for a more general solution. */ - switch (DECL_FUNCTION_CODE (decl)) + switch (gimple_call_combined_fn (stmt)) { - case BUILT_IN_POW: - case BUILT_IN_POWF: - case BUILT_IN_POWL: + CASE_CFN_POW: if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST && (real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)), Index: tree-ssa-math-opts.c =================================================================== --- tree-ssa-math-opts.c (revision 234702) +++ tree-ssa-math-opts.c (working copy) @@ -3829,11 +3829,9 @@ pass_optimize_widening_mul::execute (function *fun if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) { - switch (DECL_FUNCTION_CODE (fndecl)) + switch (gimple_call_combined_fn (stmt)) { - case BUILT_IN_POWF: - case BUILT_IN_POW: - case BUILT_IN_POWL: + CASE_CFN_POW: if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),