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