From: Oleg Endo Date: Mon, 21 Sep 2015 00:17:22 +0000 (+0000) Subject: re PR target/67126 ([SH] gcc.target/sh/pr51244-12.c failures) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0a775f1a4b4f95182b801969178c2dea7aeac3bf;p=gcc.git re PR target/67126 ([SH] gcc.target/sh/pr51244-12.c failures) gcc/ PR target/67126 * config/sh/sh.md (*reg_lsb_t): Emit bld insn on SH2A. (*mov_t_msb_neg): Rewrite negc pattern. gcc/testsuite/ PR target/67126 * gcc.target/sh/pr51244-12.c: Adjust testcase. * gcc.target/sh/pr54236-2.c: Likewise. From-SVN: r227957 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a76fc4e9ea..14d6927de6b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-09-21 Oleg Endo + + PR target/67126 + * config/sh/sh.md (*reg_lsb_t): Emit bld insn on SH2A. + (*mov_t_msb_neg): Rewrite negc pattern. + 2015-09-20 Wilco Dijkstra * config/aarch64/aarch64.c (aarch64_internal_mov_immediate): Cleanup diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 659c4c78b30..e0fc90368ee 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -4204,7 +4204,7 @@ label: ;; Let combine see that we can get the MSB and LSB into the T bit ;; via shll and shlr. This allows it to plug it into insns that can have ;; the T bit as an input (e.g. addc). -;; FIXME: On SH2A use bld #0,Rn instead of shlr to avoid mutating the input. +;; On SH2A use bld #0,Rn instead of shlr to avoid mutating the input. (define_insn_and_split "*reg_lsb_t" [(set (reg:SI T_REG) (and:SI (match_operand:SI 0 "arith_reg_operand") @@ -4214,7 +4214,8 @@ label: "&& 1" [(const_int 0)] { - emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[0])); + emit_insn (TARGET_SH2A ? gen_bldsi_reg (operands[0], const0_rtx) + : gen_shlr (gen_reg_rtx (SImode), operands[0])); }) (define_insn_and_split "*reg_msb_t" @@ -11979,41 +11980,31 @@ label: [(set (match_dup 0) (reg:SI T_REG)) (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))]) -;; Use negc to store the T bit in a MSB of a reg in the following way: -;; T = 0: 0x80000000 -> reg -;; T = 1: 0x7FFFFFFF -> reg -;; This works because 0 - 0x80000000 = 0x80000000. +;; 0x7fffffff + T +;; 0x7fffffff + (1-T) = 0 - 0x80000000 - T +;; +;; Notice that 0 - 0x80000000 = 0x80000000. + +;; Single bit tests are usually done with zero_extract. On non-SH2A this +;; will use a tst-negc sequence. On SH2A it will use a bld-addc sequence. +;; The zeroth bit requires a special pattern, otherwise we get a shlr-addc. +;; This is a special case of the generic treg_set_expr pattern and thus has +;; to come first or it will never match. (define_insn_and_split "*mov_t_msb_neg" [(set (match_operand:SI 0 "arith_reg_dest") - (minus:SI (const_int -2147483648) ;; 0x80000000 - (match_operand 1 "treg_set_expr"))) + (plus:SI (and:SI (match_operand:SI 1 "arith_reg_operand") + (const_int 1)) + (const_int 2147483647))) (clobber (reg:SI T_REG))] - "TARGET_SH1 && can_create_pseudo_p ()" + "TARGET_SH1" "#" - "&& 1" - [(const_int 0)] -{ - if (negt_reg_operand (operands[1], VOIDmode)) - { - emit_insn (gen_addc (operands[0], - force_reg (SImode, const0_rtx), - force_reg (SImode, GEN_INT (2147483647)))); - DONE; - } - - sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn); - if (ti.remove_trailing_nott ()) - emit_insn (gen_addc (operands[0], - force_reg (SImode, const0_rtx), - force_reg (SImode, GEN_INT (2147483647)))); - else - emit_insn (gen_negc (operands[0], - force_reg (SImode, GEN_INT (-2147483648LL)))); - DONE; -}) + "&& can_create_pseudo_p ()" + [(parallel [(set (match_dup 0) + (plus:SI (zero_extract:SI (match_dup 1) + (const_int 1) (const_int 0)) + (const_int 2147483647))) + (clobber (reg:SI T_REG))])]) -;; 0x7fffffff + T -;; 0x7fffffff + (1-T) = 0 - 0x80000000 - T (define_insn_and_split "*mov_t_msb_neg" [(set (match_operand:SI 0 "arith_reg_dest") (plus:SI (match_operand 1 "treg_set_expr") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5fd91c111ce..752bac6be3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-09-21 Oleg Endo + + PR target/67126 + * gcc.target/sh/pr51244-12.c: Adjust testcase. + * gcc.target/sh/pr54236-2.c: Likewise. + 2015-09-20 Oleg Endo * gcc.target/sh/pr43417.c: Move target independent test to ... diff --git a/gcc/testsuite/gcc.target/sh/pr51244-12.c b/gcc/testsuite/gcc.target/sh/pr51244-12.c index ae856f8c0ff..027c5ab975f 100644 --- a/gcc/testsuite/gcc.target/sh/pr51244-12.c +++ b/gcc/testsuite/gcc.target/sh/pr51244-12.c @@ -4,8 +4,14 @@ /* { dg-do compile } */ /* { dg-options "-O1" } */ /* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ -/* { dg-final { scan-assembler-times "negc" 15 } } */ -/* { dg-final { scan-assembler-times "addc" 3 } } */ + +/* { dg-final { scan-assembler-times "negc" 15 { target { ! sh2a } } } } */ +/* { dg-final { scan-assembler-times "addc" 3 { target { ! sh2a } } } } */ + +/* { dg-final { scan-assembler-times "negc" 13 { target { sh2a } } } } */ +/* { dg-final { scan-assembler-times "addc" 5 { target { sh2a } } } } */ +/* { dg-final { scan-assembler-times "bld" 2 { target { sh2a } } } } */ + /* { dg-final { scan-assembler-not "movrt|#-1|add\t|sub\t|movt" } } */ int diff --git a/gcc/testsuite/gcc.target/sh/pr54236-2.c b/gcc/testsuite/gcc.target/sh/pr54236-2.c index c72afb92957..b6c24939566 100644 --- a/gcc/testsuite/gcc.target/sh/pr54236-2.c +++ b/gcc/testsuite/gcc.target/sh/pr54236-2.c @@ -5,7 +5,6 @@ /* { dg-options "-O1" } */ /* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */ /* { dg-final { scan-assembler-times "addc" 36 } } */ -/* { dg-final { scan-assembler-times "shlr" 22 } } */ /* { dg-final { scan-assembler-times "shll" 14 } } */ /* { dg-final { scan-assembler-times "add\tr" 12 } } */ /* { dg-final { scan-assembler-not "movt" } } */ @@ -17,115 +16,118 @@ /* { dg-final { scan-assembler-times "bclr\t#0" 1 { target { sh2a } } } } */ +/* { dg-final { scan-assembler-times "shlr" 22 { target { ! sh2a } } } } */ +/* { dg-final { scan-assembler-not "shlr" { target { sh2a } } } } */ + int test_000 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + (b & 1); } int test_001 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + b + (c & 1); } int test_002 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return a + b + c + (d & 1); } int test_003 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return (b & 1) + a; } int test_004 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + (c & 1) + b; } int test_005 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return a + b + (d & 1) + c; } int test_006 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return (c & 1) + a + b; } int test_007 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return a + (d & 1) + b + c; } int test_008 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return (d & 1) + a + b + c; } int test_009 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + b + (b & 1); } int test_010 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + (b & 1) + b; } int test_011 (int a, int c, int b, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return (b & 1) + a + b; } int test_012 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return a + b + d + (b & 1); } int test_013 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return a + d + (b & 1) + b; } int test_014 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return a + (b & 1) + d + b; } int test_015 (int a, int c, int b, int d) { - // 1x shlr, 1x add, 1x addc + // 1x shlr/bld, 1x add, 1x addc return (b & 1) + a + d + b; } @@ -140,42 +142,42 @@ test_016 (int a, int b, int c, int d) int test_017 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + a + (a & 1); } int test_018 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return a + (a & 1) + a; } int test_019 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return (a & 1) + a + a; } int test_020 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return b + b + (a & 1); } int test_021 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return b + (a & 1) + b; } int test_022 (int a, int b, int c, int d) { - // 1x shlr, 1x addc + // 1x shlr/bld, 1x addc return (a & 1) + b + b; }