On Tue, Nov 28 2017, Martin Jambor wrote: > ... > > Done, this is what I have just committed. I will prepare a conservative > fix for gcc 7 with only the expr_type_first_operand_type_p part. >
The following is what I have committed to the gcc-7-branch after a round of bootstrap and testing on an x86_64-linux. Thanks, Martin 2017-11-29 Martin Jambor <mjam...@suse.cz> PR ipa/82808 * tree.c (expr_type_first_operand_type_p): New function. * tree.h (expr_type_first_operand_type_p): Declare it. * ipa-cp.c (ipa_get_jf_pass_through_result): Use it. testsuite/ * gcc.dg/ipa/pr82808.c: New test. --- gcc/ipa-cp.c | 26 +++++++++++----------- gcc/testsuite/gcc.dg/ipa/pr82808.c | 27 +++++++++++++++++++++++ gcc/tree.c | 44 ++++++++++++++++++++++++++++++++++++++ gcc/tree.h | 1 + 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr82808.c diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index fa3d5fd7548..716c8cc3a1f 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1224,20 +1224,20 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) if (!is_gimple_ip_invariant (input)) return NULL_TREE; - if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) - == tcc_unary) - res = fold_unary (ipa_get_jf_pass_through_operation (jfunc), - TREE_TYPE (input), input); + tree_code opcode = ipa_get_jf_pass_through_operation (jfunc); + if (TREE_CODE_CLASS (opcode) == tcc_comparison) + restype = boolean_type_node; + else if (expr_type_first_operand_type_p (opcode)) + restype = TREE_TYPE (input); else - { - if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) - == tcc_comparison) - restype = boolean_type_node; - else - restype = TREE_TYPE (input); - res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype, - input, ipa_get_jf_pass_through_operand (jfunc)); - } + return NULL_TREE; + + if (TREE_CODE_CLASS (opcode) == tcc_unary) + res = fold_unary (opcode, restype, input); + else + res = fold_binary (opcode, restype, input, + ipa_get_jf_pass_through_operand (jfunc)); + if (res && !is_gimple_ip_invariant (res)) return NULL_TREE; diff --git a/gcc/testsuite/gcc.dg/ipa/pr82808.c b/gcc/testsuite/gcc.dg/ipa/pr82808.c new file mode 100644 index 00000000000..9c95d0b6ed7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr82808.c @@ -0,0 +1,27 @@ +/* { dg-options "-O2" } */ +/* { dg-do run } */ + +static void __attribute__((noinline)) +foo (double *a, double x) +{ + *a = x; +} + +static double __attribute__((noinline)) +f_c1 (int m, double *a) +{ + foo (a, m); + return *a; +} + +int +main (){ + double data; + double ret = 0 ; + + if ((ret = f_c1 (2, &data)) != 2) + { + __builtin_abort (); + } + return 0; +} diff --git a/gcc/tree.c b/gcc/tree.c index 69425ab59ee..698213c3501 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -14515,6 +14515,50 @@ get_nonnull_args (const_tree fntype) return argmap; } +/* Return true if an expression with CODE has to have the same result type as + its first operand. */ + +bool +expr_type_first_operand_type_p (tree_code code) +{ + switch (code) + { + case NEGATE_EXPR: + case ABS_EXPR: + case BIT_NOT_EXPR: + case PAREN_EXPR: + case CONJ_EXPR: + + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case TRUNC_MOD_EXPR: + case CEIL_MOD_EXPR: + case FLOOR_MOD_EXPR: + case ROUND_MOD_EXPR: + case RDIV_EXPR: + case EXACT_DIV_EXPR: + case MIN_EXPR: + case MAX_EXPR: + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: + case BIT_AND_EXPR: + + case LSHIFT_EXPR: + case RSHIFT_EXPR: + case LROTATE_EXPR: + case RROTATE_EXPR: + return true; + + default: + return false; + } +} + #if CHECKING_P namespace selftest { diff --git a/gcc/tree.h b/gcc/tree.h index 375edcd4ba6..f20b77f17e4 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5471,6 +5471,7 @@ extern void gt_pch_nx (tree &, gt_pointer_operator, void *); extern bool nonnull_arg_p (const_tree); extern bool is_redundant_typedef (const_tree); +extern bool expr_type_first_operand_type_p (tree_code); extern location_t set_source_range (tree expr, location_t start, location_t finish); -- 2.15.0