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);
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;
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
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);
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;
}
return default_builtin_support_vector_misalignment (mode, type, misalignment,
- is_packed);
+ is_packed,
+ is_gather_scatter);
}
static void
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
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;
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
/* 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. */
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)
+ {
+ if (TARGET_ALTIVEC && is_packed)
+ return false;
+ else
+ return true;
+ }
+
if (TARGET_EFFICIENT_UNALIGNED_VSX)
return true;
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
@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})
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
int misalignment
ATTRIBUTE_UNUSED,
bool is_packed
+ ATTRIBUTE_UNUSED,
+ bool is_gather_scatter
ATTRIBUTE_UNUSED)
{
if (optab_handler (movmisalign_optab, mode) != CODE_FOR_nothing)
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);
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. */