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

--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
--- gcc/config/i386/i386.md.jj  2020-10-01 10:40:09.955758167 +0200
+++ gcc/config/i386/i386.md     2020-10-13 12:30:13.438172411 +0200
@@ -7039,6 +7039,18 @@ (define_expand "subborrow<mode>_0"
       (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"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC (neg:QI (geu:QI (reg:CCC FLAGS_REG) (const_int 0)))
+                    (ltu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
+  "ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)])


 ;; Overflow setting add instructions

--- gcc/config/i386/i386.c.jj   2020-10-01 10:40:09.951758225 +0200
+++ gcc/config/i386/i386.c      2020-10-13 12:45:33.209848289 +0200
@@ -15136,6 +15136,20 @@ ix86_cc_mode (enum rtx_code code, rtx op
          && (rtx_equal_p (op1, XEXP (op0, 0))
              || rtx_equal_p (op1, XEXP (op0, 1))))
        return CCCmode;
+      /* Similarly for *setcc_qi_addqi3_cconly_overflow_1 pattern.  */
+      else if (code == LTU
+              && GET_CODE (op0) == NEG
+              && GET_CODE (XEXP (op0, 0)) == GEU
+              && REG_P (XEXP (XEXP (op0, 0), 0))
+              && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
+              && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
+              && XEXP (XEXP (op0, 0), 1) == const0_rtx
+              && GET_CODE (op1) == LTU
+              && REG_P (XEXP (op1, 0))
+              && GET_MODE (XEXP (op1, 0)) == CCCmode
+              && REGNO (XEXP (op1, 0)) == FLAGS_REG
+              && XEXP (op1, 1) == const0_rtx)
+       return CCCmode;
       else
        return CCmode;
     case GTU:                  /* CF=0 & ZF=0 */
@@ -19773,6 +19787,24 @@ ix86_rtx_costs (rtx x, machine_mode mode
          return true;
        }

+      if (mode == CCCmode
+         && GET_CODE (XEXP (x, 0)) == NEG
+         && GET_CODE (XEXP (XEXP (x, 0), 0)) == GEU
+         && REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0))
+         && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == CCCmode
+         && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == FLAGS_REG
+         && XEXP (XEXP (XEXP (x, 0), 0), 1) == const0_rtx
+         && GET_CODE (XEXP (x, 1)) == LTU
+         && REG_P (XEXP (XEXP (x, 1), 0))
+         && GET_MODE (XEXP (XEXP (x, 1), 0)) == CCCmode
+         && REGNO (XEXP (XEXP (x, 1), 0)) == FLAGS_REG
+         && XEXP (XEXP (x, 1), 1) == const0_rtx)
+       {
+         /* This is *setcc_qi_addqi3_cconly_overflow_1 pattern, a nop.  */
+         *total = 0;
+         return true;
+       }
+
       /* The embedded comparison operand is completely free.  */
       if (!general_operand (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
          && XEXP (x, 1) == const0_rtx)

seems to work.

Reply via email to