re PR rtl-optimization/78120 (If conversion no longer performed)
authorBernd Schmidt <bernds@redhat.com>
Thu, 24 Nov 2016 12:22:16 +0000 (12:22 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Thu, 24 Nov 2016 12:22:16 +0000 (12:22 +0000)
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
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr78120.c [new file with mode: 0644]

index 7b8d382..d501ff6 100644 (file)
@@ -1,6 +1,13 @@
 2016-11-24  Bernd Schmidt  <bschmidt@redhat.com>
 
        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.
 
        PR rtl-optimization/78120
index dbe2485..0fdd5b7 100644 (file)
@@ -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);
index a064644..8a4332e 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        * 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 (file)
index 0000000..ea8bef7
--- /dev/null
@@ -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);
+}