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<mode>, subborrow<mode>): Change patterns to better describe from which operation the CF is computed. (addcarry<mode>_0, subborrow<mode>_0): New patterns. * config/i386/i386.c (ix86_expand_builtin) <case handlecarry>: 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
This commit is contained in:
parent
585a449d73
commit
b75200689b
3 changed files with 89 additions and 26 deletions
|
@ -1,3 +1,14 @@
|
|||
2017-10-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/82628
|
||||
* config/i386/i386.md (addcarry<mode>, subborrow<mode>): Change
|
||||
patterns to better describe from which operation the CF is computed.
|
||||
(addcarry<mode>_0, subborrow<mode>_0): New patterns.
|
||||
* config/i386/i386.c (ix86_expand_builtin) <case handlecarry>: 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 <Sergey.Shalnov@intel.com>
|
||||
|
||||
* config/i386/i386.md(*movsf_internal, *movdf_internal):
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -6844,15 +6844,19 @@
|
|||
(define_insn "addcarry<mode>"
|
||||
[(set (reg:CCC FLAGS_REG)
|
||||
(compare:CCC
|
||||
(plus:SWI48
|
||||
(zero_extend:<DWI>
|
||||
(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:<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")
|
||||
(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" "<MODE>")])
|
||||
|
||||
(define_expand "addcarry<mode>_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>mode, operands)")
|
||||
|
||||
(define_insn "sub<mode>3_carry"
|
||||
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
|
||||
(minus:SWI
|
||||
|
@ -6945,15 +6961,18 @@
|
|||
(define_insn "subborrow<mode>"
|
||||
[(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:<DWI>
|
||||
(match_operand:SWI48 1 "nonimmediate_operand" "0"))
|
||||
(plus:<DWI>
|
||||
(match_operator:<DWI> 4 "ix86_carry_flag_operator"
|
||||
[(match_operand 3 "flags_reg_operand") (const_int 0)])
|
||||
(zero_extend:<DWI>
|
||||
(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>mode, operands)"
|
||||
"sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
|
||||
|
@ -6961,6 +6980,16 @@
|
|||
(set_attr "use_carry" "1")
|
||||
(set_attr "pent_pair" "pu")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_expand "subborrow<mode>_0"
|
||||
[(parallel
|
||||
[(set (reg:CC FLAGS_REG)
|
||||
(compare:CC
|
||||
(match_operand:SWI48 1 "nonimmediate_operand")
|
||||
(match_operand:SWI48 2 "<general_operand>")))
|
||||
(set (match_operand:SWI48 0 "register_operand")
|
||||
(minus:SWI48 (match_dup 1) (match_dup 2)))])]
|
||||
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
|
||||
|
||||
;; Overflow setting add instructions
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue