From 2d8fec87b11ecfad75f8cae7910e60e1a61ec61b Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Thu, 24 Nov 2016 12:22:16 +0000 Subject: [PATCH] re PR rtl-optimization/78120 (If conversion no longer performed) PR rtl-optimization/78120 * ifcvt.c (noce_conversion_profitable_p): Check original cost in all cases, and additionally test against max_seq_cost for speed optimization. (noce_process_if_block): Compute an estimate for the original cost when optimizing for speed, using the minimum of then and else block costs. testsuite/ PR rtl-optimization/78120 * gcc.target/i386/pr78120.c: New test. From-SVN: r242834 --- gcc/ChangeLog | 7 ++++++ gcc/ifcvt.c | 31 +++++++++++++++++-------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/i386/pr78120.c | 28 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr78120.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b8d38205ac..d501ff687a0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2016-11-24 Bernd Schmidt + PR rtl-optimization/78120 + * ifcvt.c (noce_conversion_profitable_p): Check original cost in all + cases, and additionally test against max_seq_cost for speed + optimization. + (noce_process_if_block): Compute an estimate for the original cost when + optimizing for speed, using the minimum of then and else block costs. + PR rtl-optimization/78120 * rtlanal.c (insn_rtx_cost): Use set_rtx_cost. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index dbe24859870..0fdd5b7885c 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -812,8 +812,10 @@ struct noce_if_info we're optimizing for size. */ bool speed_p; - /* The combined cost of COND, JUMP and the costs for THEN_BB and - ELSE_BB. */ + /* An estimate of the original costs. When optimizing for size, this is the + combined cost of COND, JUMP and the costs for THEN_BB and ELSE_BB. + When optimizing for speed, we use the costs of COND plus the minimum of + the costs for THEN_BB and ELSE_BB, as computed in the next field. */ unsigned int original_cost; /* Maximum permissible cost for the unconditional sequence we should @@ -852,12 +854,12 @@ noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info) /* Cost up the new sequence. */ unsigned int cost = seq_cost (seq, speed_p); + if (cost <= if_info->original_cost) + return true; + /* When compiling for size, we can make a reasonably accurately guess - at the size growth. */ - if (!speed_p) - return cost <= if_info->original_cost; - else - return cost <= if_info->max_seq_cost; + at the size growth. When compiling for speed, use the maximum. */ + return speed_p && cost <= if_info->max_seq_cost; } /* Helper function for noce_try_store_flag*. */ @@ -3441,15 +3443,24 @@ noce_process_if_block (struct noce_if_info *if_info) } } - if (! bb_valid_for_noce_process_p (then_bb, cond, &if_info->original_cost, + bool speed_p = optimize_bb_for_speed_p (test_bb); + unsigned int then_cost = 0, else_cost = 0; + if (!bb_valid_for_noce_process_p (then_bb, cond, &then_cost, &if_info->then_simple)) return false; if (else_bb - && ! bb_valid_for_noce_process_p (else_bb, cond, &if_info->original_cost, - &if_info->else_simple)) + && !bb_valid_for_noce_process_p (else_bb, cond, &else_cost, + &if_info->else_simple)) return false; + if (else_bb == NULL) + if_info->original_cost += then_cost; + else if (speed_p) + if_info->original_cost += MIN (then_cost, else_cost); + else + if_info->original_cost += then_cost + else_cost; + insn_a = last_active_insn (then_bb, FALSE); set_a = single_set (insn_a); gcc_assert (set_a); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a0646446232..8a4332e769c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-24 Bernd Schmidt + + PR rtl-optimization/78120 + * gcc.target/i386/pr78120.c: New test. + 2016-11-24 Eric Botcazou * gcc.c-torture/compile/20161124-1.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr78120.c b/gcc/testsuite/gcc.target/i386/pr78120.c new file mode 100644 index 00000000000..ea8bef7e273 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr78120.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=generic" } */ +/* { dg-final { scan-assembler "adc" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ + +typedef unsigned long u64; + +typedef struct { + u64 hi, lo; +} u128; + +static inline u128 add_u128 (u128 a, u128 b) +{ + a.hi += b.hi; + a.lo += b.lo; + if (a.lo < b.lo) + a.hi++; + + return a; +} + +extern u128 t1, t2, t3; + +void foo (void) +{ + t1 = add_u128 (t1, t2); + t1 = add_u128 (t1, t3); +} -- 2.30.2