Commit f3743e2e by John David Anglin

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
parent 07f87905
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> 2018-09-14 David Malcolm <dmalcolm@redhat.com>
PR c/82967 PR c/82967
......
...@@ -1215,15 +1215,15 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, ...@@ -1215,15 +1215,15 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
code = unsignedp ? unsigned_code : signed_code; code = unsignedp ? unsigned_code : signed_code;
/* If function pointers need to be "canonicalized" before they can /* If function pointers need to be "canonicalized" before they can
be reliably compared, then canonicalize them. be reliably compared, then canonicalize them. Canonicalize the
Only do this if *both* sides of the comparison are function pointers. expression when one of the operands is a function pointer. This
If one side isn't, we want a noncanonicalized comparison. See PR handles the case where the other operand is a void pointer. See
middle-end/17564. */ PR middle-end/17564. */
if (targetm.have_canonicalize_funcptr_for_compare () if (targetm.have_canonicalize_funcptr_for_compare ()
&& POINTER_TYPE_P (TREE_TYPE (treeop0)) && ((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 (treeop0))) || (POINTER_TYPE_P (TREE_TYPE (treeop1))
&& FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1)))) && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))))
{ {
rtx new_op0 = gen_reg_rtx (mode); rtx new_op0 = gen_reg_rtx (mode);
rtx new_op1 = gen_reg_rtx (mode); rtx new_op1 = gen_reg_rtx (mode);
......
...@@ -11842,12 +11842,10 @@ do_store_flag (sepops ops, rtx target, machine_mode mode) ...@@ -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 /* We won't bother with store-flag operations involving function pointers
when function pointers must be canonicalized before comparisons. */ when function pointers must be canonicalized before comparisons. */
if (targetm.have_canonicalize_funcptr_for_compare () if (targetm.have_canonicalize_funcptr_for_compare ()
&& ((TREE_CODE (TREE_TYPE (arg0)) == POINTER_TYPE && ((POINTER_TYPE_P (TREE_TYPE (arg0))
&& (TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
== FUNCTION_TYPE)) || (POINTER_TYPE_P (TREE_TYPE (arg1))
|| (TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
&& (TREE_CODE (TREE_TYPE (TREE_TYPE (arg1)))
== FUNCTION_TYPE))))
return 0; return 0;
STRIP_NOPS (arg0); STRIP_NOPS (arg0);
......
...@@ -4956,8 +4956,8 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, ...@@ -4956,8 +4956,8 @@ build_range_check (location_t loc, tree type, tree exp, int in_p,
/* Disable this optimization for function pointer expressions /* Disable this optimization for function pointer expressions
on targets that require function pointer canonicalization. */ on targets that require function pointer canonicalization. */
if (targetm.have_canonicalize_funcptr_for_compare () if (targetm.have_canonicalize_funcptr_for_compare ()
&& TREE_CODE (etype) == POINTER_TYPE && POINTER_TYPE_P (etype)
&& TREE_CODE (TREE_TYPE (etype)) == FUNCTION_TYPE) && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (etype)))
return NULL_TREE; return NULL_TREE;
if (! in_p) if (! in_p)
......
...@@ -3558,8 +3558,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -3558,8 +3558,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Disable this optimization if we're casting a function pointer /* Disable this optimization if we're casting a function pointer
type on targets that require function pointer canonicalization. */ type on targets that require function pointer canonicalization. */
&& !(targetm.have_canonicalize_funcptr_for_compare () && !(targetm.have_canonicalize_funcptr_for_compare ()
&& TREE_CODE (TREE_TYPE (@00)) == POINTER_TYPE && POINTER_TYPE_P (TREE_TYPE (@00))
&& TREE_CODE (TREE_TYPE (TREE_TYPE (@00))) == FUNCTION_TYPE) && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (@00))))
&& single_use (@0)) && single_use (@0))
(if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0)) (if (TYPE_PRECISION (TREE_TYPE (@00)) == TYPE_PRECISION (TREE_TYPE (@0))
&& (TREE_CODE (@10) == INTEGER_CST && (TREE_CODE (@10) == INTEGER_CST
......
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