]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
MATCH: Optimize COND_ADD_LEN reduction pattern
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Tue, 26 Sep 2023 09:50:37 +0000 (17:50 +0800)
committerPan Li <pan2.li@intel.com>
Tue, 26 Sep 2023 12:20:32 +0000 (20:20 +0800)
This patch leverage this commit: https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=62b505a4d5fc89
to optimize COND_LEN_ADD reduction pattern.

We are doing optimization of VEC_COND_EXPR + COND_LEN_ADD -> COND_LEN_ADD.

Consider thsi following case:

void
pr11594 (uint64_t *restrict a, uint64_t *restrict b, int loop_size)
{
  uint64_t result = 0;

  for (int i = 0; i < loop_size; i++)
    {
      if (b[i] <= a[i])
{
  result += a[i];
}
    }

  a[0] = result;
}

Before this patch:
        vsetvli a7,zero,e64,m1,ta,ma
        vmv.v.i v2,0
        vmv1r.v v3,v2                    --- redundant
.L3:
        vsetvli a5,a2,e64,m1,ta,ma
        vle64.v v1,0(a3)
        vle64.v v0,0(a1)
        slli    a6,a5,3
        vsetvli a7,zero,e64,m1,ta,ma
        sub     a2,a2,a5
        vmsleu.vv       v0,v0,v1
        add     a1,a1,a6
        vmerge.vvm      v1,v3,v1,v0     ---- redundant.
        add     a3,a3,a6
        vsetvli zero,a5,e64,m1,tu,ma
        vadd.vv v2,v2,v1
        bne     a2,zero,.L3
        li      a5,0
        vsetvli a4,zero,e64,m1,ta,ma
        vmv.s.x v1,a5
        vredsum.vs      v2,v2,v1
        vmv.x.s a5,v2
        sd      a5,0(a0)
        ret

After this patch:

vsetvli a6,zero,e64,m1,ta,ma
vmv.v.i v1,0
.L3:
vsetvli a5,a2,e64,m1,ta,ma
vle64.v v2,0(a4)
vle64.v v0,0(a1)
slli a3,a5,3
vsetvli a6,zero,e64,m1,ta,ma
sub a2,a2,a5
vmsleu.vv v0,v0,v2
add a1,a1,a3
vsetvli zero,a5,e64,m1,tu,mu
add a4,a4,a3
vadd.vv v1,v1,v2,v0.t
bne a2,zero,.L3
li a5,0
vsetivli zero,1,e64,m1,ta,ma
vmv.s.x v2,a5
vsetvli a5,zero,e64,m1,ta,ma
vredsum.vs v1,v1,v2
vmv.x.s a5,v1
sd a5,0(a0)
ret

Bootstrap && Regression is running.

Ok for trunk when testing passes ?

PR tree-optimization/111594
PR tree-optimization/110660

gcc/ChangeLog:

* match.pd: Optimize COND_LEN_ADD reduction.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/cond/cond_reduc-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/pr111594.c: New test.

gcc/match.pd
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_reduc-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/pr111594.c [new file with mode: 0644]

index a17778fbaa616399f4cdc0a91e75055a2be2d4e9..3ce90c3333b7b7c3293bb9165dca2845c1d48d9b 100644 (file)
@@ -8866,6 +8866,21 @@ and,
   (IFN_COND_ADD @0 @1 (vec_cond @2 @3 integer_zerop) @1)
    (IFN_COND_ADD (bit_and @0 @2) @1 @3 @1))
 
+/* Detect simplication for a conditional length reduction where
+
+   a = mask ? b : 0
+   c = i < len + bias ? d + a : d
+
+   is turned into
+
+   c = mask && i < len + bias ? d + b : d.  */
+(simplify
+  (IFN_COND_LEN_ADD integer_truep @0 (vec_cond @1 @2 zerop@5) @0 @3 @4)
+   (if (ANY_INTEGRAL_TYPE_P (type)
+       || (FLOAT_TYPE_P (type)
+           && fold_real_zero_addition_p (type, NULL_TREE, @5, 0)))
+    (IFN_COND_LEN_ADD @1 @0 @2 @0 @3 @4)))
+
 /* For pointers @0 and @2 and nonnegative constant offset @1, look for
    expressions like:
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_reduc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_reduc-1.c
new file mode 100644 (file)
index 0000000..db6f9d1
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvfh -mabi=lp64d -fno-vect-cost-model -ffast-math -fdump-tree-optimized" } */
+
+#include <stdint-gcc.h>
+
+#define COND_REDUCTION(TYPE)                                                   \
+  TYPE foo##TYPE (TYPE *restrict a, TYPE *restrict b, int loop_size)           \
+  {                                                                            \
+    TYPE result = 0;                                                           \
+    for (int i = 0; i < loop_size; i++)                                        \
+      if (b[i] <= a[i])                                                        \
+       result += a[i];                                                        \
+    return result;                                                             \
+  }
+
+COND_REDUCTION (int8_t)
+COND_REDUCTION (int16_t)
+COND_REDUCTION (int32_t)
+COND_REDUCTION (int64_t)
+COND_REDUCTION (uint8_t)
+COND_REDUCTION (uint16_t)
+COND_REDUCTION (uint32_t)
+COND_REDUCTION (uint64_t)
+COND_REDUCTION (_Float16)
+COND_REDUCTION (float)
+COND_REDUCTION (double)
+
+/* { dg-final { scan-tree-dump-not "VCOND_MASK" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "COND_LEN_ADD" 11 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/pr111594.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/pr111594.c
new file mode 100644 (file)
index 0000000..6d81b26
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv -mabi=lp64d -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+void
+pr11594 (uint64_t *restrict a, uint64_t *restrict b, int loop_size)
+{
+  uint64_t result = 0;
+
+  for (int i = 0; i < loop_size; i++)
+    {
+      if (b[i] <= a[i])
+       {
+         result += a[i];
+       }
+    }
+
+  a[0] = result;
+}
+
+/* { dg-final { scan-assembler-not {vmerge} } } */