/* C-compiler utilities for types and variables storage layout
- Copyright (C) 1987-2019 Free Software Foundation, Inc.
+ Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GCC.
case MODE_VECTOR_UACCUM:
return int_mode_for_size (GET_MODE_BITSIZE (mode), 0);
+ case MODE_OPAQUE:
+ return opt_scalar_int_mode ();
+
case MODE_RANDOM:
if (mode == BLKmode)
return opt_scalar_int_mode ();
return opt_machine_mode ();
}
-/* Return the mode for a vector that has NUNITS integer elements of
- INT_BITS bits each, if such a mode exists. The mode can be either
- an integer mode or a vector mode. */
-
-opt_machine_mode
-mode_for_int_vector (unsigned int int_bits, poly_uint64 nunits)
-{
- scalar_int_mode int_mode;
- machine_mode vec_mode;
- if (int_mode_for_size (int_bits, 0).exists (&int_mode)
- && mode_for_vector (int_mode, nunits).exists (&vec_mode))
- return vec_mode;
- return opt_machine_mode ();
-}
-
/* 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
return targetm.vectorize.related_mode (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
+ opt_machine_mode if there is no supported vector mode with the
+ required properties.
+
+ Unlike mode_for_vector. any returned mode is guaranteed to satisfy
+ both VECTOR_MODE_P and targetm.vector_mode_supported_p. */
+
+opt_machine_mode
+related_int_vector_mode (machine_mode vector_mode)
+{
+ gcc_assert (VECTOR_MODE_P (vector_mode));
+ scalar_int_mode int_mode;
+ if (int_mode_for_mode (GET_MODE_INNER (vector_mode)).exists (&int_mode))
+ return related_vector_mode (vector_mode, int_mode,
+ GET_MODE_NUNITS (vector_mode));
+ return opt_machine_mode ();
+}
+
/* Return the alignment of MODE. This will be bounded by 1 and
BIGGEST_ALIGNMENT. */
Bump the cumulative size to multiple of field alignment. */
if (!targetm.ms_bitfield_layout_p (rli->t)
- && DECL_SOURCE_LOCATION (field) != BUILTINS_LOCATION)
+ && DECL_SOURCE_LOCATION (field) != BUILTINS_LOCATION
+ && !TYPE_ARTIFICIAL (rli->t))
warning (OPT_Wpadded, "padding struct to align %q+D", field);
/* If the alignment is still within offset_align, just align
if (TREE_CONSTANT (unpadded_size)
&& simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0
- && input_location != BUILTINS_LOCATION)
+ && input_location != BUILTINS_LOCATION
+ && !TYPE_ARTIFICIAL (rli->t))
warning (OPT_Wpadded, "padding struct size to alignment boundary");
if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
/* If TYPE_SIZE_UNIT overflowed, then it is certainly larger than
TYPE_ALIGN_UNIT. */
&& !TREE_OVERFLOW (TYPE_SIZE_UNIT (element))
- && !integer_zerop (TYPE_SIZE_UNIT (element))
- && compare_tree_int (TYPE_SIZE_UNIT (element),
- TYPE_ALIGN_UNIT (element)) < 0)
- error ("alignment of array elements is greater than element size");
+ && !integer_zerop (TYPE_SIZE_UNIT (element)))
+ {
+ if (compare_tree_int (TYPE_SIZE_UNIT (element),
+ TYPE_ALIGN_UNIT (element)) < 0)
+ error ("alignment of array elements is greater than "
+ "element size");
+ else if (TYPE_ALIGN_UNIT (element) > 1
+ && (wi::zext (wi::to_wide (TYPE_SIZE_UNIT (element)),
+ ffs_hwi (TYPE_ALIGN_UNIT (element)) - 1)
+ != 0))
+ error ("size of array element is not a multiple of its "
+ "alignment");
+ }
break;
}