2015-02-17 Tom de Vries * fold-const.c (operand_equal_p): Handle INTERNAL_FNs. * calls.c (call_expr_flags): Same. --- gcc/calls.c | 2 ++ gcc/fold-const.c | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/gcc/calls.c b/gcc/calls.c index ec44624..2919464 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -847,6 +847,8 @@ call_expr_flags (const_tree t) if (decl) flags = flags_from_decl_or_type (decl); + else if (CALL_EXPR_FN (t) == NULL_TREE) + flags = internal_fn_flags (CALL_EXPR_IFN (t)); else { t = TREE_TYPE (CALL_EXPR_FN (t)); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8377120..3013adb 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3032,11 +3032,26 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) switch (TREE_CODE (arg0)) { case CALL_EXPR: - /* If the CALL_EXPRs call different functions, then they - clearly can not be equal. */ - if (! operand_equal_p (CALL_EXPR_FN (arg0), CALL_EXPR_FN (arg1), - flags)) + if ((CALL_EXPR_FN (arg0) == NULL_TREE) + != (CALL_EXPR_FN (arg1) == NULL_TREE)) + /* If not both CALL_EXPRs are either internal or normal function + functions, then they are not equal. */ return 0; + else if (CALL_EXPR_FN (arg0) == NULL_TREE) + { + /* If the CALL_EXPRs call different internal functions, then they + are not equal. */ + if (CALL_EXPR_IFN (arg0) != CALL_EXPR_IFN (arg1)) + return 0; + } + else + { + /* If the CALL_EXPRs call different functions, then they are not + equal. */ + if (! operand_equal_p (CALL_EXPR_FN (arg0), CALL_EXPR_FN (arg1), + flags)) + return 0; + } { unsigned int cef = call_expr_flags (arg0); -- 1.9.1