Hi!

Joseph reported ia32 glibc build ICEs, because the
*adddi3_doubleword_cc_overflow_1 pattern allows a memory output and matching
input, but addcarry<mode>* to which it splits doesn't, for some strange
reason it only allows register output.  As it emits an adc instruction
which is very similar to add, I don't see the point of doing in the
predicates/constraints anything other than what add does.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2020-01-07  Jakub Jelinek  <ja...@redhat.com>

        PR target/93174
        * config/i386/i386.md (addcarry<mode>_0): Use nonimmediate_operand
        predicate for output operand instead of register_operand.
        (addcarry<mode>, addcarry<mode>_1): Likewise.  Add alternative with
        memory destination and non-memory operands[2].

        * gcc.c-torture/compile/pr93174.c: New test.

--- gcc/config/i386/i386.md.jj  2020-01-07 10:54:45.924177633 +0100
+++ gcc/config/i386/i386.md     2020-01-07 18:12:48.043555173 +0100
@@ -6786,13 +6786,13 @@ (define_insn "addcarry<mode>"
              (plus:SWI48
                (match_operator:SWI48 5 "ix86_carry_flag_operator"
                  [(match_operand 3 "flags_reg_operand") (const_int 0)])
-               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
-             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
+               (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
+             (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
          (plus:<DWI>
            (zero_extend:<DWI> (match_dup 2))
            (match_operator:<DWI> 4 "ix86_carry_flag_operator"
              [(match_dup 3) (const_int 0)]))))
-   (set (match_operand:SWI48 0 "register_operand" "=r")
+   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
        (plus:SWI48 (plus:SWI48 (match_op_dup 5
                                 [(match_dup 3) (const_int 0)])
                                (match_dup 1))
@@ -6812,7 +6812,7 @@ (define_expand "addcarry<mode>_0"
               (match_operand:SWI48 1 "nonimmediate_operand")
               (match_operand:SWI48 2 "x86_64_general_operand"))
             (match_dup 1)))
-      (set (match_operand:SWI48 0 "register_operand")
+      (set (match_operand:SWI48 0 "nonimmediate_operand")
           (plus:SWI48 (match_dup 1) (match_dup 2)))])]
   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
 
@@ -6830,7 +6830,7 @@ (define_insn "*addcarry<mode>_1"
            (match_operand:<DWI> 6 "const_scalar_int_operand" "")
            (match_operator:<DWI> 4 "ix86_carry_flag_operator"
              [(match_dup 3) (const_int 0)]))))
-   (set (match_operand:SWI48 0 "register_operand" "=r")
+   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
        (plus:SWI48 (plus:SWI48 (match_op_dup 5
                                 [(match_dup 3) (const_int 0)])
                                (match_dup 1))
--- gcc/testsuite/gcc.c-torture/compile/pr93174.c.jj    2020-01-07 
18:16:29.460185015 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr93174.c       2020-01-07 
18:15:29.716094376 +0100
@@ -0,0 +1,14 @@
+/* PR target/93174 */
+
+unsigned long long a[2];
+void bar (void);
+
+void
+foo (int c)
+{
+  int e = c >> 2;
+  a[0] += c;
+  a[1] = a[0] < c;
+  while (e--)
+    bar ();
+}

        Jakub

Reply via email to