https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67317

Uroš Bizjak <ubizjak at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |ubizjak at gmail dot com

--- Comment #6 from Uroš Bizjak <ubizjak at gmail dot com> ---
Created attachment 36258
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36258&action=edit
Proposed patch

This patch changes expanders of carry-handling builtins to use
addqi3_cconly_overflow and canonicalizes carry hanling insn to what combine can
process:

(define_insn "addcarry<mode>"
  [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (plus:SWI48
            (plus:SWI48
              (match_operator:SWI48 4 "ix86_carry_flag_operator"
               [(match_operand 3 "flags_reg_operand") (const_int 0)])
              (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
            (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
          (match_dup 1)))
   (set (match_operand:SWI48 0 "register_operand" "=r")
        (plus:SWI48 (plus:SWI48 (match_op_dup 4
                                 [(match_dup 3) (const_int 0)])
                                (match_dup 1))
                    (match_dup 2)))]
  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
  [(set_attr "type" "alu")
   (set_attr "use_carry" "1")
   (set_attr "pent_pair" "pu")
   (set_attr "mode" "<MODE>")])

and

(define_insn "subborrow<mode>"
  [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (match_operand:SWI48 1 "nonimmediate_operand" "0")
          (plus:SWI48
            (match_operator:SWI48 4 "ix86_carry_flag_operator"
             [(match_operand 3 "flags_reg_operand") (const_int 0)])
            (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
   (set (match_operand:SWI48 0 "register_operand" "=r")
        (minus:SWI48 (minus:SWI48 (match_dup 1)
                                  (match_op_dup 4
                                   [(match_dup 3) (const_int 0)]))
                     (match_dup 2)))]
  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
  [(set_attr "type" "alu")
   (set_attr "use_carry" "1")
   (set_attr "pent_pair" "pu")
   (set_attr "mode" "<MODE>")])

The patch also rewrites expander to fix a bug, where carry-clobbering insns
were emitted inside carry-flag def-use chain.

For the testcase, patched gcc generates:

testcarry_u64:
        addq    %rdi, %rdx
        adcq    %rsi, %rcx
        movq    %rdx, %rax
        xorq    %rcx, %rax
        ret

Reply via email to