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.