Daily bump.
[gcc.git] / gcc / stor-layout.c
index 9aada97b03813003d9667291be088776a19ee2d8..ee1cf55df90e2948df52f6d90b7e3d6741a4d399 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -393,6 +393,9 @@ int_mode_for_mode (machine_mode mode)
     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 ();
@@ -515,18 +518,43 @@ mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
   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.  */
+/* 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
+   the mode has exactly NUNITS elements, otherwise pick whichever vector
+   size pairs the most naturally with VECTOR_MODE; this may mean choosing
+   a mode with a different size and/or number of elements, depending on
+   what the target prefers.  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
-mode_for_int_vector (unsigned int int_bits, poly_uint64 nunits)
+related_vector_mode (machine_mode vector_mode, scalar_mode element_mode,
+                    poly_uint64 nunits)
 {
+  gcc_assert (VECTOR_MODE_P (vector_mode));
+  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;
-  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;
+  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 ();
 }
 
@@ -1316,7 +1344,8 @@ place_field (record_layout_info rli, tree field)
         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
@@ -1750,7 +1779,8 @@ finalize_record_size (record_layout_info rli)
 
   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
@@ -2552,10 +2582,19 @@ layout_type (tree 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;
       }