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
This commit is contained in:
Oleg Endo 2011-09-28 21:43:01 +00:00 committed by Kaz Kojima
parent 8c850a5a7f
commit 39f2bcb5e1
4 changed files with 130 additions and 32 deletions

View File

@ -1,3 +1,13 @@
2011-09-28 Oleg Endo <oleg.endo@t-online.de>
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 <richard.sandiford@linaro.org>
* config/arm/neon.md (neon_move_lo_quad_<mode>): Delete.

View File

@ -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"
[(const_int 0)]
"emit_insn (gen_movsi_i (operands[0], operands[1]));
emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
DONE;")
(abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
(clobber (reg:SI T_REG))]
""
"")
(define_insn "cneg"
(define_insn_and_split "*abssi2"
[(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"))))]
(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],
const1_rtx));
DONE;
}")
(define_insn_and_split "*negabssi2"
[(set (match_operand:SI 0 "arith_reg_dest" "=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")])

View File

@ -1,3 +1,8 @@
2011-09-28 Oleg Endo <oleg.endo@t-online.de>
PR target/49486
* gcc.target/sh/pr49468-si.c: New.
2011-09-28 Tom de Vries <tom@codesourcery.com>
PR testsuite/50485

View File

@ -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;
}