When a stmt is replaced by a pattern stmt during vectorization, the
existing live range calculation code still calculates the live range of
the original variable, and mark it as alive from the beginning of the
block.  Changing that to a live range of the pattern result can lead to
a more precise register pressure estimation.

The testcase is generated by LLM by adapting the x264 pixel_avg loop.
We used the vanilla pixel_avg loop as the testcase downstream because
our downstream version has other issues that overestimate the required
register number.  The adapted case, although not directly encountered in
benchmarks, can show that the estimation can be improved on the trunk,
at least for cases like this, too.

Regtested on rv64gcv and rv32gcv, no regression.

Assisted-by: Codex

gcc/ChangeLog:

        * config/riscv/riscv-vector-costs.cc (get_pattern_var): New
        function.
        (costs::compute_local_live_ranges): Replace the argument with
        the pattern result when necessary.

gcc/testsuite/ChangeLog:

        * gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c: Remove
        xfail.
        * gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-7.c: Ditto.
        * gcc.target/riscv/rvv/autovec/pr121910.c: Change expectation.
        * gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-16.c: New test.
---
 gcc/config/riscv/riscv-vector-costs.cc        | 26 +++++++++++++++++++
 .../costmodel/riscv/rvv/dynamic-lmul4-5.c     |  4 +--
 .../costmodel/riscv/rvv/dynamic-lmul4-7.c     |  4 +--
 .../costmodel/riscv/rvv/dynamic-lmul8-16.c    | 25 ++++++++++++++++++
 .../gcc.target/riscv/rvv/autovec/pr121910.c   |  2 +-
 5 files changed, 56 insertions(+), 5 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-16.c

diff --git a/gcc/config/riscv/riscv-vector-costs.cc 
b/gcc/config/riscv/riscv-vector-costs.cc
index 73e73634503..8f2139b637d 100644
--- a/gcc/config/riscv/riscv-vector-costs.cc
+++ b/gcc/config/riscv/riscv-vector-costs.cc
@@ -346,6 +346,31 @@ variable_vectorized_p (class loop *loop, stmt_vec_info 
stmt_info,
                   || type != load_vec_info_type));
 }
 
+/* Return the pattern result if the original definition of VAR is replaced by
+   a pattern stmt.  Otherwise, return VAR.  */
+static tree
+get_pattern_var (tree var, loop_vec_info loop_vinfo)
+{
+  gimple *stmt;
+  stmt_vec_info stmt_info;
+
+  if (TREE_CODE (var) == SSA_NAME
+      && (stmt = SSA_NAME_DEF_STMT (var))
+      && is_gimple_assign_or_call (stmt)
+      && (stmt_info = loop_vinfo->lookup_stmt (stmt))
+      && STMT_VINFO_IN_PATTERN_P (stmt_info))
+    {
+      stmt_info = STMT_VINFO_RELATED_STMT (stmt_info);
+      stmt = stmt_info->stmt;
+      if (gimple_code (stmt) == GIMPLE_CALL)
+       var = gimple_call_lhs (stmt);
+      else
+       var = gimple_assign_lhs (stmt);
+    }
+
+  return var;
+}
+
 /* Compute local live ranges of each vectorized variable.
    Note that we only compute local live ranges (within a block) since
    local live ranges information is accurate enough for us to determine
@@ -426,6 +451,7 @@ costs::compute_local_live_ranges (
                  if (variable_vectorized_p (loop, program_point.stmt_info,
                                             *node, var, false))
                    {
+                     var = get_pattern_var (var, loop_vinfo);
                      biggest_mode
                        = get_biggest_mode (biggest_mode,
                                            TYPE_MODE (TREE_TYPE (var)));
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c 
b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
index 387c3847cf2..09c64bb1cc7 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
@@ -39,9 +39,9 @@ void foo2 (int16_t *__restrict a,
     }
 }
 
-/* { dg-final { scan-assembler {e16,m2} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {e16,m2} } } */
 /* { dg-final { scan-assembler-not {csrr} } } */
-/* { dg-final { scan-tree-dump-times "Preferring smaller LMUL loop because it 
has unexpected spills" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Preferring smaller LMUL loop because it 
has unexpected spills" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 8" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 4" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 2" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-7.c 
b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-7.c
index 259885f6739..1d37a516a76 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-7.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-7.c
@@ -39,9 +39,9 @@ void foo2 (int8_t *__restrict a,
     }
 }
 
-/* { dg-final { scan-assembler {e64,m4} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {e64,m4} } } */
 /* { dg-final { scan-assembler-not {csrr} } } */
-/* { dg-final { scan-tree-dump-times "Preferring smaller LMUL loop because it 
has unexpected spills" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Preferring smaller LMUL loop because it 
has unexpected spills" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 8" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 4" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 2" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-16.c 
b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-16.c
new file mode 100644
index 00000000000..7f4b29dcc83
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul8-16.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize 
-mrvv-max-lmul=dynamic -fdump-tree-vect-details" } */
+
+/* Replaced scalar average results must not be counted as block-wide int
+   live ranges.  Four independent averages expose the false spill estimate.  */
+void
+avg4 (unsigned char *restrict d0, const unsigned char *restrict a0,
+      const unsigned char *restrict b0, unsigned char *restrict d1,
+      const unsigned char *restrict a1, const unsigned char *restrict b1,
+      unsigned char *restrict d2, const unsigned char *restrict a2,
+      const unsigned char *restrict b2, unsigned char *restrict d3,
+      const unsigned char *restrict a3, const unsigned char *restrict b3, int 
n)
+{
+  for (int i = 0; i < n; i++)
+    {
+      d0[i] = (a0[i] + b0[i] + 1) >> 1;
+      d1[i] = (a1[i] + b1[i] + 1) >> 1;
+      d2[i] = (a2[i] + b2[i] + 1) >> 1;
+      d3[i] = (a3[i] + b3[i] + 1) >> 1;
+    }
+}
+
+/* { dg-final { scan-assembler-times {e8,m8} 1 } } */
+/* { dg-final { scan-tree-dump-not "Biggest mode = SI" "vect" } } */
+/* { dg-final { scan-tree-dump-not "Preferring smaller LMUL loop because it 
has unexpected spills" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121910.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121910.c
index 024aae33648..02a52ce94d9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121910.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr121910.c
@@ -31,4 +31,4 @@ void mc_chroma(uint8_t* dst, int i_dst_stride, uint8_t* src, 
int i_src_stride,
 }
 
 /* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
-/* { dg-final { scan-tree-dump "Choosing vector mode RVVM1QI" "vect" } } */
+/* { dg-final { scan-tree-dump "Choosing vector mode RVVM2QI" "vect" } } */
-- 
2.47.1

Reply via email to