This patch adds an is_gather_scatter argument to the
support_vector_misalignment hook.  All targets but riscv do not care
about alignment for gather/scatter so return true for is_gather_scatter.

gcc/ChangeLog:

        * config/aarch64/aarch64.cc 
(aarch64_builtin_support_vector_misalignment):
        Return true for gather/scatter.
        * config/arm/arm.cc (arm_builtin_support_vector_misalignment):
        Ditto.
        * config/epiphany/epiphany.cc (epiphany_support_vector_misalignment):
        Ditto.
        * config/gcn/gcn.cc (gcn_vectorize_support_vector_misalignment):
        Ditto.
        * config/loongarch/loongarch.cc 
(loongarch_builtin_support_vector_misalignment):
        Ditto.
        * config/riscv/riscv.cc (riscv_support_vector_misalignment):
        Add gather/scatter argument.
        * config/rs6000/rs6000.cc (rs6000_builtin_support_vector_misalignment):
        Return true for gather/scatter.
        * config/s390/s390.cc (s390_support_vector_misalignment):
        Ditto.
        * doc/tm.texi: Add argument.
        * target.def: Ditto.
        * targhooks.cc (default_builtin_support_vector_misalignment):
        Ditto.
        * targhooks.h (default_builtin_support_vector_misalignment):
        Ditto.
        * tree-vect-data-refs.cc (vect_supportable_dr_alignment):
        Ditto.
---
 gcc/config/aarch64/aarch64.cc     | 12 +++++++++---
 gcc/config/arm/arm.cc             | 12 +++++++++---
 gcc/config/epiphany/epiphany.cc   |  8 ++++++--
 gcc/config/gcn/gcn.cc             |  6 +++++-
 gcc/config/loongarch/loongarch.cc |  8 ++++++--
 gcc/config/riscv/riscv.cc         | 29 +++++++++++++++++++++++------
 gcc/config/rs6000/rs6000.cc       |  6 +++++-
 gcc/config/s390/s390.cc           |  6 ++++--
 gcc/doc/tm.texi                   |  8 +++++---
 gcc/target.def                    | 14 +++++++++-----
 gcc/targhooks.cc                  |  2 ++
 gcc/targhooks.h                   |  2 +-
 gcc/tree-vect-data-refs.cc        |  2 +-
 13 files changed, 85 insertions(+), 30 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 10b8ed5d387..0162c724cd2 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -356,7 +356,8 @@ static int aarch64_address_cost (rtx, machine_mode, 
addr_space_t, bool);
 static bool aarch64_builtin_support_vector_misalignment (machine_mode mode,
                                                         const_tree type,
                                                         int misalignment,
-                                                        bool is_packed);
+                                                        bool is_packed,
+                                                        bool 
is_gather_scatter);
 static machine_mode aarch64_simd_container_mode (scalar_mode, poly_int64);
 static bool aarch64_print_address_internal (FILE*, machine_mode, rtx,
                                            aarch64_addr_query_type);
