[GCC] match.pd: Simplify rule for bitwise not with casts

Message ID 20231128153812.4787-1-Ezra.Sitorus@arm.com
State Accepted
Headers
Series [GCC] match.pd: Simplify rule for bitwise not with casts |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Ezra Sitorus Nov. 28, 2023, 3:38 p.m. UTC
  From: Ezra Sitorus <ezra.sitorus@arm.com>

Add the transform rule (T)(~A) -> ~(T)(A) for view_convert. The simplified result could be a single assembly instruction when chained with other instructions.

gcc/ChangeLog:
        * match.pd: Add new transform rule.
	* testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpretq_vmvnq.c: Add new test
	* testsuite/gcc.target/arm/simd/vreinterpretq_vmvnq_1.c: Add new test
---
 gcc/match.pd                                  |  5 ++++
 .../advsimd-intrinsics/vreinterpretq_vmvnq.c  | 25 ++++++++++++++++++
 .../arm/simd/vreinterpretq_vmvnq_1.c          | 26 +++++++++++++++++++
 3 files changed, 56 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpretq_vmvnq.c
 create mode 100644 gcc/testsuite/gcc.target/arm/simd/vreinterpretq_vmvnq_1.c
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 95225e4ca5f..273230a7681 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3576,6 +3576,11 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	  && !TYPE_OVERFLOW_SANITIZED (type))
       (convert (op! @0 @1)))))
 
+/* (T)(~A) -> ~(T)A  */
+  (simplify
+   (view_convert (bit_not @0))
+   (bit_not (view_convert @0)))
+
   /* ~A + A -> -1 */
   (simplify
    (plus:c (convert? (bit_not @0)) (convert? @0))
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpretq_vmvnq.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpretq_vmvnq.c
new file mode 100644
index 00000000000..ed82c844bd4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpretq_vmvnq.c
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <arm_neon.h>
+
+int64x2_t test_vector1(int32x4_t a, int32x4_t b)
+{
+  return vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(a)),
+                   vreinterpretq_s64_s32(b));
+}
+
+int64x2_t test_vector2(int32x4_t a, int16x8_t b)
+{
+  return vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(a)),
+                   vreinterpretq_s64_s16(b));
+}
+
+int64x2_t test_vector3(int32x4_t a, int64x2_t b)
+{
+  return vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(a)), b);
+}
+
+/* { dg-final { scan-assembler-times {\tbic\t} 3 } } */
+/* { dg-final { scan-assembler-not {\tand\t} } } */
+/* { dg-final { scan-assembler-not {\tmvn\t} } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vreinterpretq_vmvnq_1.c b/gcc/testsuite/gcc.target/arm/simd/vreinterpretq_vmvnq_1.c
new file mode 100644
index 00000000000..a34425100ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vreinterpretq_vmvnq_1.c
@@ -0,0 +1,26 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-march=armv8.2-a -mfloat-abi=hard -mfpu=neon" } */
+
+#include <arm_neon.h>
+
+int64x2_t test_vector1(int32x4_t a, int32x4_t b)
+{
+  return vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(a)),
+                   vreinterpretq_s64_s32(b));
+}
+
+int64x2_t test_vector2(int32x4_t a, int16x8_t b)
+{
+  return vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(a)),
+                   vreinterpretq_s64_s16(b));
+}
+
+int64x2_t test_vector3(int32x4_t a, int64x2_t b)
+{
+  return vandq_s64(vreinterpretq_s64_s32(vmvnq_s32(a)), b);
+}
+
+/* { dg-final { scan-assembler-times {\tvbic\t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvand\t} } } */
+/* { dg-final { scan-assembler-not {\tvmvn\t} } } */