From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1880) id 58293382D458; Fri, 27 May 2022 04:55:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 58293382D458 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Max Filippov To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-790] xtensa: Improve bswap[sd]i2 insn patterns X-Act-Checkin: gcc X-Git-Author: Takayuki 'January June' Suwa X-Git-Refname: refs/heads/master X-Git-Oldrev: 6454b4a8f5d90dd355c3c7e31a592a439223b645 X-Git-Newrev: 9aad2b22436d5346fa224e5c14439dcef36cf3dd Message-Id: <20220527045554.58293382D458@sourceware.org> Date: Fri, 27 May 2022 04:55:54 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 May 2022 04:55:54 -0000 https://gcc.gnu.org/g:9aad2b22436d5346fa224e5c14439dcef36cf3dd commit r13-790-g9aad2b22436d5346fa224e5c14439dcef36cf3dd Author: Takayuki 'January June' Suwa Date: Fri May 13 22:33:59 2022 +0900 xtensa: Improve bswap[sd]i2 insn patterns This patch makes bswap[sd]i2 better register allocation, and reconstructs bswapsi2 in order to take advantage of GIMPLE manual byte-swapping recognition. gcc/ChangeLog: * config/xtensa/xtensa.md (bswapsi2): New expansion pattern. (bswapsi2_internal): Revise the template and condition, and add detection code for preceding the same insn in order to omit a "SSAI 8" instruction of the latter. (bswapdi2): Suppress built-in insn expansion with the corresponding library call when optimizing for size. gcc/testsuite/ChangeLog: * gcc.target/xtensa/bswap.c: Remove test. * gcc.target/xtensa/bswap-O1.c: New. * gcc.target/xtensa/bswap-O2.c: Ditto. * gcc.target/xtensa/bswap-Os.c: Ditto. Diff: --- gcc/config/xtensa/xtensa.md | 77 +++++++++++++++++++++++------- gcc/testsuite/gcc.target/xtensa/bswap-O1.c | 37 ++++++++++++++ gcc/testsuite/gcc.target/xtensa/bswap-O2.c | 37 ++++++++++++++ gcc/testsuite/gcc.target/xtensa/bswap-Os.c | 37 ++++++++++++++ gcc/testsuite/gcc.target/xtensa/bswap.c | 14 ------ 5 files changed, 172 insertions(+), 30 deletions(-) diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 2d146b7995c..6f5cbc541d8 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -471,23 +471,68 @@ ;; Byte swap. -(define_insn "bswapsi2" - [(set (match_operand:SI 0 "register_operand" "=&a") - (bswap:SI (match_operand:SI 1 "register_operand" "r")))] - "!optimize_size" - "ssai\t8\;srli\t%0, %1, 16\;src\t%0, %0, %1\;src\t%0, %0, %0\;src\t%0, %1, %0" - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set_attr "length" "15")]) +(define_expand "bswapsi2" + [(set (match_operand:SI 0 "register_operand" "") + (bswap:SI (match_operand:SI 1 "register_operand" "")))] + "!optimize_debug && optimize > 1" +{ + /* GIMPLE manual byte-swapping recognition is now activated. + For both built-in and manual bswaps, emit corresponding library call + if optimizing for size, or a series of dedicated machine instructions + if otherwise. */ + if (optimize_size) + emit_library_call_value (optab_libfunc (bswap_optab, SImode), + operands[0], LCT_NORMAL, SImode, + operands[1], SImode); + else + emit_insn (gen_bswapsi2_internal (operands[0], operands[1])); + DONE; +}) -(define_insn "bswapdi2" - [(set (match_operand:DI 0 "register_operand" "=&a") - (bswap:DI (match_operand:DI 1 "register_operand" "r")))] - "!optimize_size" - "ssai\t8\;srli\t%0, %D1, 16\;src\t%0, %0, %D1\;src\t%0, %0, %0\;src\t%0, %D1, %0\;srli\t%D0, %1, 16\;src\t%D0, %D0, %1\;src\t%D0, %D0, %D0\;src\t%D0, %1, %D0" - [(set_attr "type" "arith") - (set_attr "mode" "DI") - (set_attr "length" "27")]) +(define_insn "bswapsi2_internal" + [(set (match_operand:SI 0 "register_operand" "=a,&a") + (bswap:SI (match_operand:SI 1 "register_operand" "0,r"))) + (clobber (match_scratch:SI 2 "=&a,X"))] + "!optimize_debug && optimize > 1 && !optimize_size" +{ + rtx_insn *prev_insn = prev_nonnote_nondebug_insn (insn); + const char *init = "ssai\t8\;"; + static char result[64]; + if (prev_insn && NONJUMP_INSN_P (prev_insn)) + { + rtx x = PATTERN (prev_insn); + if (GET_CODE (x) == PARALLEL && XVECLEN (x, 0) == 2 + && GET_CODE (XVECEXP (x, 0, 0)) == SET + && GET_CODE (XVECEXP (x, 0, 1)) == CLOBBER) + { + x = XEXP (XVECEXP (x, 0, 0), 1); + if (GET_CODE (x) == BSWAP && GET_MODE (x) == SImode) + init = ""; + } + } + sprintf (result, + (which_alternative == 0) + ? "%s" "srli\t%%2, %%1, 16\;src\t%%2, %%2, %%1\;src\t%%2, %%2, %%2\;src\t%%0, %%1, %%2" + : "%s" "srli\t%%0, %%1, 16\;src\t%%0, %%0, %%1\;src\t%%0, %%0, %%0\;src\t%%0, %%1, %%0", + init); + return result; +} + [(set_attr "type" "arith,arith") + (set_attr "mode" "SI") + (set_attr "length" "15,15")]) + +(define_expand "bswapdi2" + [(set (match_operand:DI 0 "register_operand" "") + (bswap:DI (match_operand:DI 1 "register_operand" "")))] + "!optimize_debug && optimize > 1 && optimize_size" +{ + /* Replace with a single DImode library call. + Without this, two SImode library calls are emitted. */ + emit_library_call_value (optab_libfunc (bswap_optab, DImode), + operands[0], LCT_NORMAL, DImode, + operands[1], DImode); + DONE; +}) ;; Negation and one's complement. diff --git a/gcc/testsuite/gcc.target/xtensa/bswap-O1.c b/gcc/testsuite/gcc.target/xtensa/bswap-O1.c new file mode 100644 index 00000000000..a0c885baaf1 --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/bswap-O1.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +unsigned int test_0(unsigned int a) +{ + return (a & 0x000000FF) << 24 | + (a & 0x0000FF00) << 8 | + (a & 0x00FF0000) >> 8 | + (a & 0xFF000000) >> 24; +} + +unsigned int test_1(unsigned int a) +{ + union + { + unsigned int i; + unsigned char a[4]; + } u, v; + u.i = a; + v.a[0] = u.a[3]; + v.a[1] = u.a[2]; + v.a[2] = u.a[1]; + v.a[3] = u.a[0]; + return v.i; +} + +unsigned int test_2(unsigned int a) +{ + return __builtin_bswap32(a); +} + +unsigned long long test_3(unsigned long long a) +{ + return __builtin_bswap64(a); +} + +/* { dg-final { scan-assembler-times "call" 2 } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/bswap-O2.c b/gcc/testsuite/gcc.target/xtensa/bswap-O2.c new file mode 100644 index 00000000000..4cf95b9255c --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/bswap-O2.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +unsigned int test_0(unsigned int a) +{ + return (a & 0x000000FF) << 24 | + (a & 0x0000FF00) << 8 | + (a & 0x00FF0000) >> 8 | + (a & 0xFF000000) >> 24; +} + +unsigned int test_1(unsigned int a) +{ + union + { + unsigned int i; + unsigned char a[4]; + } u, v; + u.i = a; + v.a[0] = u.a[3]; + v.a[1] = u.a[2]; + v.a[2] = u.a[1]; + v.a[3] = u.a[0]; + return v.i; +} + +unsigned int test_2(unsigned int a) +{ + return __builtin_bswap32(a); +} + +unsigned long long test_3(unsigned long long a) +{ + return __builtin_bswap64(a); +} + +/* { dg-final { scan-assembler-times "ssai" 4 } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/bswap-Os.c b/gcc/testsuite/gcc.target/xtensa/bswap-Os.c new file mode 100644 index 00000000000..1e010fd62ae --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/bswap-Os.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +unsigned int test_0(unsigned int a) +{ + return (a & 0x000000FF) << 24 | + (a & 0x0000FF00) << 8 | + (a & 0x00FF0000) >> 8 | + (a & 0xFF000000) >> 24; +} + +unsigned int test_1(unsigned int a) +{ + union + { + unsigned int i; + unsigned char a[4]; + } u, v; + u.i = a; + v.a[0] = u.a[3]; + v.a[1] = u.a[2]; + v.a[2] = u.a[1]; + v.a[3] = u.a[0]; + return v.i; +} + +unsigned int test_2(unsigned int a) +{ + return __builtin_bswap32(a); +} + +unsigned long long test_3(unsigned long long a) +{ + return __builtin_bswap64(a); +} + +/* { dg-final { scan-assembler-times "call" 4 } } */ diff --git a/gcc/testsuite/gcc.target/xtensa/bswap.c b/gcc/testsuite/gcc.target/xtensa/bswap.c deleted file mode 100644 index 057a3569703..00000000000 --- a/gcc/testsuite/gcc.target/xtensa/bswap.c +++ /dev/null @@ -1,14 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O1" } */ - -unsigned long f32(unsigned long v) -{ - return __builtin_bswap32(v); -} - -unsigned long long f64(unsigned long long v) -{ - return __builtin_bswap64(v); -} - -/* { dg-final { scan-assembler-times "ssai" 2 } } */