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

--- Comment #68 from Uroš Bizjak <ubizjak at gmail dot com> ---
For the testcase in the Comment #0, we can use this PoC i386 patch:

--cut here--
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d5b90291fc9..60b279dac42 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -8313,7 +8313,7 @@ (define_insn_and_split "*lea<mode>_general_4"

 ;; Subtract instructions

-(define_expand "sub<mode>3"
+(define_expand "*sub<mode>3"
   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
        (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
@@ -8968,6 +8968,14 @@ (define_expand "usubv<mode>4"
   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
                                       TARGET_APX_NDD);")

+(define_expand "sub<mode>3"
+  [(parallel [(set (reg:CC FLAGS_REG)
+                  (compare:CC
+                    (match_operand:SWI 1 "nonimmediate_operand")
+                    (match_operand:SWI 2 "<general_operand>")))
+             (set (match_operand:SWI 0 "register_operand")
+                  (minus:SWI (match_dup 1) (match_dup 2)))])])
+
 (define_expand "sub<mode>_3"
   [(parallel [(set (reg:CC FLAGS_REG)
                   (compare:CC
--cut here--

_.cse2 pass is then able to merge:

(insn 7 4 22 2 (parallel [
            (set (reg:CC 17 flags)
                (compare:CC (reg/v:DI 101 [ a ])
                    (reg/v:DI 102 [ b ])))
            (set (reg/v:DI 100 [ <retval> ])
                (minus:DI (reg/v:DI 101 [ a ])
                    (reg/v:DI 102 [ b ])))
        ]) "pr3507.c":2:16 452 {*subdi_3}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))
(insn 22 7 23 2 (set (reg:CC 17 flags)
        (compare:CC (reg/v:DI 101 [ a ])
            (reg/v:DI 102 [ b ]))) "pr3507.c":5:6 16 {*cmpdi_1}
     (nil))

to:

(insn 7 4 23 2 (parallel [
            (set (reg:CC 17 flags)
                (compare:CC (reg/v:DI 101 [ a ])
                    (reg/v:DI 102 [ b ])))
            (set (reg/v:DI 100 [ <retval> ])
                (minus:DI (reg/v:DI 101 [ a ])
                    (reg/v:DI 102 [ b ])))
        ]) "pr3507.c":2:16 452 {*subdi_3}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

So, the idea here is to teach CSE pass to also merge:

(insn 7 4 22 2 (parallel [
            (set (reg/v:DI 100 [ <retval> ])
                (minus:DI (reg/v:DI 101 [ a ])
                    (reg/v:DI 102 [ b ])))
            (clobber (reg:CC 17 flags))
        ]) "pr3507.c":2:16 395 {*subdi_1}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))
(insn 22 7 23 2 (set (reg:CC 17 flags)
        (compare:CC (reg/v:DI 101 [ a ])
            (reg/v:DI 102 [ b ]))) "pr3507.c":5:6 16 {*cmpdi_1}
     (nil))

in the same way.

Reply via email to