@@ -24401,10 +24402,14 @@ aarch64_simd_vector_alignment_reachable (const_tree 
type, bool is_packed)
 static bool
 aarch64_builtin_support_vector_misalignment (machine_mode mode,
                                             const_tree type, int misalignment,
-                                            bool is_packed)
+                                            bool is_packed,
+                                            bool is_gather_scatter)
 {
   if (TARGET_SIMD && STRICT_ALIGNMENT)
     {
+      if (is_gather_scatter)
+       return true;
+
       /* Return if movmisalign pattern is not supported for this mode.  */
       if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
         return false;
@@ -24414,7 +24419,8 @@ aarch64_builtin_support_vector_misalignment 
(machine_mode mode,
        return false;
     }
   return default_builtin_support_vector_misalignment (mode, type, misalignment,
-                                                     is_packed);
+                                                     is_packed,
+                                                     is_gather_scatter);
 }
 
 /* If VALS is a vector constant that can be loaded into a register
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index bde06f3fa86..29b45ae96bd 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -289,7 +289,8 @@ static bool arm_vector_alignment_reachable (const_tree 
type, bool is_packed);
 static bool arm_builtin_support_vector_misalignment (machine_mode mode,
                                                     const_tree type,
                                                     int misalignment,
-                                                    bool is_packed);
+                                                    bool is_packed,
+                                                    bool is_gather_scatter);
 static void arm_conditional_register_usage (void);
 static enum flt_eval_method arm_excess_precision (enum excess_precision_type);
 static reg_class_t arm_preferred_rename_class (reg_class_t rclass);
@@ -30661,12 +30662,16 @@ arm_vector_alignment_reachable (const_tree type, bool 
is_packed)
 static bool
 arm_builtin_support_vector_misalignment (machine_mode mode,
                                         const_tree type, int misalignment,
-                                        bool is_packed)
+                                        bool is_packed,
+                                        bool is_gather_scatter)
 {
   if (TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access)
     {
       HOST_WIDE_INT align = TYPE_ALIGN_UNIT (type);
 
+      if (is_gather_scatter)
+       return true;
+
       if (is_packed)
         return align == 1;
 
@@ -30683,7 +30688,8 @@ arm_builtin_support_vector_misalignment (machine_mode 
mode,
     }
 
   return default_builtin_support_vector_misalignment (mode, type, misalignment,
-                                                     is_packed);
+                                                     is_packed,
+                                                     is_gather_scatter);
 }
 
 static void
diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc
index 16626f85f7e..f53a643575b 100644
--- a/gcc/config/epiphany/epiphany.cc
+++ b/gcc/config/epiphany/epiphany.cc
@@ -2816,12 +2816,16 @@ epiphany_vector_alignment_reachable (const_tree type, 
bool is_packed)
 
 static bool
 epiphany_support_vector_misalignment (machine_mode mode, const_tree type,
-                                     int misalignment, bool is_packed)
+                                     int misalignment, bool is_packed,
+                                     bool is_gather_scatter)
 {
+  if (is_gather_scatter)
+    return true;
   if (GET_MODE_SIZE (mode) == 8 && misalignment % 4 == 0)
     return true;
   return default_builtin_support_vector_misalignment (mode, type, misalignment,
-                                                     is_packed);
+                                                     is_packed,
+                                                     is_gather_scatter);
 }
 
 /* STRUCTURE_SIZE_BOUNDARY seems a bit crude in how it enlarges small
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index 0ce5a29fbb5..72203dcccd4 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -5315,8 +5315,12 @@ gcn_preferred_vector_alignment (const_tree type)
 static bool
 gcn_vectorize_support_vector_misalignment (machine_mode ARG_UNUSED (mode),
                                           const_tree type, int misalignment,
-                                          bool is_packed)
+                                          bool is_packed,
+                                          bool is_gather_scatter)
 {
+  if (is_gather_scatter)
+    return true;
+
   if (is_packed)
     return false;
 
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index f62e4163c71..39a56dd6d22 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -11116,17 +11116,21 @@ static bool
 loongarch_builtin_support_vector_misalignment (machine_mode mode,
                                               const_tree type,
                                               int misalignment,
-                                              bool is_packed)
+                                              bool is_packed,
+                                              bool is_gather_scatter)
 {
   if ((ISA_HAS_LSX || ISA_HAS_LASX) && STRICT_ALIGNMENT)
     {
+      if (is_gather_scatter)
+       return true;
       if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
        return false;
       if (misalignment == -1)
        return false;
     }
   return default_builtin_support_vector_misalignment (mode, type, misalignment,
-                                                     is_packed);
+                                                     is_packed,
+                                                     is_gather_scatter);
 }
 
 /* Return a PARALLEL containing NELTS elements, with element I equal
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a4428f0e96d..dcb0291d79d 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12608,14 +12608,31 @@ riscv_estimated_poly_value (poly_int64 val,
 /* Return true if the vector misalignment factor is supported by the
    target.  */
 bool
