Commit 2d8fec87 by Bernd Schmidt Committed by Bernd Schmidt

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
parent 334442f2
2016-11-24 Bernd Schmidt <bschmidt@redhat.com> 2016-11-24 Bernd Schmidt <bschmidt@redhat.com>
PR rtl-optimization/78120 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. * rtlanal.c (insn_rtx_cost): Use set_rtx_cost.
PR rtl-optimization/78120 PR rtl-optimization/78120
...@@ -812,8 +812,10 @@ struct noce_if_info ...@@ -812,8 +812,10 @@ struct noce_if_info
we're optimizing for size. */ we're optimizing for size. */
bool speed_p; bool speed_p;
/* The combined cost of COND, JUMP and the costs for THEN_BB and /* An estimate of the original costs. When optimizing for size, this is the
ELSE_BB. */ 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; unsigned int original_cost;
/* Maximum permissible cost for the unconditional sequence we should /* 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) ...@@ -852,12 +854,12 @@ noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
/* Cost up the new sequence. */ /* Cost up the new sequence. */
unsigned int cost = seq_cost (seq, speed_p); 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 /* When compiling for size, we can make a reasonably accurately guess
at the size growth. */ at the size growth. When compiling for speed, use the maximum. */
if (!speed_p) return speed_p && cost <= if_info->max_seq_cost;
return cost <= if_info->original_cost;
else
return cost <= if_info->max_seq_cost;
} }
/* Helper function for noce_try_store_flag*. */ /* Helper function for noce_try_store_flag*. */
...@@ -3441,15 +3443,24 @@ noce_process_if_block (struct noce_if_info *if_info) ...@@ -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)) &if_info->then_simple))
return false; return false;
if (else_bb if (else_bb
&& ! bb_valid_for_noce_process_p (else_bb, cond, &if_info->original_cost, && !bb_valid_for_noce_process_p (else_bb, cond, &else_cost,
&if_info->else_simple)) &if_info->else_simple))
return false; 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); insn_a = last_active_insn (then_bb, FALSE);
set_a = single_set (insn_a); set_a = single_set (insn_a);
gcc_assert (set_a); gcc_assert (set_a);
......
2016-11-24 Bernd Schmidt <bschmidt@redhat.com>
PR rtl-optimization/78120
* gcc.target/i386/pr78120.c: New test.
2016-11-24 Eric Botcazou <ebotcazou@adacore.com> 2016-11-24 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c-torture/compile/20161124-1.c: New test. * gcc.c-torture/compile/20161124-1.c: New test.
......
/* { 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);
}
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