aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2018-09-14 23:26:12 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2018-09-14 23:26:12 +0000
commitf3743e2e32432a1d961c81097db3f755fd2dae76 (patch)
tree408d2c467782ee84c4590e65b055f6b0cb4fbc1a /gcc
parent07f879058339c496273c9960562c3fdad317001a (diff)
downloadgcc-f3743e2e32432a1d961c81097db3f755fd2dae76.zip
gcc-f3743e2e32432a1d961c81097db3f755fd2dae76.tar.gz
gcc-f3743e2e32432a1d961c81097db3f755fd2dae76.tar.bz2
re PR middle-end/87188 (Function pointer canonicalization optimized away)
PR middle-end/87188 * dojump.c (do_compare_and_jump): Canonicalize function pointers when one operand is a function pointer. Use POINTER_TYPE_P and FUNC_OR_METHOD_TYPE_P. * expr.c (do_store_flag): Use POINTER_TYPE_P and FUNC_OR_METHOD_TYPE_P. * fold-const.c (build_range_check): Likewise. * match.pd (simple_comparison): Likewise. From-SVN: r264336
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/dojump.c16
-rw-r--r--gcc/expr.c10
-rw-r--r--gcc/fold-const.c4
-rw-r--r--gcc/match.pd4
5 files changed, 26 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a2088aa..8fda90a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2018-09-14 John David Anglin <danglin@gcc.gnu.org>
+
+ PR middle-end/87188
+ * dojump.c (do_compare_and_jump): Canonicalize function pointers
+ when one operand is a function pointer. Use POINTER_TYPE_P and
+ FUNC_OR_METHOD_TYPE_P.
+ * expr.c (do_store_flag): Use POINTER_TYPE_P and FUNC_OR_METHOD_TYPE_P.
+ * fold-const.c (build_range_check): Likewise.
+ * match.pd (simple_comparison): Likewise.
+
2018-09-14 David Malcolm <dmalcolm@redhat.com>
PR c/82967
diff --git a/gcc/dojump.c b/gcc/dojump.c
index 88cc96a..56c82c5f 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -1215,15 +1215,15 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
code = unsignedp ? unsigned_code : signed_code;
/* If function pointers need to be "canonicalized" before they can
- be reliably compared, then canonicalize them.
- Only do this if *both* sides of the comparison are function pointers.
- If one side isn't, we want a noncanonicalized comparison. See PR
- middle-end/17564. */
+ be reliably compared, then canonicalize them. Canonicalize the
+ expression when one of the operands is a function pointer. This
+ handles the case where the other operand is a void pointer. See
+ PR middle-end/17564. */
if (targetm.have_canonicalize_funcptr_for_compare ()
- && POINTER_TYPE_P (TREE_TYPE (treeop0))
- && POINTER_TYPE_P (TREE_TYPE (treeop1))
- && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))
- && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))
+ && ((POINTER_TYPE_P (TREE_TYPE (treeop0))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))))
+ || (POINTER_TYPE_P (TREE_TYPE (treeop1))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))))
{
rtx new_op0 = gen_reg_rtx (mode);
rtx new_op1 = gen_reg_rtx (mode);
diff --git a/gcc/expr.c b/gcc/expr.c
index 67aa052..b8782b9 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11842,12 +11842,10 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
/* We won't bother with store-flag operations involving function pointers
when function pointers must be canonicalized before comparisons. */
if (targetm.have_canonicalize_funcptr_for_compare ()
- && ((TREE_CODE (TREE_TYPE (arg0)) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg0)))
- == FUNCTION_TYPE))
- || (TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg1)))
- == FUNCTION_TYPE))))
+ && ((POINTER_TYPE_P (TREE_TYPE (arg0))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
+ || (POINTER_TYPE_P (TREE_TYPE (arg1))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
return 0;
STRIP_NOPS (arg0);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 6b4b6a4..3a6d1b1 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4956,8 +4956,8 @@ build_range_check (location_t loc, tree type, tree exp, int in_p,
/* Disable this optimization for function pointer expressions
on targets that require function pointer canonicalization. */
if (targetm.have_canonicalize_funcptr_for_compare ()
- && TREE_CODE (etype) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (etype)) == FUNCTION_TYPE)
+ && POINTER_TYPE_P (etype)
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (etype)))
return NULL_TREE;
if (! in_p)
diff --git a/gcc/match.pd b/gcc/match.pd
index 6d54dcb..74244f3 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3558,8 +3558,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Disable this optimization if we're casting a function pointer
type on targets that require function pointer canonicalization. */
&& !(targetm.have_canonicalize_funcptr_for_compare ()
- && TREE_CODE (TREE_TYPE (@00)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_TYPE (@00))) == FUNCTION_TYPE)
+ && POINTER_TYPE_P (TREE_TYPE (@00))
+ && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@00))))
&& single_use (@0))
(if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0))
&& (TREE_CODE (@10) == INTEGER_CST