Hello! Based on discussion at [1], there was an oversight when r/r/0 alternative was added to add*_1 patterns. This alternative should also be added to other add*_X patterns, otherwise combined add+compare patterns won't be matched post-reload.
2012-04-23 Uros Bizjak <ubiz...@gmail.com> PR target/53020 * config/i386/i386.md (*add<mode>_2): Add r/r/0 alternative. (*addsi_2_zext): Ditto. (*add<mode>_3): Ditto. (*addsi_3_zext): Ditto. (*add<mode>_5): Ditto. Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. [1] http://gcc.gnu.org/ml/gcc-patches/2012-04/msg01400.html Uros.
Index: i386.md =================================================================== --- i386.md (revision 186721) +++ i386.md (working copy) @@ -5811,10 +5811,10 @@ [(set (reg FLAGS_REG) (compare (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") + (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")) (const_int 0))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") + (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>") (plus:SWI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" @@ -5831,6 +5831,13 @@ } default: + if (which_alternative == 2) + { + rtx tmp; + tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; + } + + gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; @@ -5852,10 +5859,10 @@ (define_insn "*addsi_2_zext" [(set (reg FLAGS_REG) (compare - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") + (match_operand:SI 2 "x86_64_general_operand" "rme,0")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=r") + (set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (PLUS, SImode, operands)" @@ -5872,6 +5879,13 @@ } default: + if (which_alternative == 1) + { + rtx tmp; + tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; + } + + gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], SImode)) return "sub{l}\t{%2, %k0|%k0, %2}"; @@ -5892,9 +5906,9 @@ (define_insn "*add<mode>_3" [(set (reg FLAGS_REG) (compare - (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>")) - (match_operand:SWI 1 "nonimmediate_operand" "%0"))) - (clobber (match_scratch:SWI 0 "=<r>"))] + (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) + (clobber (match_scratch:SWI 0 "=<r>,<r>"))] "ix86_match_ccmode (insn, CCZmode) && !(MEM_P (operands[1]) && MEM_P (operands[2]))" { @@ -5910,6 +5924,13 @@ } default: + if (which_alternative == 1) + { + rtx tmp; + tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; + } + + gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; @@ -5931,9 +5952,9 @@ (define_insn "*addsi_3_zext" [(set (reg FLAGS_REG) (compare - (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme")) - (match_operand:SI 1 "nonimmediate_operand" "%0"))) - (set (match_operand:DI 0 "register_operand" "=r") + (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) + (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) + (set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) && ix86_binary_operator_ok (PLUS, SImode, operands)" @@ -5950,6 +5971,13 @@ } default: + if (which_alternative == 1) + { + rtx tmp; + tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; + } + + gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], SImode)) return "sub{l}\t{%2, %k0|%k0, %2}"; @@ -6060,10 +6088,10 @@ [(set (reg FLAGS_REG) (compare (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0") - (match_operand:SWI 2 "<general_operand>" "<g>")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") + (match_operand:SWI 2 "<general_operand>" "<g>,0")) (const_int 0))) - (clobber (match_scratch:SWI 0 "=<r>"))] + (clobber (match_scratch:SWI 0 "=<r>,<r>"))] "ix86_match_ccmode (insn, CCGOCmode) && !(MEM_P (operands[1]) && MEM_P (operands[2]))" { @@ -6079,6 +6107,13 @@ } default: + if (which_alternative == 1) + { + rtx tmp; + tmp = operands[1], operands[1] = operands[2], operands[2] = tmp; + } + + gcc_assert (rtx_equal_p (operands[0], operands[1])); if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";