-riscv_support_vector_misalignment (machine_mode mode,
-                                  const_tree type ATTRIBUTE_UNUSED,
-                                  int misalignment,
-                                  bool is_packed ATTRIBUTE_UNUSED)
+riscv_support_vector_misalignment (machine_mode mode, const_tree type,
+                                  int misalignment, bool is_packed,
+                                  bool is_gather_scatter)
 {
-  /* Depend on movmisalign pattern.  */
+  /* IS_PACKED is true if the corresponding scalar element is not naturally
+     aligned.  If the misalignment is unknown and the the access is packed
+     we defer to the default hook which will check if movmisalign is present.
+     Movmisalign, in turn, depends on TARGET_VECTOR_MISALIGN_SUPPORTED.  */
+  if (misalignment == DR_MISALIGNMENT_UNKNOWN)
+    {
+      if (!is_packed)
+       return true;
+    }
+  else
+    {
+      /* If we know that misalignment is a multiple of the element size, we're
+        good.  */
+      if (misalignment % TYPE_ALIGN_UNIT (type) == 0)
+       return true;
+    }
+
+  /* Otherwise fall back to movmisalign again.  */
   return default_builtin_support_vector_misalignment (mode, type, misalignment,
-                                                     is_packed);
+                                                     is_packed,
+                                                     is_gather_scatter);
 }
 
 /* Implement TARGET_VECTORIZE_GET_MASK_MODE.  */
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 7ee26e52b13..a7a5aa5e289 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -4951,10 +4951,14 @@ static bool
 rs6000_builtin_support_vector_misalignment (machine_mode mode,
                                            const_tree type,
                                            int misalignment,
-                                           bool is_packed)
+                                           bool is_packed,
+                                           bool is_gather_scatter)
 {
   if (TARGET_VSX)
     {
+      if (is_gather_scatter)
+       return true;
+
       if (TARGET_EFFICIENT_UNALIGNED_VSX)
        return true;
 
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index de9c15c7bd4..66e843f2823 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -17334,13 +17334,15 @@ static bool
 s390_support_vector_misalignment (machine_mode mode ATTRIBUTE_UNUSED,
                                  const_tree type ATTRIBUTE_UNUSED,
                                  int misalignment ATTRIBUTE_UNUSED,
-                                 bool is_packed ATTRIBUTE_UNUSED)
+                                 bool is_packed ATTRIBUTE_UNUSED,
+                                 bool is_gather_scatter ATTRIBUTE_UNUSED)
 {
   if (TARGET_VX)
     return true;
 
   return default_builtin_support_vector_misalignment (mode, type, misalignment,
-                                                     is_packed);
+                                                     is_packed,
+                                                     is_gather_scatter);
 }
 
 /* The vector ABI requires vector types to be aligned on an 8 byte
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 5e305643b3a..928578bcc03 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6382,12 +6382,14 @@ return type of the vectorized function shall be of 
vector type
 @var{vec_type_out} and the argument types should be @var{vec_type_in}.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT 
(machine_mode @var{mode}, const_tree @var{type}, int @var{misalignment}, bool 
@var{is_packed})
+@deftypefn {Target Hook} bool TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT 
(machine_mode @var{mode}, const_tree @var{type}, int @var{misalignment}, bool 
@var{is_packed}, bool @var{is_gather_scatter})
 This hook should return true if the target supports misaligned vector
 store/load of a specific factor denoted in the @var{misalignment}
 parameter.  The vector store/load should be of machine mode @var{mode} and
-the elements in the vectors should be of type @var{type}.  @var{is_packed}
-parameter is true if the memory access is defined in a packed struct.
+the elements in the vectors should be of type @var{type}.  The
+@var{is_packed} parameter is true if the misalignment is unknown and the
+memory access is defined in a packed struct.  @var{is_gather_scatter} is true
+if the load/store is a gather or scatter.
 @end deftypefn
 
 @deftypefn {Target Hook} machine_mode TARGET_VECTORIZE_PREFERRED_SIMD_MODE 
(scalar_mode @var{mode})
diff --git a/gcc/target.def b/gcc/target.def
index 38903eb567a..273a2f2e6bb 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1918,17 +1918,21 @@ implementation approaches itself.",
  NULL)
 
 /* Return true if the target supports misaligned store/load of a
-   specific factor denoted in the third parameter.  The last parameter
-   is true if the access is defined in a packed struct.  */
+   specific factor denoted in the third parameter.  The second to the last
+   parameter is true if the access is defined in a packed struct and
+   the last parameter is true if the access is a gather/scatter. */
 DEFHOOK
 (support_vector_misalignment,
  "This hook should return true if the target supports misaligned vector\n\
 store/load of a specific factor denoted in the @var{misalignment}\n\
 parameter.  The vector store/load should be of machine mode @var{mode} and\n\
-the elements in the vectors should be of type @var{type}.  @var{is_packed}\n\
-parameter is true if the memory access is defined in a packed struct.",
+the elements in the vectors should be of type @var{type}.  The\n\
+@var{is_packed} parameter is true if the misalignment is unknown and the\n\
+memory access is defined in a packed struct.  @var{is_gather_scatter} is 
true\n\
+if the load/store is a gather or scatter.",
  bool,
- (machine_mode mode, const_tree type, int misalignment, bool is_packed),
+ (machine_mode mode, const_tree type, int misalignment, bool is_packed,
+  bool is_gather_scatter),
  default_builtin_support_vector_misalignment)
 
 /* Returns the preferred mode for SIMD operations for the specified
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index c79458e374e..e723bbbc4df 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -1556,6 +1556,8 @@ default_builtin_support_vector_misalignment (machine_mode 
mode,
                                             int misalignment
                                             ATTRIBUTE_UNUSED,
                                             bool is_packed
+                                            ATTRIBUTE_UNUSED,
+                                            bool is_gather_scatter
                                             ATTRIBUTE_UNUSED)
 {
   if (optab_handler (movmisalign_optab, mode) != CODE_FOR_nothing)
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index f16b58798c2..3fa20af0e11 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -114,7 +114,7 @@ extern bool default_builtin_vector_alignment_reachable 
(const_tree, bool);
 extern bool
 default_builtin_support_vector_misalignment (machine_mode mode,
                                             const_tree,
-                                            int, bool);
+                                            int, bool, bool);
 extern machine_mode default_preferred_simd_mode (scalar_mode mode);
 extern machine_mode default_split_reduction (machine_mode);
 extern unsigned int default_autovectorize_vector_modes (vector_modes *, bool);
diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index 5b2cb537438..019f0b6ca36 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -7490,7 +7490,7 @@ vect_supportable_dr_alignment (vec_info *vinfo, 
dr_vec_info *dr_info,
   if (misalignment == DR_MISALIGNMENT_UNKNOWN)
     is_packed = not_size_aligned (DR_REF (dr));
   if (targetm.vectorize.support_vector_misalignment (mode, type, misalignment,
-                                                    is_packed))
+                                                    is_packed, false))
     return dr_unaligned_supported;
 
   /* Unsupported.  */
-- 
2.50.0

Reply via email to