From: Oleg Endo Date: Wed, 28 Sep 2011 21:43:01 +0000 (+0000) Subject: re PR bootstrap/49486 (Bootstrap failure) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=39f2bcb5e15aa41a156ac55a0466aa3bb82bc327;p=gcc.git re PR bootstrap/49486 (Bootstrap failure) PR target/49486 * config/sh/sh.md (negdi2): Move expansion into split to allow more combination options. Add T_REG clobber. (abssi2): New expander. (*negdi2, *abssi2, *negabssi2): New insns. (cneg): Change from insn to insn_and_split. Rename to negsi_cond. Add alternative for non-SH4. * gcc.target/sh/pr49468-si.c: New. From-SVN: r179320 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98d926a89cc..2aae5aa48f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-09-28 Oleg Endo + + PR target/49486 + * config/sh/sh.md (negdi2): Move expansion into split to + allow more combination options. Add T_REG clobber. + (abssi2): New expander. + (*negdi2, *abssi2, *negabssi2): New insns. + (cneg): Change from insn to insn_and_split. Rename to + negsi_cond. Add alternative for non-SH4. + 2011-09-28 Richard Sandiford * config/arm/neon.md (neon_move_lo_quad_): Delete. diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index f2c4e551ada..63cb9393653 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -4282,28 +4282,39 @@ label: "sub r63, %1, %0" [(set_attr "type" "arith_media")]) + + +;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be +;; combined. (define_expand "negdi2" - [(set (match_operand:DI 0 "arith_reg_operand" "") - (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))] + [(set (match_operand:DI 0 "arith_reg_dest" "") + (neg:DI (match_operand:DI 1 "arith_reg_operand" ""))) + (clobber (reg:SI T_REG))] "" + "") + +(define_insn_and_split "*negdi2" + [(set (match_operand:DI 0 "arith_reg_dest" "=r") + (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))] + "TARGET_SH1" + "#" + "TARGET_SH1" + [(const_int 0)] " { - if (TARGET_SH1) - { - int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); - int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); + int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); + int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); - rtx low_src = operand_subword (operands[1], low_word, 0, DImode); - rtx high_src = operand_subword (operands[1], high_word, 0, DImode); + rtx low_src = operand_subword (operands[1], low_word, 0, DImode); + rtx high_src = operand_subword (operands[1], high_word, 0, DImode); - rtx low_dst = operand_subword (operands[0], low_word, 1, DImode); - rtx high_dst = operand_subword (operands[0], high_word, 1, DImode); + rtx low_dst = operand_subword (operands[0], low_word, 1, DImode); + rtx high_dst = operand_subword (operands[0], high_word, 1, DImode); - emit_insn (gen_clrt ()); - emit_insn (gen_negc (low_dst, low_src)); - emit_insn (gen_negc (high_dst, high_src)); - DONE; - } + emit_insn (gen_clrt ()); + emit_insn (gen_negc (low_dst, low_src)); + emit_insn (gen_negc (high_dst, high_src)); + DONE; }") (define_insn "negsi2" @@ -4326,27 +4337,77 @@ label: (const_int -1)))] "TARGET_SHMEDIA" "") -/* The SH4 202 can do zero-offset branches without pipeline stalls. - This can be used as some kind of conditional execution, which is useful - for abs. */ -(define_split +(define_expand "abssi2" [(set (match_operand:SI 0 "arith_reg_dest" "") - (plus:SI (xor:SI (neg:SI (reg:SI T_REG)) - (match_operand:SI 1 "arith_reg_operand" "")) - (reg:SI T_REG)))] - "TARGET_HARD_SH4" + (abs:SI (match_operand:SI 1 "arith_reg_operand" ""))) + (clobber (reg:SI T_REG))] + "" + "") + +(define_insn_and_split "*abssi2" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))] + "TARGET_SH1" + "#" + "TARGET_SH1" [(const_int 0)] - "emit_insn (gen_movsi_i (operands[0], operands[1])); - emit_insn (gen_cneg (operands[0], operands[0], operands[0])); - DONE;") + " +{ + emit_insn (gen_cmpgesi_t (operands[1], const0_rtx)); + emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1], + const1_rtx)); + DONE; +}") -(define_insn "cneg" +(define_insn_and_split "*negabssi2" [(set (match_operand:SI 0 "arith_reg_dest" "=r") - (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0)) - (match_operand:SI 1 "arith_reg_operand" "0") - (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))] + (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))] + "TARGET_SH1" + "#" + "TARGET_SH1" + [(const_int 0)] + " +{ + emit_insn (gen_cmpgesi_t (operands[1], const0_rtx)); + emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1], + const0_rtx)); + DONE; +}") + + +;; The SH4 202 can do zero-offset branches without pipeline stalls. +;; This can be used as some kind of conditional execution, which is useful +;; for abs. +;; Actually the instruction scheduling should decide whether to use a +;; zero-offset branch or not for any generic case involving a single +;; instruction on SH4 202. + +(define_insn_and_split "negsi_cond" + [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") + (if_then_else:SI (eq:SI (reg:SI T_REG) + (match_operand:SI 3 "const_int_operand" "M,N")) + (match_operand:SI 1 "arith_reg_operand" "0,0") + (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))] "TARGET_HARD_SH4" - "bf 0f\;neg %2,%0\\n0:" + "@ + bt\\t0f\;neg\\t%2,%0\\n0: + bf\\t0f\;neg\\t%2,%0\\n0:" + "!TARGET_HARD_SH4" + [(const_int 0)] + " +{ + rtx skip_neg_label = gen_label_rtx (); + + emit_insn (gen_movsi (operands[0], operands[1])); + + emit_jump_insn (INTVAL (operands[3]) + ? gen_branch_true (skip_neg_label) + : gen_branch_false (skip_neg_label)); + + emit_label_after (skip_neg_label, + emit_insn (gen_negsi2 (operands[0], operands[1]))); + DONE; +}" [(set_attr "type" "arith") ;; poor approximation (set_attr "length" "4")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b760725e0eb..d19933a8746 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-09-28 Oleg Endo + + PR target/49486 + * gcc.target/sh/pr49468-si.c: New. + 2011-09-28 Tom de Vries PR testsuite/50485 diff --git a/gcc/testsuite/gcc.target/sh/pr49468-si.c b/gcc/testsuite/gcc.target/sh/pr49468-si.c new file mode 100644 index 00000000000..69fbe230efa --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/pr49468-si.c @@ -0,0 +1,22 @@ +/* Check that 32 bit integer abs is generated as neg instruction and + conditional branch instead of default branch-free code. */ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-O1" } */ +/* { dg-final { scan-assembler-times "neg" 2 } } */ + + +/* Normal integer absolute value. */ +int +abs_0 (int i) +{ + return (i < 0) ? -i : i; +} + +/* Negated integer absolute value. + The generated code should be the same, except that the branch + condition is inverted. */ +int +abs_1 (int i) +{ + return (i > 0) ? -i : i; +}