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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |segher at gcc dot gnu.org

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I've tried:
--- gcc/config/i386/i386.md.jj  2020-10-01 10:40:09.955758167 +0200
+++ gcc/config/i386/i386.md     2020-10-13 11:59:58.924599503 +0200
@@ -7039,6 +7039,20 @@
       (set (match_operand:SWI48 0 "register_operand")
           (minus:SWI48 (match_dup 1) (match_dup 2)))])]
   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
+
+;; Pre-reload splitter to optimize
+;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
+;; operand and no intervening flags modifications into nothing.
+(define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1"
+  [(parallel
+     [(set (reg:CC FLAGS_REG)
+          (compare:CC (neg:QI (geu:QI (reg:CCC FLAGS_REG) (const_int 0)))
+                      (ltu:QI (reg:CCC FLAGS_REG) (const_int 0))))
+      (clobber (scratch:QI))])]
+  "ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)])


 ;; Overflow setting add instructions
but unfortunately that doesn't really work:
Trying 10 -> 17:
   10: r88:QI=ltu(flags:CCC,0)
      REG_DEAD flags:CCC
   17: {flags:CCC=cmp(r88:QI-0x1,r88:QI);clobber scratch;}
      REG_DEAD r88:QI
Successfully matched this instruction:
(parallel [
        (set (reg:CC 17 flags)
            (compare:CC (neg:QI (geu:QI (reg:CCC 17 flags)
                        (const_int 0 [0])))
                (ltu:QI (reg:CCC 17 flags)
                    (const_int 0 [0]))))
        (clobber (scratch:QI))
    ])
Failed to match this instruction:
(parallel [
        (set (reg:CCC 17 flags)
            (compare:CCC (zero_extend:TI (plus:DI (plus:DI (ltu:DI (reg:CCC 17
flags)
                                (const_int 0 [0]))
                            (reg:DI 106 [ MEM[(long long unsigned int *)a_12(D)
+ 8B] ]))
                        (reg:DI 107 [ MEM[(long long unsigned int *)b_13(D) +
8B] ])))
                (plus:TI (zero_extend:TI (reg:DI 107 [ MEM[(long long unsigned
int *)b_13(D) + 8B] ]))
                    (ltu:TI (reg:CCC 17 flags)
                        (const_int 0 [0])))))
        (set (reg:DI 109)
            (plus:DI (plus:DI (ltu:DI (reg:CC 17 flags)
                        (const_int 0 [0]))
                    (reg:DI 106 [ MEM[(long long unsigned int *)a_12(D) + 8B]
]))
                (reg:DI 107 [ MEM[(long long unsigned int *)b_13(D) + 8B] ])))
    ])
I guess that is caused by the CCmode vs. CCCmode difference.
substing produces the desired:
(set (reg:CCC 17 flags)
    (compare:CCC (neg:QI (geu:QI (reg:CCC 17 flags)
                (const_int 0 [0])))
        (ltu:QI (reg:CCC 17 flags)
            (const_int 0 [0]))))
but unfortunately combine_simplify_rtx -> simplify_set breaks that.

Reply via email to