]> gcc.gnu.org Git - gcc.git/commitdiff
i386: Add peephole2 patterns to improve add with carry or subtract with borrow with...
authorJakub Jelinek <jakub@redhat.com>
Thu, 15 Jun 2023 07:05:01 +0000 (09:05 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 15 Jun 2023 07:05:01 +0000 (09:05 +0200)
This patch adds various peephole2s which help to recognize add with
carry or subtract with borrow with memory destination.

2023-06-14  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/79173
* config/i386/i386.md (*sub<mode>_3, @add<mode>3_carry,
addcarry<mode>, @sub<mode>3_carry, *add<mode>3_cc_overflow_1): Add
define_peephole2 TARGET_READ_MODIFY_WRITE/-Os patterns to prefer
using memory destination in these patterns.

gcc/config/i386/i386.md

index 0929115ed4ddc56dd4209d0861be6f24bbbac2bc..23be04f521860ccfa85eb332f70807aa6bbf0ec9 100644 (file)
   [(set (reg:CC FLAGS_REG)
        (compare:CC (match_dup 0) (match_dup 1)))])
 
+(define_peephole2
+  [(set (match_operand:SWI 0 "general_reg_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (reg:CC FLAGS_REG)
+                  (compare:CC (match_dup 0)
+                              (match_operand:SWI 2 "memory_operand")))
+             (set (match_dup 0)
+                  (minus:SWI (match_dup 0) (match_dup 2)))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (reg:CC FLAGS_REG)
+                  (compare:CC (match_dup 1) (match_dup 0)))
+             (set (match_dup 1)
+                  (minus:SWI (match_dup 1) (match_dup 0)))])])
+
 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
 ;; subl $1, %eax; jnc .Lxx;
 (define_peephole2
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
 
+(define_peephole2
+  [(set (match_operand:SWI 0 "general_reg_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (match_dup 0)
+                  (plus:SWI
+                    (plus:SWI
+                      (match_operator:SWI 4 "ix86_carry_flag_operator"
+                        [(match_operand 3 "flags_reg_operand")
+                         (const_int 0)])
+                      (match_dup 0))
+                    (match_operand:SWI 2 "memory_operand")))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (match_dup 1)
+                  (plus:SWI (plus:SWI (match_op_dup 4
+                                        [(match_dup 3) (const_int 0)])
+                                      (match_dup 1))
+                            (match_dup 0)))
+             (clobber (reg:CC FLAGS_REG))])])
+
+(define_peephole2
+  [(set (match_operand:SWI 0 "general_reg_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (match_dup 0)
+                  (plus:SWI
+                    (plus:SWI
+                      (match_operator:SWI 4 "ix86_carry_flag_operator"
+                        [(match_operand 3 "flags_reg_operand")
+                         (const_int 0)])
+                      (match_dup 0))
+                    (match_operand:SWI 2 "memory_operand")))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
+   (set (match_dup 1) (match_dup 5))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && peep2_reg_dead_p (4, operands[5])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && !reg_overlap_mentioned_p (operands[5], operands[1])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (match_dup 1)
+                  (plus:SWI (plus:SWI (match_op_dup 4
+                                        [(match_dup 3) (const_int 0)])
+                                      (match_dup 1))
+                            (match_dup 0)))
+             (clobber (reg:CC FLAGS_REG))])])
+
 (define_insn "*add<mode>3_carry_0"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
        (plus:SWI
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
 
+(define_peephole2
+  [(parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (zero_extend:<DWI>
+                      (plus:SWI48
+                        (plus:SWI48
+                          (match_operator:SWI48 4 "ix86_carry_flag_operator"
+                            [(match_operand 2 "flags_reg_operand")
+                             (const_int 0)])
+                          (match_operand:SWI48 0 "general_reg_operand"))
+                        (match_operand:SWI48 1 "memory_operand")))
+                    (plus:<DWI>
+                      (zero_extend:<DWI> (match_dup 1))
+                      (match_operator:<DWI> 3 "ix86_carry_flag_operator"
+                        [(match_dup 2) (const_int 0)]))))
+             (set (match_dup 0)
+                  (plus:SWI48 (plus:SWI48 (match_op_dup 4
+                                            [(match_dup 2) (const_int 0)])
+                                          (match_dup 0))
+                              (match_dup 1)))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (2, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])"
+  [(parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (zero_extend:<DWI>
+                      (plus:SWI48
+                        (plus:SWI48
+                          (match_op_dup 4
+                            [(match_dup 2) (const_int 0)])
+                          (match_dup 1))
+                        (match_dup 0)))
+                    (plus:<DWI>
+                      (zero_extend:<DWI> (match_dup 0))
+                      (match_op_dup 3
+                        [(match_dup 2) (const_int 0)]))))
+             (set (match_dup 1)
+                  (plus:SWI48 (plus:SWI48 (match_op_dup 4
+                                            [(match_dup 2) (const_int 0)])
+                                          (match_dup 1))
+                              (match_dup 0)))])])
+
+(define_peephole2
+  [(set (match_operand:SWI48 0 "general_reg_operand")
+       (match_operand:SWI48 1 "memory_operand"))
+   (parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (zero_extend:<DWI>
+                      (plus:SWI48
+                        (plus:SWI48
+                          (match_operator:SWI48 5 "ix86_carry_flag_operator"
+                            [(match_operand 3 "flags_reg_operand")
+                             (const_int 0)])
+                          (match_dup 0))
+                        (match_operand:SWI48 2 "memory_operand")))
+                    (plus:<DWI>
+                      (zero_extend:<DWI> (match_dup 2))
+                      (match_operator:<DWI> 4 "ix86_carry_flag_operator"
+                        [(match_dup 3) (const_int 0)]))))
+             (set (match_dup 0)
+                  (plus:SWI48 (plus:SWI48 (match_op_dup 5
+                                            [(match_dup 3) (const_int 0)])
+                                          (match_dup 0))
+                              (match_dup 2)))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (zero_extend:<DWI>
+                      (plus:SWI48
+                        (plus:SWI48
+                          (match_op_dup 5
+                            [(match_dup 3) (const_int 0)])
+                          (match_dup 1))
+                        (match_dup 0)))
+                    (plus:<DWI>
+                      (zero_extend:<DWI> (match_dup 0))
+                      (match_op_dup 4
+                        [(match_dup 3) (const_int 0)]))))
+             (set (match_dup 1)
+                  (plus:SWI48 (plus:SWI48 (match_op_dup 5
+                                            [(match_dup 3) (const_int 0)])
+                                          (match_dup 1))
+                              (match_dup 0)))])])
+
+(define_peephole2
+  [(parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (zero_extend:<DWI>
+                      (plus:SWI48
+                        (plus:SWI48
+                          (match_operator:SWI48 4 "ix86_carry_flag_operator"
+                            [(match_operand 2 "flags_reg_operand")
+                             (const_int 0)])
+                          (match_operand:SWI48 0 "general_reg_operand"))
+                        (match_operand:SWI48 1 "memory_operand")))
+                    (plus:<DWI>
+                      (zero_extend:<DWI> (match_dup 1))
+                      (match_operator:<DWI> 3 "ix86_carry_flag_operator"
+                        [(match_dup 2) (const_int 0)]))))
+             (set (match_dup 0)
+                  (plus:SWI48 (plus:SWI48 (match_op_dup 4
+                                            [(match_dup 2) (const_int 0)])
+                                          (match_dup 0))
+                              (match_dup 1)))])
+   (set (match_operand:QI 5 "general_reg_operand")
+       (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
+   (set (match_operand:SWI48 6 "general_reg_operand")
+       (zero_extend:SWI48 (match_dup 5)))
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (4, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[5])
+   && !reg_overlap_mentioned_p (operands[5], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[6])
+   && !reg_overlap_mentioned_p (operands[6], operands[1])"
+  [(parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (zero_extend:<DWI>
+                      (plus:SWI48
+                        (plus:SWI48
+                          (match_op_dup 4
+                            [(match_dup 2) (const_int 0)])
+                          (match_dup 1))
+                        (match_dup 0)))
+                    (plus:<DWI>
+                      (zero_extend:<DWI> (match_dup 0))
+                      (match_op_dup 3
+                        [(match_dup 2) (const_int 0)]))))
+             (set (match_dup 1)
+                  (plus:SWI48 (plus:SWI48 (match_op_dup 4
+                                            [(match_dup 2) (const_int 0)])
+                                          (match_dup 1))
+                              (match_dup 0)))])
+   (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
+   (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
+
 (define_expand "addcarry<mode>_0"
   [(parallel
      [(set (reg:CCC FLAGS_REG)
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
 
+(define_peephole2
+  [(set (match_operand:SWI 0 "general_reg_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (match_dup 0)
+                  (minus:SWI
+                    (minus:SWI
+                      (match_dup 0)
+                      (match_operator:SWI 4 "ix86_carry_flag_operator"
+                        [(match_operand 3 "flags_reg_operand")
+                         (const_int 0)]))
+                    (match_operand:SWI 2 "memory_operand")))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (match_dup 1)
+                  (minus:SWI (minus:SWI (match_dup 1)
+                                        (match_op_dup 4
+                                          [(match_dup 3) (const_int 0)]))
+                             (match_dup 0)))
+             (clobber (reg:CC FLAGS_REG))])])
+
+(define_peephole2
+  [(set (match_operand:SWI 0 "general_reg_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (match_dup 0)
+                  (minus:SWI
+                    (minus:SWI
+                      (match_dup 0)
+                      (match_operator:SWI 4 "ix86_carry_flag_operator"
+                        [(match_operand 3 "flags_reg_operand")
+                         (const_int 0)]))
+                    (match_operand:SWI 2 "memory_operand")))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
+   (set (match_dup 1) (match_dup 5))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && peep2_reg_dead_p (4, operands[5])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && !reg_overlap_mentioned_p (operands[5], operands[1])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (match_dup 1)
+                  (minus:SWI (minus:SWI (match_dup 1)
+                                        (match_op_dup 4
+                                          [(match_dup 3) (const_int 0)]))
+                             (match_dup 0)))
+             (clobber (reg:CC FLAGS_REG))])])
+
 (define_insn "*sub<mode>3_carry_0"
   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
        (minus:SWI
                     (match_dup 1)))
              (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
 
+(define_peephole2
+  [(set (match_operand:SWI 0 "general_reg_operand")
+       (match_operand:SWI 1 "memory_operand"))
+   (parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (plus:SWI (match_dup 0)
+                              (match_operand:SWI 2 "memory_operand"))
+                    (match_dup 0)))
+             (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
+   (set (match_dup 1) (match_dup 0))]
+  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
+   && peep2_reg_dead_p (3, operands[0])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])
+   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 0) (match_dup 2))
+   (parallel [(set (reg:CCC FLAGS_REG)
+                  (compare:CCC
+                    (plus:SWI (match_dup 1) (match_dup 0))
+                    (match_dup 1)))
+             (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
+
 (define_insn "*addsi3_zext_cc_overflow_1"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
This page took 0.113573 seconds and 5 git commands to generate.