Hi,

In can_vec_perm_const_p if we cannot directly permute a vector mode we
try to pun it with a byte mode.  qimode_for_vec_perm checks gets the
mode size and uses that as number of elements for the new QImode vector.

This doesn't work for RVV mask vectors, though:  First, their
precision might be smaller than a byte and second, there is no
way to easily pun them.  The most common way would be a vector select
from {0, 0, ...} and {1, 1, ...} vectors.  Therefore this patch checks
if the perm's innermode precision is a multiple of QImode's precision.

I hit this during testing of a riscv backend patch related to
gather/scatter (to be upstreamed soon).  It manifests in around 10-20
FAILs in the test suite so I figured we don't need a separate test.

Bootstrapped and regtested on x86 and power10.  Regtested on aarch64 and
riscv64.

Regards
 Robin

gcc/ChangeLog:

        * optabs-query.cc (qimode_for_vec_perm): Check if QImode's
        precision divides the inner mode's precision.
---
 gcc/optabs-query.cc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc
index 5335d0d8401..484d7c2e205 100644
--- a/gcc/optabs-query.cc
+++ b/gcc/optabs-query.cc
@@ -358,7 +358,9 @@ can_conditionally_move_p (machine_mode mode)
 opt_machine_mode
 qimode_for_vec_perm (machine_mode mode)
 {
-  if (GET_MODE_INNER (mode) != QImode)
+  if (GET_MODE_INNER (mode) != QImode
+      && multiple_p (GET_MODE_PRECISION (GET_MODE_INNER (mode)),
+                    GET_MODE_PRECISION (QImode)))
     return related_vector_mode (mode, QImode, GET_MODE_SIZE (mode));
   return opt_machine_mode ();
 }
-- 
2.51.0

Reply via email to