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.