Hello!

Attached patch adjusts RTX costs to ignore addition or subtraction of
a carry flag for ADC or SBB instruction. These operations are
essentially free.

2017-05-12  Uros Bizjak  <ubiz...@gmail.com>

    PR target/80723
    * config/i386/i386.c (ix86_rtx_cost) [case PLUS]: Ignore the
    cost of adding a carry flag for ADC instruction.
    [case MINUS]: Ignore the cost of subtracting a carry flag
    for SBB instruction.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}, where
the patch fixes gcc.target/i386/cadd.c FAIL.

Committed to mainline SVN.

Uros.
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c  (revision 247980)
+++ config/i386/i386.c  (working copy)
@@ -40913,9 +40913,16 @@ ix86_rtx_costs (rtx x, machine_mode mode, int oute
            }
          else if (GET_CODE (XEXP (x, 0)) == PLUS)
            {
-             *total = cost->lea;
-             *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
-                                 outer_code, opno, speed);
+             /* Add with carry, ignore the cost of adding a carry flag.  */
+             if (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 0), mode))
+               *total = cost->add;
+             else
+               {
+                 *total = cost->lea;
+                 *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
+                                     outer_code, opno, speed);
+               }
+
              *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
                                  outer_code, opno, speed);
              *total += rtx_cost (XEXP (x, 1), mode,
@@ -40926,6 +40933,20 @@ ix86_rtx_costs (rtx x, machine_mode mode, int oute
       /* FALLTHRU */
 
     case MINUS:
+      /* Subtract with borrow, ignore the cost of subtracting a carry flag.  */
+      if (GET_MODE_CLASS (mode) == MODE_INT
+         && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
+         && GET_CODE (XEXP (x, 0)) == MINUS
+         && ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode))
+       {
+         *total = cost->add;
+         *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
+                             outer_code, opno, speed);
+         *total += rtx_cost (XEXP (x, 1), mode,
+                             outer_code, opno, speed);
+         return true;
+       }
+
       if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
        {
          /* ??? SSE cost should be used here.  */

Reply via email to