re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)

PR target/51244
	* config/sh/sh.md (movnegt): Expand into respective insns immediately.
	Use movrt_negc instead of negc pattern for non-SH2A.
	(*movnegt): Remove.
	(*movrt_negc, *negnegt, *movtt, *movt_qi): New insns and splits.

	PR target/51244
	* gcc.target/sh/pr51244-1.c: Fix thinkos.

From-SVN: r185192
This commit is contained in:
Oleg Endo 2012-03-11 13:18:08 +00:00
parent 9237e39d54
commit 07c0b5604a
4 changed files with 93 additions and 29 deletions

View File

@ -1,3 +1,11 @@
2012-03-11 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
* config/sh/sh.md (movnegt): Expand into respective insns immediately.
Use movrt_negc instead of negc pattern for non-SH2A.
(*movnegt): Remove.
(*movrt_negc, *negnegt, *movtt, *movt_qi): New insns and splits.
2012-03-10 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg)

View File

@ -9679,37 +9679,88 @@ mov.l\\t1f,r0\\n\\
;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
;; becomes a one instruction operation. Moreover, care must be taken that
;; the insn can still be combined with inverted compare and branch code
;; around it.
;; The expander will reserve the constant -1, the insn makes the whole thing
;; combinable, the splitter finally emits the insn if it was not combined
;; away.
;; Notice that when using the negc variant the T bit also gets inverted.
;; around it. On the other hand, if a function returns the complement of
;; a previous comparison result in the T bit, the xor #1,r0 approach might
;; lead to better code.
(define_expand "movnegt"
[(set (match_dup 1) (const_int -1))
(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
(xor:SI (reg:SI T_REG) (const_int 1)))
(use (match_dup 1))])]
[(set (match_operand:SI 0 "arith_reg_dest" "")
(xor:SI (reg:SI T_REG) (const_int 1)))]
""
{
operands[1] = gen_reg_rtx (SImode);
})
(define_insn_and_split "*movnegt"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(xor:SI (reg:SI T_REG) (const_int 1)))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
"TARGET_SH1"
"#"
"&& 1"
[(const_int 0)]
{
if (TARGET_SH2A)
emit_insn (gen_movrt (operands[0]));
else
emit_insn (gen_negc (operands[0], operands[1]));
{
rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
emit_insn (gen_movrt_negc (operands[0], val));
}
DONE;
}
})
(define_insn "movrt_negc"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(xor:SI (reg:SI T_REG) (const_int 1)))
(set (reg:SI T_REG) (const_int 1))
(use (match_operand:SI 1 "arith_reg_operand" "r"))]
"TARGET_SH1"
"negc %1,%0"
[(set_attr "type" "arith")])
;; The *negnegt patterns help the combine pass to figure out how to fold
;; an explicit double T bit negation.
(define_insn_and_split "*negnegt"
[(set (reg:SI T_REG)
(eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 3)
(const_int 0)))]
"! TARGET_LITTLE_ENDIAN"
"#"
""
[(const_int 0)])
(define_insn_and_split "*negnegt"
[(set (reg:SI T_REG)
(eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 0)
(const_int 0)))]
"TARGET_LITTLE_ENDIAN"
"#"
""
[(const_int 0)])
;; The *movtt patterns improve code at -O1.
(define_insn_and_split "*movtt"
[(set (reg:SI T_REG)
(eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 3))
(const_int 1)))]
"! TARGET_LITTLE_ENDIAN"
"#"
""
[(const_int 0)])
(define_insn_and_split "*movtt"
[(set (reg:SI T_REG)
(eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 0))
(const_int 1)))]
"TARGET_LITTLE_ENDIAN"
"#"
""
[(const_int 0)])
;; The *movt_qi patterns help the combine pass convert a movrt_negc pattern
;; into a movt Rn, xor #1 Rn pattern. This can happen when e.g. a function
;; returns the inverted T bit value.
(define_insn "*movt_qi"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(zero_extend:SI (subreg:QI (reg:SI T_REG) 3)))]
"! TARGET_LITTLE_ENDIAN"
"movt %0"
[(set_attr "type" "arith")])
(define_insn "*movt_qi"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(zero_extend:SI (subreg:QI (reg:SI T_REG) 0)))]
"TARGET_LITTLE_ENDIAN"
"movt %0"
[(set_attr "type" "arith")])
(define_expand "cstoresf4"

View File

@ -1,3 +1,8 @@
2012-03-11 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
* gcc.target/sh/pr51244-1.c: Fix thinkos.
2012-03-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/52450

View File

@ -13,20 +13,20 @@ testfunc_00 (int a, int b, int c, int d)
}
int
testfunc_01 (int a, char* p, int b, int c)
testfunc_01 (int a, int b, int c, int d)
{
return (a == b && a == c) ? b : c;
return (a == b || a == d) ? b : c;
}
int
testfunc_02 (int a, char* p, int b, int c)
testfunc_02 (int a, int b, int c, int d)
{
return (a == b && a == c) ? b : c;
return (a == b && a == d) ? b : c;
}
int
testfunc_03 (int a, char* p, int b, int c)
testfunc_03 (int a, int b, int c, int d)
{
return (a != b && a != c) ? b : c;
return (a != b && a != d) ? b : c;
}