This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[GCC][PATCH][Aarch64] Added pattern to match zero extended bfxil


Hi all,

This patch captures the case where an unnecessary uxtw instruction is generated after a bfxil instruction when in SI mode, and stops it from being generated.
Note that this depends on my previous patch submission
(https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01148.html).

For example:

unsigned long
combine_balanced_int (unsigned int a, unsigned int b)
{
  return (a & 0xffff0000ll) | (b & 0x0000ffffll);
}

Would generate:

combine_balanced_int:
        bfxil   w0, w1, 0, 16
        uxtw    x0, w0
        ret

But with this patch generates:

combine_balanced_int:
        bfxil   w0, w1, 0, 16
        ret

Bootstrapped on aarch64-none-linux-gnu and regtested on aarch64-none-elf with
no regressions.


gcc/
2018-07-31  Sam Tebbs  <sam.tebbs@arm.com>

        PR target/85628
        * config/aarch64/aarch64.md (*aarch64_bfxilsi_uxtw): Define.

gcc/testsuite
2018-07-31  Sam Tebbs  <sam.tebbs@arm.com>

        PR target/85628
        * gcc.target/aarch64/combine_bfxil.c (combine_zero_extended_int, foo6):
        New functions.

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index ff2db4af38e16630daeada79afc604c4696abf82..74f20018a08ab19c509a0218bc46acb9558fb1cc 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5330,6 +5330,33 @@
   [(set_attr "type" "bfm")]
 )
 
+; Zero-extended version of above (aarch64_bfxil)
+(define_insn "*aarch64_bfxilsi_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+	(zero_extend:DI (ior:SI (and:SI (match_operand:SI 1 "register_operand"
+					"r,0")
+		    (match_operand:SI 3 "const_int_operand" "n, Ulc"))
+	    (and:SI (match_operand:SI 2 "register_operand" "0,r")
+		    (match_operand:SI 4 "const_int_operand" "Ulc, n")))))]
+  "(INTVAL (operands[3]) == ~INTVAL (operands[4]))
+  && (aarch64_is_left_consecutive (INTVAL (operands[3]))
+    || aarch64_is_left_consecutive (INTVAL (operands[4])))"
+  {
+    switch (which_alternative)
+    {
+      case 0:
+	operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[3])));
+	return "bfxil\\t%0, %1, 0, %3";
+      case 1:
+	operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[4])));
+	return "bfxil\\t%0, %2, 0, %3";
+      default:
+	gcc_unreachable ();
+    }
+  }
+  [(set_attr "type" "bfm")]
+)
+
 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
 ;; each valid permutation.
diff --git a/gcc/testsuite/gcc.target/aarch64/combine_bfxil.c b/gcc/testsuite/gcc.target/aarch64/combine_bfxil.c
index 3bc1dd5b216477efe7494dbcdac7a5bf465af218..6d3f865eed59f636aad712c3c65198af8f515c25 100644
--- a/gcc/testsuite/gcc.target/aarch64/combine_bfxil.c
+++ b/gcc/testsuite/gcc.target/aarch64/combine_bfxil.c
@@ -4,6 +4,13 @@
 extern void abort(void);
 
 unsigned long long
+combine_zero_extended_int (unsigned int a, unsigned int b)
+{
+  /* { dg-final { scan-assembler-not "uxtw\\t" } } */
+  return (a & 0xffff0000ll) | (b & 0x0000ffffll);
+}
+
+unsigned long long
 combine_balanced (unsigned long long a, unsigned long long b)
 {
   return (a & 0xffffffff00000000ll) | (b & 0x00000000ffffffffll);
@@ -71,6 +78,13 @@ foo5 (unsigned int a, unsigned int b, unsigned int *c, unsigned int *d)
   *d = combine_unbalanced_int(b, a);
 }
 
+void
+foo6 (unsigned int a, unsigned int b, unsigned long long *c, unsigned long long *d)
+{
+  *c = combine_zero_extended_int(a, b);
+  *d = combine_zero_extended_int(b, a);
+}
+
 int
 main(void)
 {
@@ -92,7 +106,12 @@ main(void)
   foo5(a2, b2, &c2, &d2);
   if(c2 != 0x01234598) abort();
   if(d2 != 0xfedcba67) abort();
+
+  unsigned long long c3, d3;
+  foo6(a2, b2, &c3, &d3);
+  if(c3 != 0x0123ba98) abort();
+  if(d3 != 0xfedc4567) abort();
   return 0;
 }
 
-/* { dg-final { scan-assembler-times "bfxil\\t" 10 } } */
+/* { dg-final { scan-assembler-times "bfxil\\t" 13 } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]