[AArch64] Split X-reg UBFX into W-reg LSR when possible
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Fri, 16 Dec 2016 16:24:26 +0000 (16:24 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Fri, 16 Dec 2016 16:24:26 +0000 (16:24 +0000)
* config/aarch64/aarch64.md: New define_split above insv<mode>.

* gcc.target/aarch64/ubfx_lsr_1.c: New test.

From-SVN: r243755

gcc/ChangeLog
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/ubfx_lsr_1.c [new file with mode: 0644]

index 84797ad7acb483a3df73c53e20b616ee61bf5a94..d7f39fcb05e6e4fffeb334ecd99673ff62f5f658 100644 (file)
@@ -1,3 +1,7 @@
+2016-12-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md: New define_split above insv<mode>.
+
 2016-12-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/78408
index 65eb3265bc2964c2ed9ed455c0723cc455371367..078bd8e69a0ebf6dbc94dab33d9eb494ec9154eb 100644 (file)
   [(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<mode>"
   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
index dc64b2c7f6db991a97048749b38c6059a2bf7f78..fc73346906ce72c8d6785743dd21af6eda4b6ed5 100644 (file)
@@ -1,3 +1,7 @@
+2016-12-16  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/aarch64/ubfx_lsr_1.c: New test.
+
 2016-12-16  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..f6f72b0
--- /dev/null
@@ -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" } } */