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

Reply via email to