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. */