diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-08 09:06:27 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-01-08 09:06:27 +0000 |
commit | 8ded43522c6743e0d8eb942733c2efa98f480bca (patch) | |
tree | c2c2f5e329c26642c69c278413a27dc551d14728 /gcc | |
parent | 3370c0ec93ff7e899f83702ae7039747023eee65 (diff) | |
download | gcc-8ded43522c6743e0d8eb942733c2efa98f480bca.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206421 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 20 | ||||
-rw-r--r-- | gcc/gimple.c | 68 | ||||
-rw-r--r-- | gcc/gimple.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr59630.c | 8 | ||||
-rw-r--r-- | gcc/tsan.c | 2 |
7 files changed, 87 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f7c1a50477..78a5da489a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,22 @@ 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 * gimplify.c (gimplify_expr): Gimplify register-register type VIEW_CONVERT_EXPRs to separate stmts. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index dd45a4a1694..91fc2970924 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -879,8 +879,6 @@ gimple_fold_builtin (gimple stmt) int nargs; location_t loc = gimple_location (stmt); - gcc_assert (is_gimple_call (stmt)); - ignore = (gimple_call_lhs (stmt) == NULL); /* First try the generic builtin folder. If that succeeds, return the @@ -890,6 +888,8 @@ gimple_fold_builtin (gimple stmt) { if (ignore) STRIP_NOPS (result); + else + result = fold_convert (gimple_call_return_type (stmt), result); return result; } @@ -1206,8 +1206,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) /* Check for builtins that CCP can handle using information not available in the generic fold routines. */ - callee = gimple_call_fndecl (stmt); - if (callee && DECL_BUILT_IN (callee)) + if (gimple_call_builtin_p (stmt)) { tree result = gimple_fold_builtin (stmt); if (result) @@ -1216,7 +1215,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) gimplify_and_update_call_from_tree (gsi, result); 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); } @@ -2726,7 +2725,9 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) fn = (*valueize) (gimple_call_fn (stmt)); if (TREE_CODE (fn) == ADDR_EXPR && 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 call, retval; @@ -2738,8 +2739,11 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) fn, gimple_call_num_args (stmt), args); retval = fold_call_expr (EXPR_LOCATION (call), call, false); 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 NULL_TREE; diff --git a/gcc/gimple.c b/gcc/gimple.c index 6075e6d5126..e9851ca386a 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -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 -is_gimple_builtin_call (gimple stmt) -{ - tree callee; - - if (is_gimple_call (stmt) - && (callee = gimple_call_fndecl (stmt)) - && is_builtin_fn (callee) - && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) - return true; - - return false; +static bool +validate_type (tree type1, tree type2) +{ + if (INTEGRAL_TYPE_P (type1) + && INTEGRAL_TYPE_P (type2)) + ; + else if (POINTER_TYPE_P (type1) + && POINTER_TYPE_P (type2)) + ; + else if (TREE_CODE (type1) + != TREE_CODE (type2)) + 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 -validate_call (gimple stmt, tree fndecl) +bool +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)); unsigned nargs = gimple_call_num_args (stmt); for (unsigned i = 0; i < nargs; ++i) @@ -2380,14 +2390,7 @@ validate_call (gimple stmt, tree fndecl) if (!targs) return true; tree arg = gimple_call_arg (stmt, i); - if (INTEGRAL_TYPE_P (TREE_TYPE (arg)) - && 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))) + if (!validate_type (TREE_TYPE (arg), TREE_VALUE (targs))) return false; targs = TREE_CHAIN (targs); } @@ -2396,6 +2399,19 @@ validate_call (gimple stmt, tree fndecl) 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. */ bool @@ -2405,7 +2421,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_class klass) if (is_gimple_call (stmt) && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE && DECL_BUILT_IN_CLASS (fndecl) == klass) - return validate_call (stmt, fndecl); + return gimple_builtin_call_types_compatible_p (stmt, fndecl); return false; } @@ -2419,7 +2435,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_function code) && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (fndecl) == code) - return validate_call (stmt, fndecl); + return gimple_builtin_call_types_compatible_p (stmt, fndecl); return false; } diff --git a/gcc/gimple.h b/gcc/gimple.h index df92863699b..0e80d2eb700 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1253,7 +1253,8 @@ extern tree gimple_unsigned_type (tree); extern tree gimple_signed_type (tree); extern alias_set_type gimple_get_alias_set (tree); 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_function); extern bool gimple_asm_clobbers_memory_p (const_gimple); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3ebbab41be3..d113f2a09e4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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 * gcc.dg/pr59471.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/pr59630.c b/gcc/testsuite/gcc.dg/pr59630.c new file mode 100644 index 00000000000..6a3c72552f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr59630.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +_Bool foo() +{ + _Bool (*f)(int) = __builtin_abs; /* { dg-warning "" } */ + return f(0); +} diff --git a/gcc/tsan.c b/gcc/tsan.c index 2c053bd9e34..2e32cd2b32f 100644 --- a/gcc/tsan.c +++ b/gcc/tsan.c @@ -609,7 +609,7 @@ instrument_gimple (gimple_stmt_iterator *gsi) && (gimple_call_fndecl (stmt) != 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); return true; } |