handled efficiently by scalar code. omp_max_vf calculates the
maximum number of bytes in a vector, when such a value is relevant
to loop optimization. */
- m_maximum_scale = estimated_poly_value (omp_max_vf ());
+ m_maximum_scale = estimated_poly_value (omp_max_vf (false));
m_maximum_scale = MAX (m_maximum_scale, MAX_FIXED_MODE_SIZE);
}
if (!simd_schedule || integer_zerop (chunk_size))
return chunk_size;
- poly_uint64 vf = omp_max_vf ();
+ poly_uint64 vf = omp_max_vf (false);
if (known_eq (vf, 1U))
return chunk_size;
return NULL_TREE;
}
-/* Return maximum possible vectorization factor for the target. */
+/* Return maximum possible vectorization factor for the target, or for
+ the OpenMP offload target if one exists. */
poly_uint64
-omp_max_vf (void)
+omp_max_vf (bool offload)
{
if (!optimize
|| optimize_debug
&& OPTION_SET_P (flag_tree_loop_vectorize)))
return 1;
+ if (ENABLE_OFFLOADING && offload)
+ {
+ for (const char *c = getenv ("OFFLOAD_TARGET_NAMES"); c;)
+ {
+ if (startswith (c, "amdgcn"))
+ return ordered_max (64, omp_max_vf (false));
+ else if ((c = strchr (c, ':')))
+ c++;
+ }
+ /* Otherwise, fall through to host VF. */
+ }
+
auto_vector_modes modes;
targetm.vectorize.autovectorize_vector_modes (&modes, true);
if (!modes.is_empty ())
struct omp_for_data_loop *loops);
extern gimple *omp_build_barrier (tree lhs);
extern tree find_combined_omp_for (tree *, int *, void *);
-extern poly_uint64 omp_max_vf (void);
+extern poly_uint64 omp_max_vf (bool);
extern int omp_max_simt_vf (void);
extern const char *omp_context_name_list_prop (tree);
extern void omp_construct_traits_to_codes (tree, int, enum tree_code *);
{
if (known_eq (sctx->max_vf, 0U))
{
- sctx->max_vf = sctx->is_simt ? omp_max_simt_vf () : omp_max_vf ();
+ sctx->max_vf = (sctx->is_simt ? omp_max_simt_vf ()
+ : omp_max_vf (omp_maybe_offloaded_ctx (ctx)));
if (maybe_gt (sctx->max_vf, 1U))
{
tree c = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),