@@ -6229,6 +6229,13 @@ equal to @code{word_mode}, because the vectorizer can do some
transformations even in absence of specialized @acronym{SIMD} hardware.
@end deftypefn
+@deftypefn {Target Hook} machine_mode TARGET_VECTORIZE_PREFERRED_SIMD_MODE_COMPLEX (complex_mode @var{mode})
+This hook should return the preferred mode for vectorizing complex
+mode @var{mode}. The default is
+equal to @code{word_mode}, because the vectorizer can do some
+transformations even in absence of specialized @acronym{SIMD} hardware.
+@end deftypefn
+
@deftypefn {Target Hook} machine_mode TARGET_VECTORIZE_SPLIT_REDUCTION (machine_mode)
This hook should return the preferred mode to split the final reduction
step on @var{mode} to. The reduction is then carried out reducing upper
@@ -6291,6 +6298,30 @@ requested mode, returning a mode with the same size as @var{vector_mode}
when @var{nunits} is zero. This is the correct behavior for most targets.
@end deftypefn
+@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_RELATED_MODE_COMPLEX (machine_mode @var{vector_mode}, complex_mode @var{element_mode}, poly_uint64 @var{nunits})
+If a piece of code is using vector mode @var{vector_mode} and also wants
+to operate on elements of mode @var{element_mode}, return the vector mode
+it should use for those elements. If @var{nunits} is nonzero, ensure that
+the mode has exactly @var{nunits} elements, otherwise pick whichever vector
+size pairs the most naturally with @var{vector_mode}. Return an empty
+@code{opt_machine_mode} if there is no supported vector mode with the
+required properties.
+
+There is no prescribed way of handling the case in which @var{nunits}
+is zero. One common choice is to pick a vector mode with the same size
+as @var{vector_mode}; this is the natural choice if the target has a
+fixed vector size. Another option is to choose a vector mode with the
+same number of elements as @var{vector_mode}; this is the natural choice
+if the target has a fixed number of elements. Alternatively, the hook
+might choose a middle ground, such as trying to keep the number of
+elements as similar as possible while applying maximum and minimum
+vector sizes.
+
+The default implementation uses @code{mode_for_vector} to find the
+requested mode, returning a mode with the same size as @var{vector_mode}
+when @var{nunits} is zero. This is the correct behavior for most targets.
+@end deftypefn
+
@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (machine_mode @var{mode})
Return the mode to use for a vector mask that holds one boolean
result for each element of vector mode @var{mode}. The returned mask mode
@@ -4195,12 +4195,16 @@ address; but often a machine-dependent strategy can generate better code.
@hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE
+@hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE_COMPLEX
+
@hook TARGET_VECTORIZE_SPLIT_REDUCTION
@hook TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
@hook TARGET_VECTORIZE_RELATED_MODE
+@hook TARGET_VECTORIZE_RELATED_MODE_COMPLEX
+
@hook TARGET_VECTORIZE_GET_MASK_MODE
@hook TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
@@ -6276,6 +6276,16 @@ init_emit_once (void)
targetm.gen_rtx_complex (mode, inner, inner);
}
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_COMPLEX_INT)
+ {
+ const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
+ }
+
+ FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_COMPLEX_FLOAT)
+ {
+ const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
+ }
+
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_BOOL)
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
@@ -142,6 +142,8 @@ vector_class (enum mode_class cl)
case MODE_UFRACT: return MODE_VECTOR_UFRACT;
case MODE_ACCUM: return MODE_VECTOR_ACCUM;
case MODE_UACCUM: return MODE_VECTOR_UACCUM;
+ case MODE_COMPLEX_INT: return MODE_VECTOR_COMPLEX_INT;
+ case MODE_COMPLEX_FLOAT: return MODE_VECTOR_COMPLEX_FLOAT;
default:
error ("no vector class for class %s", mode_class_names[cl]);
return MODE_RANDOM;
@@ -400,6 +402,8 @@ complete_mode (struct mode_data *m)
case MODE_VECTOR_UFRACT:
case MODE_VECTOR_ACCUM:
case MODE_VECTOR_UACCUM:
+ case MODE_VECTOR_COMPLEX_INT:
+ case MODE_VECTOR_COMPLEX_FLOAT:
/* Vector modes should have a component and a number of components. */
validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
if (m->component->precision != (unsigned int)-1)
@@ -462,6 +466,10 @@ make_complex_modes (enum mode_class cl,
if (m->boolean)
continue;
+ /* Skip already created mode */
+ if (m->complex)
+ continue;
+
m_len = strlen (m->name);
/* The leading "1 +" is in case we prepend a "C" below. */
buf = (char *) xmalloc (1 + m_len + 1);
@@ -3747,16 +3747,19 @@ match_pattern (optab_pattern *p, const char *name, const char *pat)
if (*p == 0
&& (! force_int || mode_class[i] == MODE_INT
|| mode_class[i] == MODE_COMPLEX_INT
+ || mode_class[i] == MODE_VECTOR_COMPLEX_INT
|| mode_class[i] == MODE_VECTOR_INT)
&& (! force_partial_int
|| mode_class[i] == MODE_INT
|| mode_class[i] == MODE_COMPLEX_INT
+ || mode_class[i] == MODE_VECTOR_COMPLEX_INT
|| mode_class[i] == MODE_PARTIAL_INT
|| mode_class[i] == MODE_VECTOR_INT)
&& (! force_float
|| mode_class[i] == MODE_FLOAT
|| mode_class[i] == MODE_DECIMAL_FLOAT
|| mode_class[i] == MODE_COMPLEX_FLOAT
+ || mode_class[i] == MODE_VECTOR_COMPLEX_FLOAT
|| mode_class[i] == MODE_VECTOR_FLOAT)
&& (! force_fixed
|| mode_class[i] == MODE_FRACT
@@ -110,6 +110,7 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
|| GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_INT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_INT)
/* Nonzero if MODE is a floating-point mode. */
@@ -117,17 +118,22 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)
-#define COMPLEX_INT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT)
+#define COMPLEX_INT_MODE_P(MODE) \
+ (GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_INT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT)
-#define COMPLEX_FLOAT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
+#define COMPLEX_FLOAT_MODE_P(MODE) \
+ (GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_FLOAT \
+ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
/* Nonzero if MODE is a complex mode. */
#define COMPLEX_MODE_P(MODE) \
(GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_INT \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
/* Nonzero if MODE is a vector mode. */
@@ -138,6 +144,8 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_INT \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_COMPLEX_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
/* Nonzero if MODE is a scalar integral mode. */
@@ -927,6 +935,9 @@ extern opt_machine_mode bitwise_mode_for_mode (machine_mode);
extern opt_machine_mode mode_for_vector (scalar_mode, poly_uint64);
extern opt_machine_mode related_vector_mode (machine_mode, scalar_mode,
poly_uint64 = 0);
+extern opt_machine_mode mode_for_vector (complex_mode, poly_uint64);
+extern opt_machine_mode related_vector_mode (machine_mode,
+ complex_mode, poly_uint64 = 0);
extern opt_machine_mode related_int_vector_mode (machine_mode);
/* A class for iterating through possible bitfield modes. */
@@ -32,9 +32,11 @@ along with GCC; see the file COPYING3. If not see
DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \
DEF_MODE_CLASS (MODE_VECTOR_BOOL), /* vectors of single bits */ \
DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \
+ DEF_MODE_CLASS (MODE_VECTOR_COMPLEX_INT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_FRACT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_ACCUM), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_UACCUM), /* SIMD vectors */ \
DEF_MODE_CLASS (MODE_VECTOR_FLOAT), \
+ DEF_MODE_CLASS (MODE_VECTOR_COMPLEX_FLOAT), \
DEF_MODE_CLASS (MODE_OPAQUE) /* opaque modes */
@@ -2653,6 +2653,10 @@ simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
+ /* FIXME */
+ if (VECTOR_MODE_P (mode) && COMPLEX_MODE_P (mode))
+ return NULL_RTX;
+
/* Make sure the constant is second. */
if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
&& swap_commutative_operands_p (op0, op1))
@@ -480,8 +480,8 @@ bitwise_type_for_mode (machine_mode mode)
elements of mode INNERMODE, if one exists. The returned mode can be
either an integer mode or a vector mode. */
-opt_machine_mode
-mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
+static opt_machine_mode
+mode_for_vector (machine_mode innermode, poly_uint64 nunits)
{
machine_mode mode;
@@ -496,8 +496,14 @@ mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
mode = MIN_MODE_VECTOR_ACCUM;
else if (SCALAR_UACCUM_MODE_P (innermode))
mode = MIN_MODE_VECTOR_UACCUM;
- else
+ else if (SCALAR_INT_MODE_P (innermode))
mode = MIN_MODE_VECTOR_INT;
+ else if (COMPLEX_FLOAT_MODE_P (innermode))
+ mode = MIN_MODE_VECTOR_COMPLEX_FLOAT;
+ else if (COMPLEX_INT_MODE_P (innermode))
+ mode = MIN_MODE_VECTOR_COMPLEX_INT;
+ else
+ gcc_unreachable ();
/* Only check the broader vector_mode_supported_any_target_p here.
We'll filter through target-specific availability and
@@ -511,7 +517,7 @@ mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
/* For integers, try mapping it to a same-sized scalar mode. */
if (GET_MODE_CLASS (innermode) == MODE_INT)
{
- poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
+ poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode).coeffs[0];
if (int_mode_for_size (nbits, 0).exists (&mode)
&& have_regs_of_mode[mode])
return mode;
@@ -520,6 +526,26 @@ mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
return opt_machine_mode ();
}
+/* Find a mode that is suitable for representing a vector with NUNITS
+ elements of scalar mode INNERMODE, if one exists. The returned mode
+ can be either an integer mode or a vector mode. */
+
+opt_machine_mode
+mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
+{
+ return mode_for_vector (machine_mode (innermode), nunits);
+}
+
+/* Find a mode that is suitable for representing a vector with NUNITS
+ elements of complex mode INNERMODE, if one exists. The returned mode
+ can be either an integer mode or a vector mode. */
+
+opt_machine_mode
+mode_for_vector (complex_mode innermode, poly_uint64 nunits)
+{
+ return mode_for_vector (machine_mode (innermode), nunits);
+}
+
/* If a piece of code is using vector mode VECTOR_MODE and also wants
to operate on elements of mode ELEMENT_MODE, return the vector mode
it should use for those elements. If NUNITS is nonzero, ensure that
@@ -540,6 +566,15 @@ related_vector_mode (machine_mode vector_mode, scalar_mode element_mode,
return targetm.vectorize.related_mode (vector_mode, element_mode, nunits);
}
+opt_machine_mode
+related_vector_mode (machine_mode vector_mode,
+ complex_mode element_mode, poly_uint64 nunits)
+{
+ gcc_assert (VECTOR_MODE_P (vector_mode));
+ return targetm.vectorize.related_mode_complex (vector_mode, element_mode,
+ nunits);
+}
+
/* If a piece of code is using vector mode VECTOR_MODE and also wants
to operate on integer vectors with the same element size and number
of elements, return the vector mode it should use. Return an empty
@@ -1943,6 +1943,18 @@ transformations even in absence of specialized @acronym{SIMD} hardware.",
(scalar_mode mode),
default_preferred_simd_mode)
+/* Returns the preferred mode for SIMD operations for the specified
+ complex mode. */
+DEFHOOK
+(preferred_simd_mode_complex,
+ "This hook should return the preferred mode for vectorizing complex\n\
+mode @var{mode}. The default is\n\
+equal to @code{word_mode}, because the vectorizer can do some\n\
+transformations even in absence of specialized @acronym{SIMD} hardware.",
+ machine_mode,
+ (complex_mode mode),
+ default_preferred_simd_mode_complex)
+
/* Returns the preferred mode for splitting SIMD reductions to. */
DEFHOOK
(split_reduction,
@@ -2017,6 +2029,33 @@ when @var{nunits} is zero. This is the correct behavior for most targets.",
(machine_mode vector_mode, scalar_mode element_mode, poly_uint64 nunits),
default_vectorize_related_mode)
+DEFHOOK
+(related_mode_complex,
+ "If a piece of code is using vector mode @var{vector_mode} and also wants\n\
+to operate on elements of mode @var{element_mode}, return the vector mode\n\
+it should use for those elements. If @var{nunits} is nonzero, ensure that\n\
+the mode has exactly @var{nunits} elements, otherwise pick whichever vector\n\
+size pairs the most naturally with @var{vector_mode}. Return an empty\n\
+@code{opt_machine_mode} if there is no supported vector mode with the\n\
+required properties.\n\
+\n\
+There is no prescribed way of handling the case in which @var{nunits}\n\
+is zero. One common choice is to pick a vector mode with the same size\n\
+as @var{vector_mode}; this is the natural choice if the target has a\n\
+fixed vector size. Another option is to choose a vector mode with the\n\
+same number of elements as @var{vector_mode}; this is the natural choice\n\
+if the target has a fixed number of elements. Alternatively, the hook\n\
+might choose a middle ground, such as trying to keep the number of\n\
+elements as similar as possible while applying maximum and minimum\n\
+vector sizes.\n\
+\n\
+The default implementation uses @code{mode_for_vector} to find the\n\
+requested mode, returning a mode with the same size as @var{vector_mode}\n\
+when @var{nunits} is zero. This is the correct behavior for most targets.",
+ opt_machine_mode,
+ (machine_mode vector_mode, complex_mode element_mode, poly_uint64 nunits),
+ default_vectorize_related_mode_complex)
+
/* Function to get a target mode for a vector mask. */
DEFHOOK
(get_mask_mode,
@@ -1532,6 +1532,15 @@ default_preferred_simd_mode (scalar_mode)
return word_mode;
}
+/* By default, only attempt to parallelize bitwise operations, and
+ possibly adds/subtracts using bit-twiddling. */
+
+machine_mode
+default_preferred_simd_mode_complex (complex_mode)
+{
+ return word_mode;
+}
+
/* By default, call gen_rtx_CONCAT. */
rtx
@@ -1733,6 +1742,26 @@ default_vectorize_related_mode (machine_mode vector_mode,
return opt_machine_mode ();
}
+
+/* The default implementation of TARGET_VECTORIZE_RELATED_MODE_COMPLEX. */
+
+opt_machine_mode
+default_vectorize_related_mode_complex (machine_mode vector_mode,
+ complex_mode element_mode,
+ poly_uint64 nunits)
+{
+ machine_mode result_mode;
+ if ((maybe_ne (nunits, 0U)
+ || multiple_p (GET_MODE_SIZE (vector_mode),
+ GET_MODE_SIZE (element_mode), &nunits))
+ && mode_for_vector (element_mode, nunits).exists (&result_mode)
+ && VECTOR_MODE_P (result_mode)
+ && targetm.vector_mode_supported_p (result_mode))
+ return result_mode;
+
+ return opt_machine_mode ();
+}
+
/* By default a vector of integers is used as a mask. */
opt_machine_mode
@@ -115,11 +115,15 @@ default_builtin_support_vector_misalignment (machine_mode mode,
const_tree,
int, bool);
extern machine_mode default_preferred_simd_mode (scalar_mode mode);
+extern machine_mode default_preferred_simd_mode_complex (complex_mode mode);
extern machine_mode default_split_reduction (machine_mode);
extern unsigned int default_autovectorize_vector_modes (vector_modes *, bool);
extern opt_machine_mode default_vectorize_related_mode (machine_mode,
scalar_mode,
poly_uint64);
+extern opt_machine_mode default_vectorize_related_mode_complex (machine_mode,
+ complex_mode,
+ poly_uint64);
extern opt_machine_mode default_get_mask_mode (machine_mode);
extern bool default_empty_mask_is_expensive (unsigned);
extern vector_costs *default_vectorize_create_costs (vec_info *, bool);
@@ -1363,6 +1363,10 @@ type_for_widest_vector_mode (tree type, optab op)
mode = MIN_MODE_VECTOR_ACCUM;
else if (SCALAR_UACCUM_MODE_P (inner_mode))
mode = MIN_MODE_VECTOR_UACCUM;
+ else if (COMPLEX_INT_MODE_P (inner_mode))
+ mode = MIN_MODE_VECTOR_COMPLEX_INT;
+ else if (COMPLEX_FLOAT_MODE_P (inner_mode))
+ mode = MIN_MODE_VECTOR_COMPLEX_FLOAT;
else if (inner_mode == BImode)
mode = MIN_MODE_VECTOR_BOOL;
else
@@ -12272,18 +12272,27 @@ get_related_vectype_for_scalar_type (machine_mode prevailing_mode,
tree scalar_type, poly_uint64 nunits)
{
tree orig_scalar_type = scalar_type;
- scalar_mode inner_mode;
+ scalar_mode scal_mode;
+ complex_mode cplx_mode;
+ machine_mode inner_mode;
machine_mode simd_mode;
tree vectype;
+ bool cplx = false;
- if ((!INTEGRAL_TYPE_P (scalar_type)
+ if (is_complex_int_mode (TYPE_MODE (scalar_type), &cplx_mode)
+ || is_complex_float_mode (TYPE_MODE (scalar_type), &cplx_mode))
+ cplx = true;
+
+ if ((!cplx && !INTEGRAL_TYPE_P (scalar_type)
&& !POINTER_TYPE_P (scalar_type)
&& !SCALAR_FLOAT_TYPE_P (scalar_type))
- || (!is_int_mode (TYPE_MODE (scalar_type), &inner_mode)
- && !is_float_mode (TYPE_MODE (scalar_type), &inner_mode)))
+ || (!cplx && !is_int_mode (TYPE_MODE (scalar_type), &scal_mode)
+ && !is_float_mode (TYPE_MODE (scalar_type), &scal_mode)))
return NULL_TREE;
- unsigned int nbytes = GET_MODE_SIZE (inner_mode);
+ unsigned int nbytes =
+ (cplx) ? GET_MODE_SIZE (cplx_mode) : GET_MODE_SIZE (scal_mode);
+ inner_mode = (cplx) ? machine_mode (cplx_mode) : machine_mode (scal_mode);
/* Interoperability between modes requires one to be a constant multiple
of the other, so that the number of vectors required for each operation
@@ -12301,19 +12310,20 @@ get_related_vectype_for_scalar_type (machine_mode prevailing_mode,
they support the proper result truncation/extension.
We also make sure to build vector types with INTEGER_TYPE
component type only. */
- if (INTEGRAL_TYPE_P (scalar_type)
- && (GET_MODE_BITSIZE (inner_mode) != TYPE_PRECISION (scalar_type)
+ if (!cplx && INTEGRAL_TYPE_P (scalar_type)
+ && (GET_MODE_BITSIZE (scal_mode) != TYPE_PRECISION (scalar_type)
|| TREE_CODE (scalar_type) != INTEGER_TYPE))
- scalar_type = build_nonstandard_integer_type (GET_MODE_BITSIZE (inner_mode),
- TYPE_UNSIGNED (scalar_type));
+ scalar_type =
+ build_nonstandard_integer_type (GET_MODE_BITSIZE (scal_mode),
+ TYPE_UNSIGNED (scalar_type));
/* We shouldn't end up building VECTOR_TYPEs of non-scalar components.
When the component mode passes the above test simply use a type
corresponding to that mode. The theory is that any use that
would cause problems with this will disable vectorization anyway. */
- else if (!SCALAR_FLOAT_TYPE_P (scalar_type)
+ else if (!cplx && !SCALAR_FLOAT_TYPE_P (scalar_type)
&& !INTEGRAL_TYPE_P (scalar_type))
- scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
+ scalar_type = lang_hooks.types.type_for_mode (scal_mode, 1);
/* We can't build a vector type of elements with alignment bigger than
their size. */
@@ -12331,7 +12341,10 @@ get_related_vectype_for_scalar_type (machine_mode prevailing_mode,
if (prevailing_mode == VOIDmode)
{
gcc_assert (known_eq (nunits, 0U));
- simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
+
+ simd_mode = (cplx)
+ ? targetm.vectorize.preferred_simd_mode_complex (cplx_mode)
+ : targetm.vectorize.preferred_simd_mode (scal_mode);
if (SCALAR_INT_MODE_P (simd_mode))
{
/* Traditional behavior is not to take the integer mode
@@ -12342,13 +12355,19 @@ get_related_vectype_for_scalar_type (machine_mode prevailing_mode,
Note that nunits == 1 is allowed in order to support single
element vector types. */
if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, &nunits)
- || !mode_for_vector (inner_mode, nunits).exists (&simd_mode))
+ || !((cplx)
+ ? mode_for_vector (cplx_mode, nunits).exists (&simd_mode)
+ : mode_for_vector (scal_mode, nunits).exists (&simd_mode)))
return NULL_TREE;
}
}
else if (SCALAR_INT_MODE_P (prevailing_mode)
- || !related_vector_mode (prevailing_mode,
- inner_mode, nunits).exists (&simd_mode))
+ || !((cplx) ? related_vector_mode (prevailing_mode,
+ cplx_mode, nunits)
+ .exists (&simd_mode)
+ : related_vector_mode (prevailing_mode,
+ scal_mode, nunits)
+ .exists (&simd_mode)))
{
/* Fall back to using mode_for_vector, mostly in the hope of being
able to use an integer mode. */
@@ -12356,7 +12375,8 @@ get_related_vectype_for_scalar_type (machine_mode prevailing_mode,
&& !multiple_p (GET_MODE_SIZE (prevailing_mode), nbytes, &nunits))
return NULL_TREE;
- if (!mode_for_vector (inner_mode, nunits).exists (&simd_mode))
+ if (!((cplx) ? mode_for_vector (cplx_mode, nunits).exists (&simd_mode)
+ : mode_for_vector (scal_mode, nunits).exists (&simd_mode)))
return NULL_TREE;
}
@@ -10115,6 +10115,8 @@ build_vector_type_for_mode (tree innertype, machine_mode mode)
case MODE_VECTOR_UFRACT:
case MODE_VECTOR_ACCUM:
case MODE_VECTOR_UACCUM:
+ case MODE_VECTOR_COMPLEX_INT:
+ case MODE_VECTOR_COMPLEX_FLOAT:
nunits = GET_MODE_NUNITS (mode);
break;