diff mbox

Fix PR70457 (ICE on incompatible call to built-in pow)

Message ID 1459740523.6430.56.camel@oc8801110288.ibm.com
State New
Headers show

Commit Message

Bill Schmidt April 4, 2016, 3:28 a.m. UTC
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  <wschmidt@linux.vnet.ibm.com>
	    Jakub Jelinek <jakub@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  <wschmidt@linux.vnet.ibm.com>
	    Jakub Jelinek <jakub@redhat.com>

	* gcc.dg/torture/pr70457.c: New.
diff mbox

Patch

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)),