The attached change fixes the canonicalization of method and void
pointers in comparisons against
another method or function pointer on 32-bit hppa targets. As far as I
know, 32-bit hppa is the only
architecture that requires function pointer canonicalization due to lazy
binding.
Tested on hppa2.0w-hp-hpux11.11 and hppa-unknown-linux-gnu, GCC trunk
and 8. Committed to
trunk and gcc-8 branch.
Dave
--
John David Anglin dave.ang...@bell.net
2018-09-14 John David Anglin <dang...@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.
Index: dojump.c
===================================================================
--- dojump.c (revision 264245)
+++ dojump.c (working copy)
@@ -1214,15 +1214,15 @@
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);
Index: expr.c
===================================================================
--- expr.c (revision 264245)
+++ expr.c (working copy)
@@ -11532,12 +11532,10 @@
/* 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);
Index: fold-const.c
===================================================================
--- fold-const.c (revision 264245)
+++ fold-const.c (working copy)
@@ -4922,8 +4922,8 @@
/* 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)
Index: match.pd
===================================================================
--- match.pd (revision 264245)
+++ match.pd (working copy)
@@ -3462,8 +3462,8 @@
/* 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