Hi! In 6.x we've changed unsigned if (a < b) a++; into ADD_OVERFLOW ifn, which results in different expanded code, which on the following testcase unfortunately doesn't combine anymore into the optimal 3 instructions.
The problem is that we want adc[lq] $0, %reg instruction, but simplify-rtx.c leaves the apparently useless (plus something const0_rtx) out, just uses something, and there is no pattern that matches that. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-03-27 Jakub Jelinek <ja...@redhat.com> PR target/85095 * config/i386/i386.md (*add<mode>3_carry0): New pattern. * gcc.target/i386/pr85095.c: New test. --- gcc/config/i386/i386.md.jj 2018-03-27 12:54:54.685244368 +0200 +++ gcc/config/i386/i386.md 2018-03-27 19:38:43.891451026 +0200 @@ -6854,6 +6854,23 @@ (define_insn "add<mode>3_carry" (set_attr "pent_pair" "pu") (set_attr "mode" "<MODE>")]) +(define_insn "*add<mode>3_carry0" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (plus:SWI + (match_operator:SWI 3 "ix86_carry_flag_operator" + [(match_operand 2 "flags_reg_operand") (const_int 0)]) + (match_operand:SWI 1 "nonimmediate_operand" "0"))) + (clobber (reg:CC FLAGS_REG))] + "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)" +{ + operands[4] = const0_rtx; + return "adc{<imodesuffix>}\t{%4, %0|%0, %4}"; +} + [(set_attr "type" "alu") + (set_attr "use_carry" "1") + (set_attr "pent_pair" "pu") + (set_attr "mode" "<MODE>")]) + (define_insn "*addsi3_carry_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI --- gcc/testsuite/gcc.target/i386/pr85095.c.jj 2018-03-27 19:49:02.985677415 +0200 +++ gcc/testsuite/gcc.target/i386/pr85095.c 2018-03-27 19:49:28.076686590 +0200 @@ -0,0 +1,13 @@ +/* PR target/85095 * +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ + +unsigned long +foo (unsigned long a, unsigned long b) +{ + a += b; + if (a < b) a++; + return a; +} + +/* { dg-final { scan-assembler-times "adc\[lq]\t\\\$0," 1 } } */ Jakub