On Sun, 2016-04-03 at 18:43 -0500, Bill Schmidt wrote: > 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?
For GCC 5 and GCC 4.9, a slightly different patch is required, since gimple_call_combined_fn doesn't exist in previous releases. Also, the sin, cos, etc., functions are also vulnerable: [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_builtin_p to ensure a call statement is compatible with a built-in's prototype. * tree-ssa-math-opts.c (execute_cse_sincos): Likewise. (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: gcc/testsuite/gcc.dg/torture/pr70457.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr70457.c (revision 0) +++ gcc/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: gcc/tree-inline.c =================================================================== --- gcc/tree-inline.c (revision 234702) +++ gcc/tree-inline.c (working copy) @@ -3860,6 +3860,8 @@ estimate_num_insns (gimple stmt, eni_weights *weig case BUILT_IN_POW: case BUILT_IN_POWF: case BUILT_IN_POWL: + if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) + break; if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST && REAL_VALUES_EQUAL (TREE_REAL_CST (gimple_call_arg (stmt, 1)), dconst2)) Index: gcc/tree-ssa-math-opts.c =================================================================== --- gcc/tree-ssa-math-opts.c (revision 234702) +++ gcc/tree-ssa-math-opts.c (working copy) @@ -1437,7 +1437,7 @@ execute_cse_sincos (void) if (is_gimple_call (stmt) && gimple_call_lhs (stmt) && (fndecl = gimple_call_fndecl (stmt)) - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) { tree arg, arg0, arg1, result; HOST_WIDE_INT n; @@ -2867,6 +2867,8 @@ execute_optimize_widening_mul (void) case BUILT_IN_POWF: case BUILT_IN_POW: case BUILT_IN_POWL: + if (!gimple_call_builtin_p (stmt)) + break; if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST && REAL_VALUES_EQUAL (TREE_REAL_CST (gimple_call_arg (stmt, 1)),