summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-08 09:06:27 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-08 09:06:27 +0000
commit8ded43522c6743e0d8eb942733c2efa98f480bca (patch)
treec2c2f5e329c26642c69c278413a27dc551d14728 /gcc
parent3370c0ec93ff7e899f83702ae7039747023eee65 (diff)
downloadgcc-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/ChangeLog17
-rw-r--r--gcc/gimple-fold.c20
-rw-r--r--gcc/gimple.c68
-rw-r--r--gcc/gimple.h3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr59630.c8
-rw-r--r--gcc/tsan.c2
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;
}