Commit 50c6dd20 by Oleg Endo

This fixes a fallout that actually goes back to 5.0 but went unnoticed.

The costs for movt and movrt type of insns were not correctly reported
and ifcvt thus made some bad choices for SH.  A new cset_zero pattern
variant is also required to fix the matching for some recent changes
in the middle end.
 
gcc/
	PR target/51244
	* config/sh/sh.c (sh_movt_set_dest, sh_movrt_set_dest): Add overloads.
	(sh_rtx_costs): Handle SET of movt and movrt patterns.
	* cnofig/sh/sh-protos.h (sh_movt_set_dest, sh_movrt_set_dest): Forward
	declare new overloads.
	* config/sh/sh.md (*cset_zero): Add variant that takes a treg_set_expr
	operand.

gcc/testsuite/
	PR target/51244
	* gcc.target/sh/pr51244-11.c: Add more detailed expected insn matching.

From-SVN: r240471
parent eaaa68f3
2016-09-25 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
* config/sh/sh.c (sh_movt_set_dest, sh_movrt_set_dest): Add overloads.
(sh_rtx_costs): Handle SET of movt and movrt patterns.
* cnofig/sh/sh-protos.h (sh_movt_set_dest, sh_movrt_set_dest): Forward
declare new overloads.
* config/sh/sh.md (*cset_zero): Add variant that takes a treg_set_expr
operand.
2016-09-24 Aaron Sawdey <acsawdey@linux.vnet.ibm.com> 2016-09-24 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (expand_block_compare, do_load_for_compare): * config/rs6000/rs6000.c (expand_block_compare, do_load_for_compare):
......
...@@ -235,7 +235,9 @@ extern void sh_split_tst_subregs (rtx_insn* curr_insn, ...@@ -235,7 +235,9 @@ extern void sh_split_tst_subregs (rtx_insn* curr_insn,
extern bool sh_is_nott_insn (const rtx_insn* i); extern bool sh_is_nott_insn (const rtx_insn* i);
extern rtx sh_movt_set_dest (const rtx_insn* i); extern rtx sh_movt_set_dest (const rtx_insn* i);
extern rtx sh_movt_set_dest (const_rtx i);
extern rtx sh_movrt_set_dest (const rtx_insn* i); extern rtx sh_movrt_set_dest (const rtx_insn* i);
extern rtx sh_movrt_set_dest (const_rtx i);
inline bool sh_is_movt_insn (const rtx_insn* i) inline bool sh_is_movt_insn (const rtx_insn* i)
{ {
......
...@@ -3208,6 +3208,10 @@ sh_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code, ...@@ -3208,6 +3208,10 @@ sh_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
/ mov_insn_size (mode, TARGET_SH2A)); / mov_insn_size (mode, TARGET_SH2A));
return true; return true;
} }
if (sh_movt_set_dest (x) != NULL || sh_movrt_set_dest (x) != NULL)
return COSTS_N_INSNS (1);
return false; return false;
/* The cost of a mem access is mainly the cost of the address mode. */ /* The cost of a mem access is mainly the cost of the address mode. */
...@@ -11703,13 +11707,15 @@ sh_is_nott_insn (const rtx_insn* i) ...@@ -11703,13 +11707,15 @@ sh_is_nott_insn (const rtx_insn* i)
rtx rtx
sh_movt_set_dest (const rtx_insn* i) sh_movt_set_dest (const rtx_insn* i)
{ {
if (i == NULL) return i == NULL ? NULL : sh_movt_set_dest (PATTERN (i));
return NULL; }
const_rtx p = PATTERN (i); rtx
return GET_CODE (p) == SET sh_movt_set_dest (const_rtx pat)
&& arith_reg_dest (XEXP (p, 0), SImode) {
&& t_reg_operand (XEXP (p, 1), VOIDmode) ? XEXP (p, 0) : NULL; return GET_CODE (pat) == SET
&& arith_reg_dest (XEXP (pat, 0), SImode)
&& t_reg_operand (XEXP (pat, 1), VOIDmode) ? XEXP (pat, 0) : NULL;
} }
/* Given an insn, check whether it's a 'movrt' kind of insn, i.e. an insn /* Given an insn, check whether it's a 'movrt' kind of insn, i.e. an insn
...@@ -11718,18 +11724,20 @@ sh_movt_set_dest (const rtx_insn* i) ...@@ -11718,18 +11724,20 @@ sh_movt_set_dest (const rtx_insn* i)
rtx rtx
sh_movrt_set_dest (const rtx_insn* i) sh_movrt_set_dest (const rtx_insn* i)
{ {
if (i == NULL) return i == NULL ? NULL : sh_movrt_set_dest (PATTERN (i));
return NULL; }
const_rtx p = PATTERN (i);
rtx
sh_movrt_set_dest (const_rtx pat)
{
/* The negc movrt replacement is inside a parallel. */ /* The negc movrt replacement is inside a parallel. */
if (GET_CODE (p) == PARALLEL) if (GET_CODE (pat) == PARALLEL)
p = XVECEXP (p, 0, 0); pat = XVECEXP (pat, 0, 0);
return GET_CODE (pat) == SET
&& arith_reg_dest (XEXP (pat, 0), SImode)
&& negt_reg_operand (XEXP (pat, 1), VOIDmode) ? XEXP (pat, 0) : NULL;
return GET_CODE (p) == SET
&& arith_reg_dest (XEXP (p, 0), SImode)
&& negt_reg_operand (XEXP (p, 1), VOIDmode) ? XEXP (p, 0) : NULL;
} }
/* Given an insn and a reg number, tell whether the reg dies or is unused /* Given an insn and a reg number, tell whether the reg dies or is unused
......
...@@ -8524,6 +8524,24 @@ ...@@ -8524,6 +8524,24 @@
[(set_attr "type" "arith") ;; poor approximation [(set_attr "type" "arith") ;; poor approximation
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn_and_split "*cset_zero"
[(set (match_operand:SI 0 "arith_reg_dest")
(if_then_else:SI (match_operand 1 "treg_set_expr_not_const01")
(match_dup 0) (const_int 0)))
(clobber (reg:SI T_REG))]
"TARGET_SH1 && TARGET_ZDCBRANCH && can_create_pseudo_p ()"
"#"
"&& 1"
[(set (match_dup 0)
(if_then_else:SI (match_dup 1) (match_dup 0) (const_int 0)))]
{
sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
if (ti.remove_trailing_nott ())
operands[1] = gen_rtx_EQ (SImode, get_t_reg_rtx (), const0_rtx);
else
operands[1] = gen_rtx_EQ (SImode, get_t_reg_rtx (), const1_rtx);
})
(define_expand "cstoresf4" (define_expand "cstoresf4"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(match_operator:SI 1 "ordered_comparison_operator" (match_operator:SI 1 "ordered_comparison_operator"
......
2016-09-25 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
* gcc.target/sh/pr51244-11.c: Add more detailed expected insn matching.
2016-09-24 Dominique d'Humieres <dominiq@lps.ens.fr> 2016-09-24 Dominique d'Humieres <dominiq@lps.ens.fr>
* gfortran.dg/coarray_lib_comm_1.f90: Really fix test * gfortran.dg/coarray_lib_comm_1.f90: Really fix test
......
/* Check that zero-displacement branches are used instead of branch-free /* Check that zero-displacement branches are used instead of branch-free
execution patterns. */ execution patterns.
This is usually handled by the *cset_zero patterns. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O1 -mzdcbranch" } */ /* { dg-options "-O1 -mzdcbranch" } */
/* { dg-final { scan-assembler-not "subc|and" } } */ /* { dg-final { scan-assembler-not "subc|and|bra" } } */
/* { dg-final { scan-assembler-times "bf\t0f" 1 } } */
/* { dg-final { scan-assembler-times "bt\t0f" 1 } } */
int* int*
test_00 (int* s) test_00 (int* s)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment