From: Jakub Jelinek Date: Tue, 24 Oct 2017 10:44:56 +0000 (+0200) Subject: re PR rtl-optimization/82628 (wrong code at -Os on x86_64-linux-gnu in the 32-bit... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b75200689b0d86be5c3b91afb7303575359622ae;p=gcc.git re PR rtl-optimization/82628 (wrong code at -Os on x86_64-linux-gnu in the 32-bit mode) PR target/82628 * config/i386/i386.md (addcarry, subborrow): Change patterns to better describe from which operation the CF is computed. (addcarry_0, subborrow_0): New patterns. * config/i386/i386.c (ix86_expand_builtin) : Pass one LTU with [DT]Imode and another one with [SD]Imode. If arg0 is 0, use _0 suffixed expanders instead of emitting a comparison before it. From-SVN: r254039 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 82d69edfb0b..c2c3a523405 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-10-24 Jakub Jelinek + + PR target/82628 + * config/i386/i386.md (addcarry, subborrow): Change + patterns to better describe from which operation the CF is computed. + (addcarry_0, subborrow_0): New patterns. + * config/i386/i386.c (ix86_expand_builtin) : Pass + one LTU with [DT]Imode and another one with [SD]Imode. If arg0 + is 0, use _0 suffixed expanders instead of emitting a comparison + before it. + 2017-10-06 Sergey Shalnov * config/i386/i386.md(*movsf_internal, *movdf_internal): diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 72caf62bbf8..d8241fa15cd 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -35080,10 +35080,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, int ignore) { size_t i; - enum insn_code icode; + enum insn_code icode, icode2; tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); tree arg0, arg1, arg2, arg3, arg4; - rtx op0, op1, op2, op3, op4, pat, insn; + rtx op0, op1, op2, op3, op4, pat, pat2, insn; machine_mode mode0, mode1, mode2, mode3, mode4; unsigned int fcode = DECL_FUNCTION_CODE (fndecl); @@ -36058,22 +36058,34 @@ rdseed_step: case IX86_BUILTIN_SBB32: icode = CODE_FOR_subborrowsi; + icode2 = CODE_FOR_subborrowsi_0; mode0 = SImode; + mode1 = DImode; + mode2 = CCmode; goto handlecarry; case IX86_BUILTIN_SBB64: icode = CODE_FOR_subborrowdi; + icode2 = CODE_FOR_subborrowdi_0; mode0 = DImode; + mode1 = TImode; + mode2 = CCmode; goto handlecarry; case IX86_BUILTIN_ADDCARRYX32: icode = CODE_FOR_addcarrysi; + icode2 = CODE_FOR_addcarrysi_0; mode0 = SImode; + mode1 = DImode; + mode2 = CCCmode; goto handlecarry; case IX86_BUILTIN_ADDCARRYX64: icode = CODE_FOR_addcarrydi; + icode2 = CODE_FOR_addcarrydi_0; mode0 = DImode; + mode1 = TImode; + mode2 = CCCmode; handlecarry: arg0 = CALL_EXPR_ARG (exp, 0); /* unsigned char c_in. */ @@ -36082,7 +36094,8 @@ rdseed_step: arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out. */ op1 = expand_normal (arg0); - op1 = copy_to_mode_reg (QImode, convert_to_mode (QImode, op1, 1)); + if (!integer_zerop (arg0)) + op1 = copy_to_mode_reg (QImode, convert_to_mode (QImode, op1, 1)); op2 = expand_normal (arg1); if (!register_operand (op2, mode0)) @@ -36099,21 +36112,31 @@ rdseed_step: op4 = copy_addr_to_reg (op4); } - /* Generate CF from input operand. */ - emit_insn (gen_addqi3_cconly_overflow (op1, constm1_rtx)); - - /* Generate instruction that consumes CF. */ op0 = gen_reg_rtx (mode0); + if (integer_zerop (arg0)) + { + /* If arg0 is 0, optimize right away into add or sub + instruction that sets CCCmode flags. */ + op1 = gen_rtx_REG (mode2, FLAGS_REG); + emit_insn (GEN_FCN (icode2) (op0, op2, op3)); + } + else + { + /* Generate CF from input operand. */ + emit_insn (gen_addqi3_cconly_overflow (op1, constm1_rtx)); - op1 = gen_rtx_REG (CCCmode, FLAGS_REG); - pat = gen_rtx_LTU (mode0, op1, const0_rtx); - emit_insn (GEN_FCN (icode) (op0, op2, op3, op1, pat)); + /* Generate instruction that consumes CF. */ + op1 = gen_rtx_REG (CCCmode, FLAGS_REG); + pat = gen_rtx_LTU (mode1, op1, const0_rtx); + pat2 = gen_rtx_LTU (mode0, op1, const0_rtx); + emit_insn (GEN_FCN (icode) (op0, op2, op3, op1, pat, pat2)); + } /* Return current CF value. */ if (target == 0) target = gen_reg_rtx (QImode); - PUT_MODE (pat, QImode); + pat = gen_rtx_LTU (QImode, op1, const0_rtx); emit_insn (gen_rtx_SET (target, pat)); /* Store the result. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d5792eb22a4..49ad0394fb5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6844,15 +6844,19 @@ (define_insn "addcarry" [(set (reg:CCC FLAGS_REG) (compare:CCC - (plus:SWI48 + (zero_extend: (plus:SWI48 - (match_operator:SWI48 4 "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_dup 1))) + (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"))) + (plus: + (zero_extend: (match_dup 2)) + (match_operator: 4 "ix86_carry_flag_operator" + [(match_dup 3) (const_int 0)])))) (set (match_operand:SWI48 0 "register_operand" "=r") - (plus:SWI48 (plus:SWI48 (match_op_dup 4 + (plus:SWI48 (plus:SWI48 (match_op_dup 5 [(match_dup 3) (const_int 0)]) (match_dup 1)) (match_dup 2)))] @@ -6863,6 +6867,18 @@ (set_attr "pent_pair" "pu") (set_attr "mode" "")]) +(define_expand "addcarry_0" + [(parallel + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand") + (match_operand:SWI48 2 "x86_64_general_operand")) + (match_dup 1))) + (set (match_operand:SWI48 0 "register_operand") + (plus:SWI48 (match_dup 1) (match_dup 2)))])] + "ix86_binary_operator_ok (PLUS, mode, operands)") + (define_insn "sub3_carry" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,") (minus:SWI @@ -6945,15 +6961,18 @@ (define_insn "subborrow" [(set (reg:CCC FLAGS_REG) (compare:CCC - (match_operand:SWI48 1 "nonimmediate_operand" "0") - (plus:SWI48 - (match_operator:SWI48 4 "ix86_carry_flag_operator" - [(match_operand 3 "flags_reg_operand") (const_int 0)]) - (match_operand:SWI48 2 "nonimmediate_operand" "rm")))) + (zero_extend: + (match_operand:SWI48 1 "nonimmediate_operand" "0")) + (plus: + (match_operator: 4 "ix86_carry_flag_operator" + [(match_operand 3 "flags_reg_operand") (const_int 0)]) + (zero_extend: + (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))) (set (match_operand:SWI48 0 "register_operand" "=r") - (minus:SWI48 (minus:SWI48 (match_dup 1) - (match_op_dup 4 - [(match_dup 3) (const_int 0)])) + (minus:SWI48 (minus:SWI48 + (match_dup 1) + (match_operator:SWI48 5 "ix86_carry_flag_operator" + [(match_dup 3) (const_int 0)])) (match_dup 2)))] "ix86_binary_operator_ok (MINUS, mode, operands)" "sbb{}\t{%2, %0|%0, %2}" @@ -6961,6 +6980,16 @@ (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "")]) + +(define_expand "subborrow_0" + [(parallel + [(set (reg:CC FLAGS_REG) + (compare:CC + (match_operand:SWI48 1 "nonimmediate_operand") + (match_operand:SWI48 2 ""))) + (set (match_operand:SWI48 0 "register_operand") + (minus:SWI48 (match_dup 1) (match_dup 2)))])] + "ix86_binary_operator_ok (MINUS, mode, operands)") ;; Overflow setting add instructions