" /* Patterns that are used by optabs that are enabled for this target. */\n"
" bool pat_enable[NUM_OPTAB_PATTERNS];\n"
"\n"
- " /* Cache if the target supports vec_gather_load for at least one vector\n"
- " mode. */\n"
- " bool supports_vec_gather_load;\n"
- " bool supports_vec_gather_load_cached;\n"
- " bool supports_vec_scatter_store;\n"
- " bool supports_vec_scatter_store_cached;\n"
+ " /* Index VOIDmode caches if the target supports vec_gather_load for any\n"
+ " vector mode. Every other index X caches specifically for mode X.\n"
+ " 1 means yes, -1 means no. */\n"
+ " signed char supports_vec_gather_load[NUM_MACHINE_MODES];\n"
+ " signed char supports_vec_scatter_store[NUM_MACHINE_MODES];\n"
"};\n"
"extern void init_all_optabs (struct target_optabs *);\n"
"\n"
return cheap[speed_p];
}
-/* Return true if vector conversion optab OP supports at least one mode,
- given that the second mode is always an integer vector. */
+/* If MODE is not VOIDmode, return true if vector conversion optab OP supports
+ that mode, given that the second mode is always an integer vector.
+ If MODE is VOIDmode, return true if OP supports any vector mode. */
static bool
-supports_vec_convert_optab_p (optab op)
+supports_vec_convert_optab_p (optab op, machine_mode mode)
{
- for (int i = 0; i < NUM_MACHINE_MODES; ++i)
+ int start = mode == VOIDmode ? 0 : mode;
+ int end = mode == VOIDmode ? MAX_MACHINE_MODE : mode;
+ for (int i = start; i <= end; ++i)
if (VECTOR_MODE_P ((machine_mode) i))
for (int j = MIN_MODE_VECTOR_INT; j < MAX_MODE_VECTOR_INT; ++j)
if (convert_optab_handler (op, (machine_mode) i,
return false;
}
-/* Return true if vec_gather_load is available for at least one vector
- mode. */
+/* If MODE is not VOIDmode, return true if vec_gather_load is available for
+ that mode. If MODE is VOIDmode, return true if gather_load is available
+ for at least one vector mode. */
bool
-supports_vec_gather_load_p ()
+supports_vec_gather_load_p (machine_mode mode)
{
- if (this_fn_optabs->supports_vec_gather_load_cached)
- return this_fn_optabs->supports_vec_gather_load;
+ if (!this_fn_optabs->supports_vec_gather_load[mode])
+ this_fn_optabs->supports_vec_gather_load[mode]
+ = (supports_vec_convert_optab_p (gather_load_optab, mode)
+ || supports_vec_convert_optab_p (mask_gather_load_optab, mode)
+ ? 1 : -1);
- this_fn_optabs->supports_vec_gather_load_cached = true;
-
- this_fn_optabs->supports_vec_gather_load
- = (supports_vec_convert_optab_p (gather_load_optab)
- || supports_vec_convert_optab_p (mask_gather_load_optab));
-
- return this_fn_optabs->supports_vec_gather_load;
+ return this_fn_optabs->supports_vec_gather_load[mode] > 0;
}
-/* Return true if vec_scatter_store is available for at least one vector
- mode. */
+/* If MODE is not VOIDmode, return true if vec_scatter_store is available for
+ that mode. If MODE is VOIDmode, return true if scatter_store is available
+ for at least one vector mode. */
bool
-supports_vec_scatter_store_p ()
+supports_vec_scatter_store_p (machine_mode mode)
{
- if (this_fn_optabs->supports_vec_scatter_store_cached)
- return this_fn_optabs->supports_vec_scatter_store;
-
- this_fn_optabs->supports_vec_scatter_store_cached = true;
-
- this_fn_optabs->supports_vec_scatter_store
- = (supports_vec_convert_optab_p (scatter_store_optab)
- || supports_vec_convert_optab_p (mask_scatter_store_optab));
+ if (!this_fn_optabs->supports_vec_scatter_store[mode])
+ this_fn_optabs->supports_vec_scatter_store[mode]
+ = (supports_vec_convert_optab_p (scatter_store_optab, mode)
+ || supports_vec_convert_optab_p (mask_scatter_store_optab, mode)
+ ? 1 : -1);
- return this_fn_optabs->supports_vec_scatter_store;
+ return this_fn_optabs->supports_vec_scatter_store[mode] > 0;
}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp-simd -msve-vector-bits=256 -fno-vect-cost-model" } */
+
+#include <stdint.h>
+
+void
+foo (uint64_t *restrict x, uint64_t *restrict y, uint64_t *restrict index)
+{
+#pragma omp for simd simdlen(2)
+ for (int i = 0; i < 128; ++i)
+ x[i] += y[index[i]];
+}
+
+/* { dg-final { scan-assembler-times {\tldr\td[0-9]+, \[x[0-9]+, x[0-9]+, lsl #?3\]} 2 } } */
+/* { dg-final { scan-assembler-not {\tshl\tv[0-9]+\.2d,} } } */
+/* { dg-final { scan-assembler-not {\tumov\t} } } */
+/* { dg-final { scan-assembler {\tadd\tv[0-9]+\.2d,} } } */
+/* { dg-final { scan-assembler {\tstr\tq[0-9]+,} } } */