https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87188
--- Comment #23 from dave.anglin at bell dot net --- On 2018-09-12 4:03 AM, rguenth at gcc dot gnu.org wrote: > --- Comment #22 from Richard Biener <rguenth at gcc dot gnu.org> --- > (In reply to dave.anglin from comment #21) >> On 2018-09-09 2:46 PM, rguenther at suse dot de wrote: >>> In the last patch you replace arg0 || arg1 with arg0 & & arg1, that looks >>> wrong. Otherwise the patch looks OK. >> It was intentional. See the comment in dojump.c: >> >> /* 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. */ >> 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)))) >> >> Based on this, I thought that we could allow do_store_flag to output a >> "scc" instruction >> when both sides weren't function or method pointers. > Ah, I see. Based on my testing, when we have a function or method pointer for one of the operands, the other operand is either a function, method or void pointer. An implicit cast occurs if one compares a function pointer to say an int or int*. Of course, a warning is generated in that case. So, we want to canonicalize when one of the operands is a function or method pointer. This canonicalizes comparisons of a function pointer and a void pointer. Attached is latest patch.