aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2016-09-25 06:59:37 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2016-09-25 06:59:37 +0000
commit50c6dd20ce5e777e96de24ea6a1a896cf8836931 (patch)
tree69658dc6948bcfd9cfb05d59758237eca0527549
parenteaaa68f33d943f9714e48d5f81d96e364bb77054 (diff)
downloadgcc-50c6dd20ce5e777e96de24ea6a1a896cf8836931.zip
gcc-50c6dd20ce5e777e96de24ea6a1a896cf8836931.tar.gz
gcc-50c6dd20ce5e777e96de24ea6a1a896cf8836931.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/sh/sh-protos.h2
-rw-r--r--gcc/config/sh/sh.c38
-rw-r--r--gcc/config/sh/sh.md18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-11.c9
6 files changed, 64 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ab5e5ad..ce6841b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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>
* config/rs6000/rs6000.c (expand_block_compare, do_load_for_compare):
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index f611dab..1bac403 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -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 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 i);
inline bool sh_is_movt_insn (const rtx_insn* i)
{
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index a9b5a14..bfa248d 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3208,6 +3208,10 @@ sh_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
/ mov_insn_size (mode, TARGET_SH2A));
return true;
}
+
+ if (sh_movt_set_dest (x) != NULL || sh_movrt_set_dest (x) != NULL)
+ return COSTS_N_INSNS (1);
+
return false;
/* 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)
rtx
sh_movt_set_dest (const rtx_insn* i)
{
- if (i == NULL)
- return NULL;
+ return i == NULL ? NULL : sh_movt_set_dest (PATTERN (i));
+}
- const_rtx p = PATTERN (i);
- return GET_CODE (p) == SET
- && arith_reg_dest (XEXP (p, 0), SImode)
- && t_reg_operand (XEXP (p, 1), VOIDmode) ? XEXP (p, 0) : NULL;
+rtx
+sh_movt_set_dest (const_rtx pat)
+{
+ 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
@@ -11718,18 +11724,20 @@ sh_movt_set_dest (const rtx_insn* i)
rtx
sh_movrt_set_dest (const rtx_insn* i)
{
- if (i == NULL)
- return NULL;
-
- const_rtx p = PATTERN (i);
+ return i == NULL ? NULL : sh_movrt_set_dest (PATTERN (i));
+}
+rtx
+sh_movrt_set_dest (const_rtx pat)
+{
/* The negc movrt replacement is inside a parallel. */
- if (GET_CODE (p) == PARALLEL)
- p = XVECEXP (p, 0, 0);
+ if (GET_CODE (pat) == PARALLEL)
+ 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
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 25e03ef..dcb31eb 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -8524,6 +8524,24 @@
[(set_attr "type" "arith") ;; poor approximation
(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"
[(set (match_operand:SI 0 "register_operand")
(match_operator:SI 1 "ordered_comparison_operator"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ae952cb..4fc22c4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
* gfortran.dg/coarray_lib_comm_1.f90: Really fix test
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-11.c b/gcc/testsuite/gcc.target/sh/pr51244-11.c
index fea7f6c..f058269 100644
--- a/gcc/testsuite/gcc.target/sh/pr51244-11.c
+++ b/gcc/testsuite/gcc.target/sh/pr51244-11.c
@@ -1,8 +1,11 @@
/* 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-options "-O1 -mzdcbranch" } */
-/* { dg-final { scan-assembler-not "subc|and" } } */
+/* { dg-options "-O1 -mzdcbranch" } */
+/* { 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*
test_00 (int* s)