aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2015-01-24 13:04:53 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2015-01-24 13:04:53 +0000
commit841dbf801d85c65f02c04de31e7cf965a020c518 (patch)
treedb69dc3cf457df982a926d511d89a52be95ee9fc /gcc/testsuite
parent19bd4ebce2c48709989f7b56d1be5360e86c33af (diff)
downloadgcc-841dbf801d85c65f02c04de31e7cf965a020c518.zip
gcc-841dbf801d85c65f02c04de31e7cf965a020c518.tar.gz
gcc-841dbf801d85c65f02c04de31e7cf965a020c518.tar.bz2
re PR target/49263 (SH Target: underutilized "TST #imm, R0" instruction)
gcc/ PR target/49263 PR target/53987 PR target/64345 PR target/59533 PR target/52933 PR target/54236 PR target/51244 * config/sh/sh-protos.h (sh_extending_set_of_reg::can_use_as_unextended_reg, sh_extending_set_of_reg::use_as_unextended_reg, sh_is_nott_insn, sh_movt_set_dest, sh_movrt_set_dest, sh_is_movt_insn, sh_is_movrt_insn, sh_insn_operands_modified_between_p, sh_reg_dead_or_unused_after_insn, sh_in_recog_treg_set_expr, sh_recog_treg_set_expr, sh_split_treg_set_expr): New functions. (sh_treg_insns): New class. * config/sh/sh.c (TARGET_LEGITIMATE_COMBINED_INSN): Define target hook. (scope_counter): New class. (sh_legitimate_combined_insn, sh_is_nott_insn, sh_movt_set_dest, sh_movrt_set_dest, sh_reg_dead_or_unused_after_insn, sh_extending_set_of_reg::can_use_as_unextended_reg, sh_extending_set_of_reg::use_as_unextended_reg, sh_recog_treg_set_expr, sh_in_recog_treg_set_expr, sh_try_split_insn_simple, sh_split_treg_set_expr): New functions. (addsubcosts): Handle treg_set_expr. (sh_rtx_costs): Handle IF_THEN_ELSE and ZERO_EXTRACT. (sh_rtx_costs): Use arith_reg_operand in SIGN_EXTEND and ZERO_EXTEND. (sh_rtx_costs): Handle additional bit test patterns in EQ and AND cases. (sh_insn_operands_modified_between_p): Make non-static. * config/sh/predicates.md (zero_extend_movu_operand): Allow simple_mem_operand in addition to displacement_mem_operand. (zero_extend_operand): Don't allow zero_extend_movu_operand. (treg_set_expr, treg_set_expr_not_const01, arith_reg_or_treg_set_expr): New predicates. * config/sh/sh.md (tstsi_t): Use arith_reg_operand and arith_or_int_operand instead of logical_operand. Convert to insn_and_split. Try to optimize constant operand in splitter. (tsthi_t, tstqi_t): Fold into *tst<mode>_t. Convert to insn_and_split. (*tstqi_t_zero): Delete. (*tst<mode>_t_subregs): Add !sh_in_recog_treg_set_expr split condition. (tstsi_t_and_not): Delete. (tst<mode>_t_zero_extract_eq): Rename to *tst<mode>_t_zero_extract. Convert to insn_and_split. (unnamed split, tstsi_t_zero_extract_xor, tstsi_t_zero_extract_subreg_xor_little, tstsi_t_zero_extract_subreg_xor_big): Delete. (*tstsi_t_shift_mask): New insn_and_split. (cmpeqsi_t, cmpgesi_t): Add new split for const_int 0 operands and try to recombine with surrounding insns when splitting. (*negtstsi): Add !sh_in_recog_treg_set_expr condition. (cmp_div0s_0, cmp_div0s_1, *cmp_div0s_0, *cmp_div0s_1): Rewrite as ... (cmp_div0s, *cmp_div0s_1, *cmp_div0s_2, *cmp_div0s_3, *cmp_div0s_4, *cmp_div0s_5, *cmp_div0s_6): ... these new insn_and_split patterns. (*cbranch_div0s: Delete. (*addc): Convert to insn_and_split. Use treg_set_expr as 3rd operand. Try to recombine with surrounding insns when splitting. Add operand order variants. (*addc_t_r, *addc_r_t): Use treg_set_expr_not_const01. (*addc_r_r_1, *addc_r_lsb, *addc_r_r_lsb, *addc_r_lsb_r, *addc_r_msb, *addc_r_r_msb, *addc_2r_msb): Delete. (*addc_2r_lsb): Rename to *addc_2r_t. Use treg_set_expr. Add operand order variant. (*addc_negreg_t): New insn_and_split. (*subc): Convert to insn_and_split. Use treg_set_expr as 3rd operand. Try to recombine with surrounding insns when splitting. Add operand order variants. (*subc_negt_reg, *subc_negreg_t, *reg_lsb_t, *reg_msb_t): New insn_and_split patterns. (*rotcr): Use arith_reg_or_treg_set_expr. Try to recombine with surrounding insns when splitting. (unnamed rotcr split): Use arith_reg_or_treg_set_expr. (*rotcl): Likewise. Add zero_extract variant. (*ashrsi2_31): New insn_and_split. (*negc): Convert to insn_and_split. Use treg_set_expr. (*zero_extend<mode>si2_disp_mem): Update comment. (movrt_negc, *movrt_negc, nott): Add !sh_in_recog_treg_set_expr split condition. (*mov_t_msb_neg, mov_neg_si_t): Use treg_set_expr. Try to recombine with surrounding insns when splitting. (any_treg_expr_to_reg): New insn_and_split. (*neg_zero_extract_0, *neg_zero_extract_1, *neg_zero_extract_2, *neg_zero_extract_3, *neg_zero_extract_4, *neg_zero_extract_5, *neg_zero_extract_6, *zero_extract_0, *zero_extract_1, *zero_extract_2): New single bit zero extract patterns. (bld_reg, *bld_regqi): Fold into bld<mode>_reg. (*get_thread_pointersi, store_gbr, *mov<mode>_gbr_load, *mov<mode>_gbr_load, *mov<mode>_gbr_load, *mov<mode>_gbr_load, *movdi_gbr_load): Use arith_reg_dest instead of register_operand for set destination. (set_thread_pointersi, load_gbr): Use arith_reg_operand instead of register_operand for set source. gcc/testsuite/ PR target/49263 PR target/53987 PR target/64345 PR target/59533 PR target/52933 PR target/54236 PR target/51244 * gcc.target/sh/pr64345-1.c: New. * gcc.target/sh/pr64345-2.c: New. * gcc.target/sh/pr59533-1.c: New. * gcc.target/sh/pr49263.c: Adjust matching of expected insns. * gcc.target/sh/pr52933-2.c: Likewise. * gcc.target/sh/pr54089-1.c: Likewise. * gcc.target/sh/pr54236-1.c: Likewise. * gcc.target/sh/pr51244-20-sh2a.c: Likewise. * gcc.target/sh/pr49263-1.c: Remove xfails. * gcc.target/sh/pr49263-2.c: Likewise. * gcc.target/sh/pr49263-3.c: Likewise. * gcc.target/sh/pr53987-1.c: Likewise. * gcc.target/sh/pr52933-1.c: Adjust matching of expected insns. (test_24, test_25, test_26, test_27, test_28, test_29, test_30): New. * gcc.target/sh/pr51244-12.c: Adjust matching of expected insns. (test05, test06, test07, test08, test09, test10, test11, test12): New. * gcc.target/sh/pr54236-3.c: Adjust matching of expected insns. (test_002, test_003, test_004, test_005, test_006, test_007, test_008, test_009): New. * gcc.target/sh/pr51244-4.c: Adjust matching of expected insns. (test_02): New. From-SVN: r220081
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog31
-rw-r--r--gcc/testsuite/gcc.target/sh/pr49263-1.c6
-rw-r--r--gcc/testsuite/gcc.target/sh/pr49263-2.c11
-rw-r--r--gcc/testsuite/gcc.target/sh/pr49263-3.c18
-rw-r--r--gcc/testsuite/gcc.target/sh/pr49263.c2
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-12.c58
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c4
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-4.c24
-rw-r--r--gcc/testsuite/gcc.target/sh/pr52933-1.c49
-rw-r--r--gcc/testsuite/gcc.target/sh/pr52933-2.c7
-rw-r--r--gcc/testsuite/gcc.target/sh/pr53987-1.c2
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54089-1.c2
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54236-1.c11
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54236-3.c73
-rw-r--r--gcc/testsuite/gcc.target/sh/pr59533-1.c185
-rw-r--r--gcc/testsuite/gcc.target/sh/pr64345-1.c97
-rw-r--r--gcc/testsuite/gcc.target/sh/pr64345-2.c116
17 files changed, 658 insertions, 38 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c0bc347..8b3dfc4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,34 @@
+2015-01-24 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/49263
+ PR target/53987
+ PR target/64345
+ PR target/59533
+ PR target/52933
+ PR target/54236
+ PR target/51244
+ * gcc.target/sh/pr64345-1.c: New.
+ * gcc.target/sh/pr64345-2.c: New.
+ * gcc.target/sh/pr59533-1.c: New.
+ * gcc.target/sh/pr49263.c: Adjust matching of expected insns.
+ * gcc.target/sh/pr52933-2.c: Likewise.
+ * gcc.target/sh/pr54089-1.c: Likewise.
+ * gcc.target/sh/pr54236-1.c: Likewise.
+ * gcc.target/sh/pr51244-20-sh2a.c: Likewise.
+ * gcc.target/sh/pr49263-1.c: Remove xfails.
+ * gcc.target/sh/pr49263-2.c: Likewise.
+ * gcc.target/sh/pr49263-3.c: Likewise.
+ * gcc.target/sh/pr53987-1.c: Likewise.
+ * gcc.target/sh/pr52933-1.c: Adjust matching of expected insns.
+ (test_24, test_25, test_26, test_27, test_28, test_29, test_30): New.
+ * gcc.target/sh/pr51244-12.c: Adjust matching of expected insns.
+ (test05, test06, test07, test08, test09, test10, test11, test12): New.
+ * gcc.target/sh/pr54236-3.c: Adjust matching of expected insns.
+ (test_002, test_003, test_004, test_005, test_006, test_007, test_008,
+ test_009): New.
+ * gcc.target/sh/pr51244-4.c: Adjust matching of expected insns.
+ (test_02): New.
+
2015-01-24 Tom de Vries <tom@codesourcery.com>
* gcc.target/i386/funcspec-5.c: Replace avx512 with avx512f.
diff --git a/gcc/testsuite/gcc.target/sh/pr49263-1.c b/gcc/testsuite/gcc.target/sh/pr49263-1.c
index fd3cb4b..92a0cb0 100644
--- a/gcc/testsuite/gcc.target/sh/pr49263-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr49263-1.c
@@ -3,9 +3,9 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "and" } } */
-/* { dg-final { scan-assembler-not "bclr" { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "extu" 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "exts" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "bclr" } } */
+/* { dg-final { scan-assembler-times "extu" 1 } } */
+/* { dg-final { scan-assembler-times "exts" 1 } } */
#define make_func(__valtype__, __valget__, __tstval__, __suff__)\
int test_imm_##__tstval__##__suff__ (__valtype__ val) \
diff --git a/gcc/testsuite/gcc.target/sh/pr49263-2.c b/gcc/testsuite/gcc.target/sh/pr49263-2.c
index 3385161..a6318fc 100644
--- a/gcc/testsuite/gcc.target/sh/pr49263-2.c
+++ b/gcc/testsuite/gcc.target/sh/pr49263-2.c
@@ -3,13 +3,12 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "and" } } */
-/* { dg-final { scan-assembler-not "exts" { xfail *-*-* } } } */
-
+/* { dg-final { scan-assembler-not "exts" } } */
/* { dg-final { scan-assembler-times "tst\t#127,r0" 2 } } */
-/* { dg-final { scan-assembler-times "tst\t#255,r0" 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "65407" 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "-129" 2 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "extu" 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "tst\t#255,r0" 1 } } */
+/* { dg-final { scan-assembler-times "65407" 1 } } */
+/* { dg-final { scan-assembler-times "-129" 2 } } */
+/* { dg-final { scan-assembler-times "extu" 1 } } */
int
test_00 (unsigned char x)
diff --git a/gcc/testsuite/gcc.target/sh/pr49263-3.c b/gcc/testsuite/gcc.target/sh/pr49263-3.c
index 1edfe87..0fbed94 100644
--- a/gcc/testsuite/gcc.target/sh/pr49263-3.c
+++ b/gcc/testsuite/gcc.target/sh/pr49263-3.c
@@ -2,18 +2,18 @@
is shifted by a constant amount. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-not "and|shl|sha|exts" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "and|shl|sha|exts" } } */
-/* { dg-final { scan-assembler-times "tst\t#7,r0" 3 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "tst\t#12,r0" 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "tst\t#24,r0" 6 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "tst\t#13,r0" 3 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "tst\t#242,r0" 3 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "tst\t#7,r0" 3 } } */
+/* { dg-final { scan-assembler-times "tst\t#12,r0" 1 } } */
+/* { dg-final { scan-assembler-times "tst\t#24,r0" 6 } } */
+/* { dg-final { scan-assembler-times "tst\t#13,r0" 3 } } */
+/* { dg-final { scan-assembler-times "tst\t#242,r0" 3 } } */
/* { dg-final { scan-assembler-times "tst\t#252,r0" 1 } } */
-/* { dg-final { scan-assembler-times "tst\t#64,r0" 6 { target { ! sh2a } xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "tst\t#64,r0" 4 { target { sh2a } xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times "bld\t#6" 2 { target { sh2a } xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times "tst\t#64,r0" 6 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#64,r0" 4 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#6" 2 { target { sh2a } } } } */
int
test_00 (unsigned char* x, int y, int z)
diff --git a/gcc/testsuite/gcc.target/sh/pr49263.c b/gcc/testsuite/gcc.target/sh/pr49263.c
index 783d865..2393e53 100644
--- a/gcc/testsuite/gcc.target/sh/pr49263.c
+++ b/gcc/testsuite/gcc.target/sh/pr49263.c
@@ -5,6 +5,8 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-not "and" } } */
+/* { dg-final { scan-assembler-not "extu" } } */
+/* { dg-final { scan-assembler-not "exts" } } */
#define make_func(__valtype__, __valget__, __tstval__, __suff__)\
int test_imm_##__tstval__##__suff__ (__valtype__ val) \
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-12.c b/gcc/testsuite/gcc.target/sh/pr51244-12.c
index da94101..ae856f8 100644
--- a/gcc/testsuite/gcc.target/sh/pr51244-12.c
+++ b/gcc/testsuite/gcc.target/sh/pr51244-12.c
@@ -4,8 +4,9 @@
/* { dg-do compile } */
/* { dg-options "-O1" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
-/* { dg-final { scan-assembler-times "negc" 10 } } */
-/* { dg-final { scan-assembler-not "movrt|#-1|add|sub" } } */
+/* { dg-final { scan-assembler-times "negc" 15 } } */
+/* { dg-final { scan-assembler-times "addc" 3 } } */
+/* { dg-final { scan-assembler-not "movrt|#-1|add\t|sub\t|movt" } } */
int
test00 (int a, int b, int* x)
@@ -66,3 +67,56 @@ test04_inv (int a)
{
return ((a & 0x55) != 0) ? 0x80000000 : 0x7FFFFFFF;
}
+
+int
+test05 (int a, int b)
+{
+ /* 1x addc */
+ return a != b ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test06 (char a)
+{
+ return ((a & 0x03) == 0) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test07 (char a)
+{
+ return ((a & 0x80) == 0) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test08 (char a)
+{
+ return ((a & 1) == 0) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test09 (int a)
+{
+ /* 1x cmp/pz, 1x addc */
+ return a < 0 ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test10 (int a)
+{
+ /* 1x cmp/pz, 1x negc */
+ return a >= 0 ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test11 (int a)
+{
+ /* 1x cmp/pl, 1x negc */
+ return a > 0 ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test12 (int a)
+{
+ /* 1x cmp/pl, 1x addc */
+ return a <= 0 ? 0x7FFFFFFF : 0x80000000;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c b/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c
index 3208f93..82ed9e0 100644
--- a/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c
+++ b/gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c
@@ -4,8 +4,8 @@
/* { dg-options "-O2" } */
/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */
/* { dg-final { scan-assembler-times "tst" 6 } } */
-/* { dg-final { scan-assembler-times "movt" 1 } } */
-/* { dg-final { scan-assembler-times "nott" 1 } } */
+/* { dg-final { scan-assembler-not "movt" } } */
+/* { dg-final { scan-assembler-times "nott" 2 } } */
/* { dg-final { scan-assembler-times "cmp/eq" 2 } } */
/* { dg-final { scan-assembler-times "cmp/hi" 4 } } */
/* { dg-final { scan-assembler-times "cmp/gt" 3 } } */
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-4.c b/gcc/testsuite/gcc.target/sh/pr51244-4.c
index a11429b..ac967bf 100644
--- a/gcc/testsuite/gcc.target/sh/pr51244-4.c
+++ b/gcc/testsuite/gcc.target/sh/pr51244-4.c
@@ -1,19 +1,31 @@
/* Check that storing the (negated) T bit as all ones or zeros in a reg
- uses the subc instruction. On SH2A a sequence with the movrt instruction
- is also OK instead of subc. */
+ uses the subc instruction. */
/* { dg-do compile } */
/* { dg-options "-O1 -mbranch-cost=2" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
-/* { dg-final { scan-assembler-not "movt|tst|negc" } } */
-/* { dg-final { scan-assembler "subc|movrt|neg|not" } } */
+/* { dg-final { scan-assembler-not "movt|tst|negc|movrt" } } */
+/* { dg-final { scan-assembler-times "subc" 3 } } */
+/* { dg-final { scan-assembler-times "not\t" 1 } } */
+/* { dg-final { scan-assembler-times "shll" 1 } } */
+/* { dg-final { scan-assembler-not "cmp/gt" } } */
-int test_00 (int x, int y)
+int
+test_00 (int x, int y)
{
+ /* 1x subc, 1x not */
return x != y ? -1 : 0;
}
-int test_01 (int x, int y)
+int
+test_01 (int x, int y)
{
+ /* 1x subc */
return x == y ? -1 : 0;
}
+int
+test_02 (int x)
+{
+ /* 1x shll, 1x subc */
+ return 0 <= x ? 0 : -1;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr52933-1.c b/gcc/testsuite/gcc.target/sh/pr52933-1.c
index b65707e..0c69027 100644
--- a/gcc/testsuite/gcc.target/sh/pr52933-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr52933-1.c
@@ -5,8 +5,13 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
-/* { dg-final { scan-assembler-times "div0s" 25 } } */
+/* { dg-final { scan-assembler-times "div0s" 32 } } */
/* { dg-final { scan-assembler-not "tst" } } */
+/* { dg-final { scan-assembler-not "not\t" } } */
+/* { dg-final { scan-assembler-not "nott" } } */
+
+/* { dg-final { scan-assembler-times "negc" 9 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "movrt" 9 { target { sh2a } } } } */
typedef unsigned char bool;
@@ -166,3 +171,45 @@ test_23 (int a, int b, int c, int d)
/* Should emit 2x div0s. */
return ((a < 0) == (b < 0)) | ((c < 0) == (d < 0));
}
+
+bool
+test_24 (int a, int b)
+{
+ return a >= 0 != b >= 0;
+}
+
+bool
+test_25 (int a, int b)
+{
+ return !(a < 0 != b < 0);
+}
+
+int
+test_26 (int a, int b, int c, int d)
+{
+ return a >= 0 != b >= 0 ? c : d;
+}
+
+int
+test_27 (int a, int b)
+{
+ return a >= 0 == b >= 0;
+}
+
+int
+test_28 (int a, int b, int c, int d)
+{
+ return a >= 0 == b >= 0 ? c : d;
+}
+
+int
+test_29 (int a, int b)
+{
+ return ((a >> 31) ^ (b >= 0)) & 1;
+}
+
+int
+test_30 (int a, int b)
+{
+ return ((a >> 31) ^ (b >> 31)) & 1;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr52933-2.c b/gcc/testsuite/gcc.target/sh/pr52933-2.c
index 865cb37..67e2753 100644
--- a/gcc/testsuite/gcc.target/sh/pr52933-2.c
+++ b/gcc/testsuite/gcc.target/sh/pr52933-2.c
@@ -6,7 +6,12 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mpretend-cmove" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
-/* { dg-final { scan-assembler-times "div0s" 25 } } */
+/* { dg-final { scan-assembler-times "div0s" 32 } } */
/* { dg-final { scan-assembler-not "tst" } } */
+/* { dg-final { scan-assembler-not "not\t" } } */
+/* { dg-final { scan-assembler-not "nott" } } */
+
+/* { dg-final { scan-assembler-times "negc" 9 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "movrt" 9 { target { sh2a } } } } */
#include "pr52933-1.c"
diff --git a/gcc/testsuite/gcc.target/sh/pr53987-1.c b/gcc/testsuite/gcc.target/sh/pr53987-1.c
index a0394ac..003dd4f 100644
--- a/gcc/testsuite/gcc.target/sh/pr53987-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr53987-1.c
@@ -6,7 +6,7 @@
/* { dg-final { scan-assembler-not "exts.b" } } */
/* { dg-final { scan-assembler-not "exts.w" } } */
/* { dg-final { scan-assembler-not "movu" } } */
-/* { dg-final { scan-assembler-not "tst\t#255" { xfail *-*-*} } } */
+/* { dg-final { scan-assembler-not "tst\t#255" } } */
int
test_00 (unsigned char* x, char* xx, int y, int z)
diff --git a/gcc/testsuite/gcc.target/sh/pr54089-1.c b/gcc/testsuite/gcc.target/sh/pr54089-1.c
index 4dbd1b8..418ba69 100644
--- a/gcc/testsuite/gcc.target/sh/pr54089-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr54089-1.c
@@ -4,6 +4,8 @@
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
/* { dg-final { scan-assembler-times "rotcr" 24 } } */
/* { dg-final { scan-assembler-times "shll\t" 1 } } */
+/* { dg-final { scan-assembler-not "and\t#1" } } */
+/* { dg-final { scan-assembler-not "cmp/pl" } } */
typedef char bool;
diff --git a/gcc/testsuite/gcc.target/sh/pr54236-1.c b/gcc/testsuite/gcc.target/sh/pr54236-1.c
index f7568a9..b5c3546 100644
--- a/gcc/testsuite/gcc.target/sh/pr54236-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr54236-1.c
@@ -7,8 +7,12 @@
/* { dg-final { scan-assembler-times "addc" 4 } } */
/* { dg-final { scan-assembler-times "subc" 3 } } */
/* { dg-final { scan-assembler-times "sett" 5 } } */
-/* { dg-final { scan-assembler-times "negc" 1 } } */
-/* { dg-final { scan-assembler-not "movt" } } */
+
+/* { dg-final { scan-assembler-times "negc" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-not "movt" { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "bld" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "movt" 1 { target { sh2a } } } } */
int
test_00 (int a, int b, int c, int d)
@@ -64,7 +68,8 @@ test_07 (int *vec)
{
/* Must not see a 'sett' or 'addc' here.
This is a case where combine tries to produce
- 'a + (0 - b) + 1' out of 'a - b + 1'. */
+ 'a + (0 - b) + 1' out of 'a - b + 1'.
+ On non-SH2A there is a 'tst + negc', on SH2A a 'bld + movt'. */
int z = vec[0];
int vi = vec[1];
int zi = vec[2];
diff --git a/gcc/testsuite/gcc.target/sh/pr54236-3.c b/gcc/testsuite/gcc.target/sh/pr54236-3.c
index fc0d111..933ece3 100644
--- a/gcc/testsuite/gcc.target/sh/pr54236-3.c
+++ b/gcc/testsuite/gcc.target/sh/pr54236-3.c
@@ -2,11 +2,13 @@
If everything works as expected we won't see any movt instructions in
these cases. */
/* { dg-do compile } */
-/* { dg-options "-O1" } */
+/* { dg-options "-O2" } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
-/* { dg-final { scan-assembler-times "addc" 1 } } */
-/* { dg-final { scan-assembler-times "subc" 1 } } */
-/* { dg-final { scan-assembler-not "movt" } } */
+/* { dg-final { scan-assembler-times "addc" 4 } } */
+/* { dg-final { scan-assembler-times "subc" 5 } } */
+/* { dg-final { scan-assembler-times "movt" 1 } } */
+/* { dg-final { scan-assembler-times "sub\t" 1 } } */
+/* { dg-final { scan-assembler-times "neg\t" 2 } } */
int
test_000 (int* x, unsigned int c)
@@ -29,3 +31,66 @@ test_001 (int* x, unsigned int c)
s -= ! (x[i] & 0x3000);
return s;
}
+
+int
+test_002 (int a, int b, int c)
+{
+ /* 1x tst, 1x subc */
+ return ((a & b) != 0) - c;
+}
+
+int
+test_003 (int a, int b, int c)
+{
+ /* 1x tst, 1x movt, 1x sub */
+ return ((a & b) == 0) - c;
+}
+
+int
+test_004 (int a, int b, int c)
+{
+ /* 1x tst, 1x addc */
+ return c - ((a & b) != 0);
+}
+
+int
+test_005 (int a, int b, int c)
+{
+ /* 1x shll, 1x subc */
+ int x = a < 0;
+ return c - (b + x);
+}
+
+int
+test_006 (int a, int b, int c)
+{
+ /* 1x neg, 1x cmp/pl, 1x addc */
+ int x = a > 0;
+ int y = b + x;
+ return y - c;
+}
+
+int
+test_007 (int a, int b, int c)
+{
+ /* 1x add #-1, 1x cmp/eq, 1x addc */
+ int x = a != 1;
+ int y = b - x;
+ return c + y;
+}
+
+int
+test_008 (int a, int b, int c)
+{
+ /* 1x neg, 1x cmp/gt, 1x subc */
+ int x = a > 1;
+ int y = b - x;
+ return c + y;
+}
+
+int
+test_009 (int a, int b, int c, int d)
+{
+ /* 1x div0s, 1x subc */
+ return c - d - (a < 0 != b < 0);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr59533-1.c b/gcc/testsuite/gcc.target/sh/pr59533-1.c
new file mode 100644
index 0000000..f45e4b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr59533-1.c
@@ -0,0 +1,185 @@
+/* Check that the cmp/pz instruction is generated as expected. */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+
+/* { dg-final { scan-assembler-times "shll" 1 } } */
+/* { dg-final { scan-assembler-times "movt" 5 } } */
+/* { dg-final { scan-assembler-times "rotcl" 1 } } */
+/* { dg-final { scan-assembler-times "and" 3 } } */
+/* { dg-final { scan-assembler-times "extu.b" 5 } } */
+
+/* { dg-final { scan-assembler-times "cmp/pz" 22 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "addc" 3 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "subc" 12 { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "cmp/pz" 20 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "addc" 5 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "subc" 10 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld" 2 { target { sh2a } } } } */
+
+int
+test_00 (unsigned char* a)
+{
+ /* 1x cmp/pz, 1x movt */
+ return a[0] < 128;
+}
+
+int
+test_01 (unsigned char* a)
+{
+ /* 1x cmp/pz, 1x addc */
+ return a[0] + (a[0] < 128);
+}
+
+int
+test_02 (unsigned char* a)
+{
+ /* 1x cmp/pz, 1x addc */
+ return a[0] + ((a[0] & 0x80) == 0);
+}
+
+int
+test_03 (unsigned char* a)
+{
+ /* 1x cmp/pz, 1x subc
+ SH2A: 1x bld, 1x addc */
+ return a[0] + (a[0] > 127);
+}
+
+int
+test_04 (unsigned char* a)
+{
+ /* 1x cmp/pz, 1x subc
+ SH2A: 1x bld, 1x addc */
+ return a[0] + ((a[0] & 0x80) != 0);
+}
+
+int
+test_05 (unsigned char* a, int b, int c)
+{
+ /* 1x cmp/pz */
+ if (a[0] < 128)
+ return c;
+ else
+ return b + 50;
+}
+
+unsigned int
+test_06 (unsigned int a)
+{
+ /* 1x cmp/pz, 1x movt */
+ return ~a >> 31;
+}
+
+int
+test_07 (unsigned short* a)
+{
+ /* 1x cmp/pz */
+ return a[0] < 32768;
+}
+
+int
+test_08 (unsigned short* a)
+{
+ /* 1x cmp/pz, 1x addc */
+ return a[0] + (a[0] < 32768);
+}
+
+unsigned int
+test_09 (unsigned int a)
+{
+ /* 1x cmp/pz, 1x movt */
+ return (a >> 31) ^ 1;
+}
+
+unsigned int
+test_10 (unsigned int a, unsigned int b)
+{
+ /* 1x cmp/pz, 1x rotcl */
+ return (a << 1) | ((a >> 31) ^ 1);
+}
+
+unsigned int
+test_11 (int x)
+{
+ /* 1x cmp/pz, 1x subc */
+ return ~(x >> 31);
+}
+
+unsigned int
+test_12 (int x)
+{
+ /* 1x cmp/pz, 1x subc */
+ return 0xFFFFFFFF - (x >> 31);
+}
+
+unsigned int
+test_13 (int x)
+{
+ /* 1x cmp/pz, 1x subc, 1x add */
+ return ~(x >> 31) << 1;
+}
+
+unsigned int
+test_14 (int x)
+{
+ /* 1x cmp/pz, 1x subc */
+ return ~(x >> 31) >> 1;
+}
+
+unsigned int
+test_15 (int x)
+{
+ /* 1x cmp/pz, 1x subc */
+ return ~(x >> 31) >> 31;
+}
+
+unsigned int
+test_16 (int x)
+{
+ /* 1x cmp/pz, 1x subc, 1x and */
+ return ~(x >> 31) & 0xFF000000;
+}
+
+unsigned int
+test_17 (int x)
+{
+ /* 1x cmp/pz, 1x subc, 1x and */
+ return ~(x >> 31) & 0x00FF0000;
+}
+
+unsigned int
+test_18 (int x)
+{
+ /* 1x cmp/pz, 1x subc, 1x and */
+ return ~(x >> 31) & 0x0000FF00;
+}
+
+unsigned int
+test_19 (int x)
+{
+ /* 1x cmp/pz, 1x subc, 1x extu.b */
+ return ~(x >> 31) & 0x000000FF;
+}
+
+unsigned int
+test_20 (int x, unsigned int y, unsigned int z)
+{
+ /* 1x shll */
+ return ~(x >> 31) ? y : z;
+}
+
+int
+test_21 (int x)
+{
+ /* 1x cmp/pz, 1x subc */
+ return x >= 0 ? 0xFFFFFFFF : 0;
+}
+
+int
+test_22 (int x)
+{
+ /* 1x cmp/pz, 1x movt */
+ return (x >> 31) + 1;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr64345-1.c b/gcc/testsuite/gcc.target/sh/pr64345-1.c
new file mode 100644
index 0000000..16c37d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr64345-1.c
@@ -0,0 +1,97 @@
+/* Verify that single bit zero extractions emit the expected
+ insns sequences. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "exts|extu|sha|shld|subc|xor" } } */
+
+/* { dg-final { scan-assembler-times "tst" 716 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "cmp/pz" 6 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "shll\t" 6 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "shlr\t" 8 { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "tst" 442 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld" 276 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "cmp/pz" 6 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "shll\t" 4 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "shlr\t" 8 { target { sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "and\t#1" 32 } } */
+
+#define make_func(type,shift)\
+ int test_##type##_##_shift_##shift##_0 (type x)\
+ {\
+ return ((x >> shift) ^ 1) & 1 ? -40 : -10;\
+ }\
+ int test_##type##_##_shift_##shift##_1 (type x)\
+ {\
+ return ((x >> shift) ^ 0) & 1 ? -40 : -10;\
+ }\
+ int test_##type##_##_shift_##shift##_2 (type x)\
+ {\
+ return ((x >> shift) ^ 1) & 1;\
+ }\
+ int test_##type##_##_shift_##shift##_3 (type x)\
+ {\
+ return ((x >> shift) ^ 0) & 1;\
+ }\
+ int test_##type##_##_shift_##shift##_4 (type x)\
+ {\
+ return (x & (1 << shift)) == 0;\
+ }\
+ int test_##type##_##_shift_##shift##_5 (type x)\
+ {\
+ return (x & (1 << shift)) != 0;\
+ }\
+\
+ int test_##type##_##_shift_##shift##_6 (type* x)\
+ {\
+ return ((*x >> shift) ^ 1) & 1 ? -40 : -10;\
+ }\
+ int test_##type##_##_shift_##shift##_7 (type* x)\
+ {\
+ return ((*x >> shift) ^ 0) & 1 ? -40 : -10;\
+ }\
+ int test_##type##_##_shift_##shift##_8 (type* x)\
+ {\
+ return ((*x >> shift) ^ 1) & 1;\
+ }\
+ int test_##type##_##_shift_##shift##_9 (type* x)\
+ {\
+ return ((*x >> shift) ^ 0) & 1;\
+ }\
+ int test_##type##_##_shift_##shift##_10 (type* x)\
+ {\
+ return (*x & (1 << shift)) == 0;\
+ }\
+ int test_##type##_##_shift_##shift##_11 (type* x)\
+ {\
+ return (*x & (1 << shift)) != 0;\
+ }
+
+#define make_funcs(type)\
+ make_func (type, 0)\
+ make_func (type, 1)\
+ make_func (type, 2)\
+ make_func (type, 3)\
+ make_func (type, 4)\
+ make_func (type, 5)\
+ make_func (type, 6)\
+ make_func (type, 7)
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+
+make_funcs (int8_t)
+make_funcs (uint8_t)
+make_funcs (int16_t)
+make_funcs (uint16_t)
+make_funcs (int32_t)
+make_funcs (uint32_t)
+make_funcs (int64_t)
+make_funcs (uint64_t)
diff --git a/gcc/testsuite/gcc.target/sh/pr64345-2.c b/gcc/testsuite/gcc.target/sh/pr64345-2.c
new file mode 100644
index 0000000..dba1552
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr64345-2.c
@@ -0,0 +1,116 @@
+/* Verify that the TST insn is used to extract a zero extended
+ single bit into the T bit (for a following conditional branch) and into
+ a GP register. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "exts|extu|sha|shld|subc|xor" } } */
+
+/* { dg-final { scan-assembler-times "tst" 61 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#1," 1 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#2" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#4" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#8" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#16" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#32" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#64" 2 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#128" 2 { target { ! sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "tst" 54 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#1," 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#2" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#4" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#8" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#16" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#32" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#64" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "tst\t#128" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#1," 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#2" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#3" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#4" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#5" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#6" 1 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "bld\t#7" 1 { target { sh2a } } } } */
+
+/* { dg-final { scan-assembler-times "and\t#1" 1 } } */
+/* { dg-final { scan-assembler-times "cmp/pz" 1 } } */
+/* { dg-final { scan-assembler-times "shll" 1 } } */
+
+typedef struct
+{
+ unsigned int b31 : 1;
+ unsigned int b30 : 1;
+ unsigned int b29 : 1;
+ unsigned int b28 : 1;
+ unsigned int b27 : 1;
+ unsigned int b26 : 1;
+ unsigned int b25 : 1;
+ unsigned int b24 : 1;
+ unsigned int b23 : 1;
+ unsigned int b22 : 1;
+ unsigned int b21 : 1;
+ unsigned int b20 : 1;
+ unsigned int b19 : 1;
+ unsigned int b18 : 1;
+ unsigned int b17 : 1;
+ unsigned int b16 : 1;
+ unsigned int b15 : 1;
+ unsigned int b14 : 1;
+ unsigned int b13 : 1;
+ unsigned int b12 : 1;
+ unsigned int b11 : 1;
+ unsigned int b10 : 1;
+ unsigned int b9 : 1;
+ unsigned int b8 : 1;
+ unsigned int b7 : 1;
+ unsigned int b6 : 1;
+ unsigned int b5 : 1;
+ unsigned int b4 : 1;
+ unsigned int b3 : 1;
+ unsigned int b2 : 1;
+ unsigned int b1 : 1;
+ unsigned int b0 : 1;
+} S;
+
+#define make_funcs(bitpos)\
+ unsigned int test_b##bitpos##_0 (S s)\
+ {\
+ return s.b##bitpos;\
+ }\
+ unsigned int test_b##bitpos##_1 (S s)\
+ {\
+ return !s.b##bitpos;\
+ }\
+
+make_funcs (0)
+make_funcs (1)
+make_funcs (2)
+make_funcs (3)
+make_funcs (4)
+make_funcs (5)
+make_funcs (6)
+make_funcs (7)
+make_funcs (8)
+make_funcs (9)
+make_funcs (10)
+make_funcs (11)
+make_funcs (12)
+make_funcs (13)
+make_funcs (14)
+make_funcs (15)
+make_funcs (16)
+make_funcs (17)
+make_funcs (18)
+make_funcs (19)
+make_funcs (20)
+make_funcs (21)
+make_funcs (22)
+make_funcs (23)
+make_funcs (24)
+make_funcs (25)
+make_funcs (26)
+make_funcs (27)
+make_funcs (28)
+make_funcs (29)
+make_funcs (30)
+make_funcs (31)