Commit 5c944c6c by Richard Biener Committed by Richard Biener

re PR middle-end/59630 (ICE converting the return type of a builtin function)

2014-01-08  Richard Biener  <rguenther@suse.de>

	PR middle-end/59630
	* gimple.h (is_gimple_builtin_call): Remove.
	(gimple_builtin_call_types_compatible_p): New.
	(gimple_call_builtin_p): New overload.
	* gimple.c (is_gimple_builtin_call): Remove.
	(validate_call): Rename to ...
	(gimple_builtin_call_types_compatible_p): ... this and export.  Also
	check return types.
	(validate_type): New static function.
	(gimple_call_builtin_p): New overload and adjust.
	* gimple-fold.c (gimple_fold_builtin): Fold the return value.
	(gimple_fold_call): Likewise.  Use gimple_call_builtin_p.
	(gimple_fold_stmt_to_constant_1): Likewise.
	* tsan.c (instrument_gimple): Use gimple_call_builtin_p.

	* gcc.dg/pr59630.c: New testcase.

From-SVN: r206421
parent 0bd34ae4
2014-01-08 Richard Biener <rguenther@suse.de> 2014-01-08 Richard Biener <rguenther@suse.de>
PR middle-end/59630
* gimple.h (is_gimple_builtin_call): Remove.
(gimple_builtin_call_types_compatible_p): New.
(gimple_call_builtin_p): New overload.
* gimple.c (is_gimple_builtin_call): Remove.
(validate_call): Rename to ...
(gimple_builtin_call_types_compatible_p): ... this and export. Also
check return types.
(validate_type): New static function.
(gimple_call_builtin_p): New overload and adjust.
* gimple-fold.c (gimple_fold_builtin): Fold the return value.
(gimple_fold_call): Likewise. Use gimple_call_builtin_p.
(gimple_fold_stmt_to_constant_1): Likewise.
* tsan.c (instrument_gimple): Use gimple_call_builtin_p.
2014-01-08 Richard Biener <rguenther@suse.de>
PR middle-end/59471 PR middle-end/59471
* gimplify.c (gimplify_expr): Gimplify register-register type * gimplify.c (gimplify_expr): Gimplify register-register type
VIEW_CONVERT_EXPRs to separate stmts. VIEW_CONVERT_EXPRs to separate stmts.
......
...@@ -879,8 +879,6 @@ gimple_fold_builtin (gimple stmt) ...@@ -879,8 +879,6 @@ gimple_fold_builtin (gimple stmt)
int nargs; int nargs;
location_t loc = gimple_location (stmt); location_t loc = gimple_location (stmt);
gcc_assert (is_gimple_call (stmt));
ignore = (gimple_call_lhs (stmt) == NULL); ignore = (gimple_call_lhs (stmt) == NULL);
/* First try the generic builtin folder. If that succeeds, return the /* First try the generic builtin folder. If that succeeds, return the
...@@ -890,6 +888,8 @@ gimple_fold_builtin (gimple stmt) ...@@ -890,6 +888,8 @@ gimple_fold_builtin (gimple stmt)
{ {
if (ignore) if (ignore)
STRIP_NOPS (result); STRIP_NOPS (result);
else
result = fold_convert (gimple_call_return_type (stmt), result);
return result; return result;
} }
...@@ -1206,8 +1206,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) ...@@ -1206,8 +1206,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
/* Check for builtins that CCP can handle using information not /* Check for builtins that CCP can handle using information not
available in the generic fold routines. */ available in the generic fold routines. */
callee = gimple_call_fndecl (stmt); if (gimple_call_builtin_p (stmt))
if (callee && DECL_BUILT_IN (callee))
{ {
tree result = gimple_fold_builtin (stmt); tree result = gimple_fold_builtin (stmt);
if (result) if (result)
...@@ -1216,7 +1215,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) ...@@ -1216,7 +1215,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
gimplify_and_update_call_from_tree (gsi, result); gimplify_and_update_call_from_tree (gsi, result);
changed = true; changed = true;
} }
else if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD) else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
changed |= targetm.gimple_fold_builtin (gsi); changed |= targetm.gimple_fold_builtin (gsi);
} }
...@@ -2726,7 +2725,9 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) ...@@ -2726,7 +2725,9 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
fn = (*valueize) (gimple_call_fn (stmt)); fn = (*valueize) (gimple_call_fn (stmt));
if (TREE_CODE (fn) == ADDR_EXPR if (TREE_CODE (fn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
&& DECL_BUILT_IN (TREE_OPERAND (fn, 0))) && DECL_BUILT_IN (TREE_OPERAND (fn, 0))
&& gimple_builtin_call_types_compatible_p (stmt,
TREE_OPERAND (fn, 0)))
{ {
tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt)); tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
tree call, retval; tree call, retval;
...@@ -2738,8 +2739,11 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) ...@@ -2738,8 +2739,11 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
fn, gimple_call_num_args (stmt), args); fn, gimple_call_num_args (stmt), args);
retval = fold_call_expr (EXPR_LOCATION (call), call, false); retval = fold_call_expr (EXPR_LOCATION (call), call, false);
if (retval) if (retval)
/* fold_call_expr wraps the result inside a NOP_EXPR. */ {
STRIP_NOPS (retval); /* fold_call_expr wraps the result inside a NOP_EXPR. */
STRIP_NOPS (retval);
retval = fold_convert (gimple_call_return_type (stmt), retval);
}
return retval; return retval;
} }
return NULL_TREE; return NULL_TREE;
......
...@@ -2351,27 +2351,37 @@ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt) ...@@ -2351,27 +2351,37 @@ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt)
} }
/* Return TRUE iff stmt is a call to a built-in function. */ /* Return true if TYPE1 and TYPE2 are compatible enough for builtin
processing. */
bool static bool
is_gimple_builtin_call (gimple stmt) validate_type (tree type1, tree type2)
{ {
tree callee; if (INTEGRAL_TYPE_P (type1)
&& INTEGRAL_TYPE_P (type2))
if (is_gimple_call (stmt) ;
&& (callee = gimple_call_fndecl (stmt)) else if (POINTER_TYPE_P (type1)
&& is_builtin_fn (callee) && POINTER_TYPE_P (type2))
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) ;
return true; else if (TREE_CODE (type1)
!= TREE_CODE (type2))
return false; return false;
return true;
} }
/* Return true when STMTs arguments match those of FNDECL. */ /* Return true when STMTs arguments and return value match those of FNDECL,
a decl of a builtin function. */
static bool bool
validate_call (gimple stmt, tree fndecl) gimple_builtin_call_types_compatible_p (gimple stmt, tree fndecl)
{ {
gcc_checking_assert (DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN);
tree ret = gimple_call_lhs (stmt);
if (ret
&& !validate_type (TREE_TYPE (ret), TREE_TYPE (TREE_TYPE (fndecl))))
return false;
tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
unsigned nargs = gimple_call_num_args (stmt); unsigned nargs = gimple_call_num_args (stmt);
for (unsigned i = 0; i < nargs; ++i) for (unsigned i = 0; i < nargs; ++i)
...@@ -2380,14 +2390,7 @@ validate_call (gimple stmt, tree fndecl) ...@@ -2380,14 +2390,7 @@ validate_call (gimple stmt, tree fndecl)
if (!targs) if (!targs)
return true; return true;
tree arg = gimple_call_arg (stmt, i); tree arg = gimple_call_arg (stmt, i);
if (INTEGRAL_TYPE_P (TREE_TYPE (arg)) if (!validate_type (TREE_TYPE (arg), TREE_VALUE (targs)))
&& INTEGRAL_TYPE_P (TREE_VALUE (targs)))
;
else if (POINTER_TYPE_P (TREE_TYPE (arg))
&& POINTER_TYPE_P (TREE_VALUE (targs)))
;
else if (TREE_CODE (TREE_TYPE (arg))
!= TREE_CODE (TREE_VALUE (targs)))
return false; return false;
targs = TREE_CHAIN (targs); targs = TREE_CHAIN (targs);
} }
...@@ -2396,6 +2399,19 @@ validate_call (gimple stmt, tree fndecl) ...@@ -2396,6 +2399,19 @@ validate_call (gimple stmt, tree fndecl)
return true; return true;
} }
/* Return true when STMT is builtins call. */
bool
gimple_call_builtin_p (gimple stmt)
{
tree fndecl;
if (is_gimple_call (stmt)
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
&& DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN)
return gimple_builtin_call_types_compatible_p (stmt, fndecl);
return false;
}
/* Return true when STMT is builtins call to CLASS. */ /* Return true when STMT is builtins call to CLASS. */
bool bool
...@@ -2405,7 +2421,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_class klass) ...@@ -2405,7 +2421,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_class klass)
if (is_gimple_call (stmt) if (is_gimple_call (stmt)
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
&& DECL_BUILT_IN_CLASS (fndecl) == klass) && DECL_BUILT_IN_CLASS (fndecl) == klass)
return validate_call (stmt, fndecl); return gimple_builtin_call_types_compatible_p (stmt, fndecl);
return false; return false;
} }
...@@ -2419,7 +2435,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_function code) ...@@ -2419,7 +2435,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_function code)
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (fndecl) == code) && DECL_FUNCTION_CODE (fndecl) == code)
return validate_call (stmt, fndecl); return gimple_builtin_call_types_compatible_p (stmt, fndecl);
return false; return false;
} }
......
...@@ -1253,7 +1253,8 @@ extern tree gimple_unsigned_type (tree); ...@@ -1253,7 +1253,8 @@ extern tree gimple_unsigned_type (tree);
extern tree gimple_signed_type (tree); extern tree gimple_signed_type (tree);
extern alias_set_type gimple_get_alias_set (tree); extern alias_set_type gimple_get_alias_set (tree);
extern bool gimple_ior_addresses_taken (bitmap, gimple); extern bool gimple_ior_addresses_taken (bitmap, gimple);
extern bool is_gimple_builtin_call (gimple stmt); extern bool gimple_builtin_call_types_compatible_p (gimple, tree);
extern bool gimple_call_builtin_p (gimple);
extern bool gimple_call_builtin_p (gimple, enum built_in_class); extern bool gimple_call_builtin_p (gimple, enum built_in_class);
extern bool gimple_call_builtin_p (gimple, enum built_in_function); extern bool gimple_call_builtin_p (gimple, enum built_in_function);
extern bool gimple_asm_clobbers_memory_p (const_gimple); extern bool gimple_asm_clobbers_memory_p (const_gimple);
......
2014-01-08 Richard Biener <rguenther@suse.de> 2014-01-08 Richard Biener <rguenther@suse.de>
PR middle-end/59630
* gcc.dg/pr59630.c: New testcase.
2014-01-08 Richard Biener <rguenther@suse.de>
PR middle-end/59471 PR middle-end/59471
* gcc.dg/pr59471.c: New testcase. * gcc.dg/pr59471.c: New testcase.
......
/* { dg-do compile } */
/* { dg-options "-O" } */
_Bool foo()
{
_Bool (*f)(int) = __builtin_abs; /* { dg-warning "" } */
return f(0);
}
...@@ -609,7 +609,7 @@ instrument_gimple (gimple_stmt_iterator *gsi) ...@@ -609,7 +609,7 @@ instrument_gimple (gimple_stmt_iterator *gsi)
&& (gimple_call_fndecl (stmt) && (gimple_call_fndecl (stmt)
!= builtin_decl_implicit (BUILT_IN_TSAN_INIT))) != builtin_decl_implicit (BUILT_IN_TSAN_INIT)))
{ {
if (is_gimple_builtin_call (stmt)) if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
instrument_builtin_call (gsi); instrument_builtin_call (gsi);
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment