From bcb036c515a43d2c3ded6399aa486fbc3d7f8a76 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Fri, 16 Dec 2016 16:24:26 +0000 Subject: [PATCH] [AArch64] Split X-reg UBFX into W-reg LSR when possible * config/aarch64/aarch64.md: New define_split above insv. * gcc.target/aarch64/ubfx_lsr_1.c: New test. From-SVN: r243755 --- gcc/ChangeLog | 4 ++++ gcc/config/aarch64/aarch64.md | 20 ++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/aarch64/ubfx_lsr_1.c | 14 ++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/ubfx_lsr_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 84797ad..d7f39fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2016-12-16 Kyrylo Tkachov + + * config/aarch64/aarch64.md: New define_split above insv. + 2016-12-16 Jakub Jelinek PR c/78408 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 65eb326..078bd8e 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4325,6 +4325,26 @@ [(set_attr "type" "bfx")] ) +;; When the bit position and width add up to 32 we can use a W-reg LSR +;; instruction taking advantage of the implicit zero-extension of the X-reg. +(define_split + [(set (match_operand:DI 0 "register_operand") + (zero_extract:DI (match_operand:DI 1 "register_operand") + (match_operand 2 + "aarch64_simd_shift_imm_offset_di") + (match_operand 3 + "aarch64_simd_shift_imm_di")))] + "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), 1, + GET_MODE_BITSIZE (DImode) - 1) + && (INTVAL (operands[2]) + INTVAL (operands[3])) + == GET_MODE_BITSIZE (SImode)" + [(set (match_dup 0) + (zero_extend:DI (lshiftrt:SI (match_dup 4) (match_dup 3))))] + { + operands[4] = gen_lowpart (SImode, operands[1]); + } +) + ;; Bitfield Insert (insv) (define_expand "insv" [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dc64b2c..fc73346 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-12-16 Kyrylo Tkachov + + * gcc.target/aarch64/ubfx_lsr_1.c: New test. + 2016-12-16 Jakub Jelinek PR c/78408 diff --git a/gcc/testsuite/gcc.target/aarch64/ubfx_lsr_1.c b/gcc/testsuite/gcc.target/aarch64/ubfx_lsr_1.c new file mode 100644 index 0000000..f6f72b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ubfx_lsr_1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Check that an X-reg UBFX can be simplified into a W-reg LSR. */ + +int +f (unsigned long long x) +{ + x = (x >> 24) & 255; + return x + 1; +} + +/* { dg-final { scan-assembler "lsr\tw" } } */ +/* { dg-final { scan-assembler-not "ubfx\tx" } } */ -- 2.7.4