diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2015-01-24 13:04:53 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2015-01-24 13:04:53 +0000 |
commit | 841dbf801d85c65f02c04de31e7cf965a020c518 (patch) | |
tree | db69dc3cf457df982a926d511d89a52be95ee9fc /gcc/testsuite | |
parent | 19bd4ebce2c48709989f7b56d1be5360e86c33af (diff) | |
download | gcc-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/ChangeLog | 31 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr49263-1.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr49263-2.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr49263-3.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr49263.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr51244-12.c | 58 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr51244-4.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr52933-1.c | 49 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr52933-2.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr53987-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr54089-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr54236-1.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr54236-3.c | 73 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr59533-1.c | 185 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64345-1.c | 97 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/pr64345-2.c | 116 |
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) |