Hi! The following peephole2 changes: - addl (%rdi), %esi + xorl %eax, %eax + addl %esi, (%rdi) setc %al - movl %esi, (%rdi) - movzbl %al, %eax ret on the testcase. *add<mode>3_cc_overflow_1, being an add{l,q} insn, is commutative, so if TARGET_READ_MODIFY_WRITE we can replace addl (%rdi), %esi; movl %esi, (%rdi) with addl %esi, (%rdi) if %edi is dead after those two insns.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-05-08 Jakub Jelinek <ja...@redhat.com> PR target/94857 * config/i386/i386.md (peephole2 after *add<mode>3_cc_overflow_1): New define_peephole2. * gcc.target/i386/pr94857.c: New test. --- gcc/config/i386/i386.md.jj 2020-05-06 20:03:38.489391717 +0200 +++ gcc/config/i386/i386.md 2020-05-07 19:59:45.650521607 +0200 @@ -6992,6 +6992,23 @@ (define_insn "*add<mode>3_cc_overflow_1" [(set_attr "type" "alu") (set_attr "mode" "<MODE>")]) +(define_peephole2 + [(parallel [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:SWI (match_operand:SWI 0 "general_reg_operand") + (match_operand:SWI 1 "memory_operand")) + (match_dup 0))) + (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))]) + (set (match_dup 1) (match_dup 0))] + "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) + && peep2_reg_dead_p (2, operands[0]) + && !reg_overlap_mentioned_p (operands[0], operands[1])" + [(parallel [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:SWI (match_dup 1) (match_dup 0)) + (match_dup 1))) + (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])]) + (define_insn "*addsi3_zext_cc_overflow_1" [(set (reg:CCC FLAGS_REG) (compare:CCC --- gcc/testsuite/gcc.target/i386/pr94857.c.jj 2020-05-07 20:09:16.002907217 +0200 +++ gcc/testsuite/gcc.target/i386/pr94857.c 2020-05-07 20:08:46.533351730 +0200 @@ -0,0 +1,15 @@ +/* PR target/94857 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtune=skylake -masm=att" } */ +/* { dg-final { scan-assembler "\taddl\t%\[a-z0-9]\*, \\\(" } } */ + +#ifndef __x86_64__ +__attribute__((regparm(2))) +#endif +int +foo (unsigned *p, unsigned x) +{ + unsigned u = *p; + *p += x; + return u > *p; +} Jakub