[AArch64 Testsuite] vld1_lane.c: Remove unused test data
[platform/upstream/gcc.git] / gcc / stor-layout.c
index 5b89f74..9757777 100644 (file)
@@ -1,5 +1,5 @@
 /* C-compiler utilities for types and variables storage layout
-   Copyright (C) 1987-2013 Free Software Foundation, Inc.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -22,14 +22,26 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "alias.h"
 #include "tree.h"
+#include "fold-const.h"
+#include "stor-layout.h"
+#include "stringpool.h"
+#include "varasm.h"
+#include "print-tree.h"
 #include "rtl.h"
 #include "tm_p.h"
 #include "flags.h"
 #include "function.h"
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "stmt.h"
 #include "expr.h"
 #include "diagnostic-core.h"
-#include "ggc.h"
 #include "target.h"
 #include "langhooks.h"
 #include "regs.h"
@@ -37,7 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-inline.h"
 #include "tree-dump.h"
-#include "gimple.h"
+#include "gimplify.h"
 
 /* Data type for the expressions representing sizes of data types.
    It is the first integer type laid out.  */
@@ -56,10 +68,8 @@ static tree self_referential_size (tree);
 static void finalize_record_size (record_layout_info);
 static void finalize_type_size (tree);
 static void place_union_field (record_layout_info, tree);
-#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
 static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
                             HOST_WIDE_INT, tree);
-#endif
 extern void debug_rli (record_layout_info);
 \f
 /* Show that REFERENCE_TYPES are internal and should use address_mode.
@@ -98,30 +108,18 @@ variable_size (tree size)
 /* An array of functions used for self-referential size computation.  */
 static GTY(()) vec<tree, va_gc> *size_functions;
 
-/* Look inside EXPR into simple arithmetic operations involving constants.
-   Return the outermost non-arithmetic or non-constant node.  */
+/* Return true if T is a self-referential component reference.  */
 
-static tree
-skip_simple_constant_arithmetic (tree expr)
+static bool
+self_referential_component_ref_p (tree t)
 {
-  while (true)
-    {
-      if (UNARY_CLASS_P (expr))
-       expr = TREE_OPERAND (expr, 0);
-      else if (BINARY_CLASS_P (expr))
-       {
-         if (TREE_CONSTANT (TREE_OPERAND (expr, 1)))
-           expr = TREE_OPERAND (expr, 0);
-         else if (TREE_CONSTANT (TREE_OPERAND (expr, 0)))
-           expr = TREE_OPERAND (expr, 1);
-         else
-           break;
-       }
-      else
-       break;
-    }
+  if (TREE_CODE (t) != COMPONENT_REF)
+    return false;
+
+  while (REFERENCE_CLASS_P (t))
+    t = TREE_OPERAND (t, 0);
 
-  return expr;
+  return (TREE_CODE (t) == PLACEHOLDER_EXPR);
 }
 
 /* Similar to copy_tree_r but do not copy component references involving
@@ -151,19 +149,10 @@ copy_self_referential_tree_r (tree *tp, int *walk_subtrees, void *data)
     }
 
   /* Default case: the component reference.  */
-  else if (code == COMPONENT_REF)
+  else if (self_referential_component_ref_p (*tp))
     {
-      tree inner;
-      for (inner = TREE_OPERAND (*tp, 0);
-          REFERENCE_CLASS_P (inner);
-          inner = TREE_OPERAND (inner, 0))
-       ;
-
-      if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
-       {
-         *walk_subtrees = 0;
-         return NULL_TREE;
-       }
+      *walk_subtrees = 0;
+      return NULL_TREE;
     }
 
   /* We're not supposed to have them in self-referential size trees
@@ -196,7 +185,7 @@ self_referential_size (tree size)
 
   /* Do not factor out simple operations.  */
   t = skip_simple_constant_arithmetic (size);
-  if (TREE_CODE (t) == CALL_EXPR)
+  if (TREE_CODE (t) == CALL_EXPR || self_referential_component_ref_p (t))
     return size;
 
   /* Collect the list of self-references in the expression.  */
@@ -234,12 +223,7 @@ self_referential_size (tree size)
       param_type = TREE_TYPE (ref);
       param_decl
        = build_decl (input_location, PARM_DECL, param_name, param_type);
-      if (targetm.calls.promote_prototypes (NULL_TREE)
-         && INTEGRAL_TYPE_P (param_type)
-         && TYPE_PRECISION (param_type) < TYPE_PRECISION (integer_type_node))
-       DECL_ARG_TYPE (param_decl) = integer_type_node;
-      else
-       DECL_ARG_TYPE (param_decl) = param_type;
+      DECL_ARG_TYPE (param_decl) = param_type;
       DECL_ARTIFICIAL (param_decl) = 1;
       TREE_READONLY (param_decl) = 1;
 
@@ -264,7 +248,7 @@ self_referential_size (tree size)
   fntype = build_function_type (return_type, param_type_list);
 
   /* Build the function declaration.  */
-  sprintf (buf, "SZ"HOST_WIDE_INT_PRINT_UNSIGNED, fnno++);
+  sprintf (buf, "SZ" HOST_WIDE_INT_PRINT_UNSIGNED, fnno++);
   fnname = get_file_function_name (buf);
   fndecl = build_decl (input_location, FUNCTION_DECL, fnname, fntype);
   for (t = param_decl_list; t; t = DECL_CHAIN (t))
@@ -316,10 +300,11 @@ finalize_size_functions (void)
 
   for (i = 0; size_functions && size_functions->iterate (i, &fndecl); i++)
     {
+      allocate_struct_function (fndecl, false);
+      set_cfun (NULL);
       dump_function (TDI_original, fndecl);
       gimplify_function_tree (fndecl);
-      dump_function (TDI_generic, fndecl);
-      cgraph_finalize_function (fndecl, false);
+      cgraph_node::finalize_function (fndecl, false);
     }
 
   vec_free (size_functions);
@@ -330,10 +315,11 @@ finalize_size_functions (void)
    it may have padding as well.  If LIMIT is nonzero, modes of wider
    than MAX_FIXED_MODE_SIZE will not be used.  */
 
-enum machine_mode
+machine_mode
 mode_for_size (unsigned int size, enum mode_class mclass, int limit)
 {
-  enum machine_mode mode;
+  machine_mode mode;
+  int i;
 
   if (limit && size > MAX_FIXED_MODE_SIZE)
     return BLKmode;
@@ -344,20 +330,26 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit)
     if (GET_MODE_PRECISION (mode) == size)
       return mode;
 
+  if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (int_n_data[i].bitsize == size
+         && int_n_enabled_p[i])
+       return int_n_data[i].m;
+
   return BLKmode;
 }
 
 /* Similar, except passed a tree node.  */
 
-enum machine_mode
+machine_mode
 mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
 {
   unsigned HOST_WIDE_INT uhwi;
   unsigned int ui;
 
-  if (!host_integerp (size, 1))
+  if (!tree_fits_uhwi_p (size))
     return BLKmode;
-  uhwi = tree_low_cst (size, 1);
+  uhwi = tree_to_uhwi (size);
   ui = uhwi;
   if (uhwi != ui)
     return BLKmode;
@@ -367,25 +359,36 @@ mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
 /* Similar, but never return BLKmode; return the narrowest mode that
    contains at least the requested number of value bits.  */
 
-enum machine_mode
+machine_mode
 smallest_mode_for_size (unsigned int size, enum mode_class mclass)
 {
-  enum machine_mode mode;
+  machine_mode mode = VOIDmode;
+  int i;
 
   /* Get the first mode which has at least this size, in the
      specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     if (GET_MODE_PRECISION (mode) >= size)
-      return mode;
+      break;
 
-  gcc_unreachable ();
+  if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (int_n_data[i].bitsize >= size
+         && int_n_data[i].bitsize < GET_MODE_PRECISION (mode)
+         && int_n_enabled_p[i])
+       mode = int_n_data[i].m;
+
+  if (mode == VOIDmode)
+    gcc_unreachable ();
+
+  return mode;
 }
 
 /* Find an integer mode of the exact same size, or BLKmode on failure.  */
 
-enum machine_mode
-int_mode_for_mode (enum machine_mode mode)
+machine_mode
+int_mode_for_mode (machine_mode mode)
 {
   switch (GET_MODE_CLASS (mode))
     {
@@ -407,6 +410,7 @@ int_mode_for_mode (enum machine_mode mode)
     case MODE_VECTOR_ACCUM:
     case MODE_VECTOR_UFRACT:
     case MODE_VECTOR_UACCUM:
+    case MODE_POINTER_BOUNDS:
       mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
       break;
 
@@ -424,14 +428,81 @@ int_mode_for_mode (enum machine_mode mode)
   return mode;
 }
 
+/* Find a mode that can be used for efficient bitwise operations on MODE.
+   Return BLKmode if no such mode exists.  */
+
+machine_mode
+bitwise_mode_for_mode (machine_mode mode)
+{
+  /* Quick exit if we already have a suitable mode.  */
+  unsigned int bitsize = GET_MODE_BITSIZE (mode);
+  if (SCALAR_INT_MODE_P (mode) && bitsize <= MAX_FIXED_MODE_SIZE)
+    return mode;
+
+  /* Reuse the sanity checks from int_mode_for_mode.  */
+  gcc_checking_assert ((int_mode_for_mode (mode), true));
+
+  /* Try to replace complex modes with complex modes.  In general we
+     expect both components to be processed independently, so we only
+     care whether there is a register for the inner mode.  */
+  if (COMPLEX_MODE_P (mode))
+    {
+      machine_mode trial = mode;
+      if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT)
+       trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false);
+      if (trial != BLKmode
+         && have_regs_of_mode[GET_MODE_INNER (trial)])
+       return trial;
+    }
+
+  /* Try to replace vector modes with vector modes.  Also try using vector
+     modes if an integer mode would be too big.  */
+  if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE)
+    {
+      machine_mode trial = mode;
+      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+       trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0);
+      if (trial != BLKmode
+         && have_regs_of_mode[trial]
+         && targetm.vector_mode_supported_p (trial))
+       return trial;
+    }
+
+  /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE.  */
+  return mode_for_size (bitsize, MODE_INT, true);
+}
+
+/* Find a type that can be used for efficient bitwise operations on MODE.
+   Return null if no such mode exists.  */
+
+tree
+bitwise_type_for_mode (machine_mode mode)
+{
+  mode = bitwise_mode_for_mode (mode);
+  if (mode == BLKmode)
+    return NULL_TREE;
+
+  unsigned int inner_size = GET_MODE_UNIT_BITSIZE (mode);
+  tree inner_type = build_nonstandard_integer_type (inner_size, true);
+
+  if (VECTOR_MODE_P (mode))
+    return build_vector_type_for_mode (inner_type, mode);
+
+  if (COMPLEX_MODE_P (mode))
+    return build_complex_type (inner_type);
+
+  gcc_checking_assert (GET_MODE_INNER (mode) == mode);
+  return inner_type;
+}
+
 /* Find a mode that is suitable for representing a vector with
    NUNITS elements of mode INNERMODE.  Returns BLKmode if there
    is no suitable mode.  */
 
-enum machine_mode
-mode_for_vector (enum machine_mode innermode, unsigned nunits)
+machine_mode
+mode_for_vector (machine_mode innermode, unsigned nunits)
 {
-  enum machine_mode mode;
+  machine_mode mode;
 
   /* First, look for a supported vector type.  */
   if (SCALAR_FLOAT_MODE_P (innermode))
@@ -472,7 +543,7 @@ mode_for_vector (enum machine_mode innermode, unsigned nunits)
    BIGGEST_ALIGNMENT.  */
 
 unsigned int
-get_mode_alignment (enum machine_mode mode)
+get_mode_alignment (machine_mode mode)
 {
   return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
 }
@@ -480,7 +551,7 @@ get_mode_alignment (enum machine_mode mode)
 /* Return the natural mode of an array, given that it is SIZE bytes in
    total and has elements of type ELEM_TYPE.  */
 
-static enum machine_mode
+static machine_mode
 mode_for_array (tree elem_type, tree size)
 {
   tree elem_size;
@@ -493,10 +564,10 @@ mode_for_array (tree elem_type, tree size)
     return TYPE_MODE (elem_type);
 
   limit_p = true;
-  if (host_integerp (size, 1) && host_integerp (elem_size, 1))
+  if (tree_fits_uhwi_p (size) && tree_fits_uhwi_p (elem_size))
     {
-      int_size = tree_low_cst (size, 1);
-      int_elem_size = tree_low_cst (elem_size, 1);
+      int_size = tree_to_uhwi (size);
+      int_elem_size = tree_to_uhwi (elem_size);
       if (int_elem_size > 0
          && int_size % int_elem_size == 0
          && targetm.array_mode_supported_p (TYPE_MODE (elem_type),
@@ -600,11 +671,9 @@ layout_decl (tree decl, unsigned int known_align)
            {
              zero_bitfield = true;
              packed_p = false;
-#ifdef PCC_BITFIELD_TYPE_MATTERS
              if (PCC_BITFIELD_TYPE_MATTERS)
                do_type_align (type, decl);
              else
-#endif
                {
 #ifdef EMPTY_FIELD_BOUNDARY
                  if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
@@ -618,16 +687,12 @@ layout_decl (tree decl, unsigned int known_align)
 
          /* See if we can use an ordinary integer mode for a bit-field.
             Conditions are: a fixed size that is correct for another mode,
-            occupying a complete byte or bytes on proper boundary,
-            and not -fstrict-volatile-bitfields.  If the latter is set,
-            we unfortunately can't check TREE_THIS_VOLATILE, as a cast
-            may make a volatile object later.  */
+            occupying a complete byte or bytes on proper boundary.  */
          if (TYPE_SIZE (type) != 0
              && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
-             && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
-             && flag_strict_volatile_bitfields <= 0)
+             && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
            {
-             enum machine_mode xmode
+             machine_mode xmode
                = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
              unsigned int xalign = GET_MODE_ALIGNMENT (xmode);
 
@@ -972,7 +1037,6 @@ update_alignment_for_field (record_layout_info rli, tree field,
          rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
        }
     }
-#ifdef PCC_BITFIELD_TYPE_MATTERS
   else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
     {
       /* Named bit-fields cause the entire structure to have the
@@ -1015,7 +1079,6 @@ update_alignment_for_field (record_layout_info rli, tree field,
          user_align |= TYPE_USER_ALIGN (type);
        }
     }
-#endif
   else
     {
       rli->record_align = MAX (rli->record_align, desired_align);
@@ -1053,7 +1116,6 @@ place_union_field (record_layout_info rli, tree field)
                               DECL_SIZE_UNIT (field), rli->offset);
 }
 
-#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
 /* A bitfield of SIZE with a required access alignment of ALIGN is allocated
    at BYTE_OFFSET / BIT_OFFSET.  Return nonzero if the field would span more
    units of alignment than the underlying TYPE.  */
@@ -1067,10 +1129,8 @@ excess_unit_span (HOST_WIDE_INT byte_offset, HOST_WIDE_INT bit_offset,
 
   offset = offset % align;
   return ((offset + size + align - 1) / align
-         > ((unsigned HOST_WIDE_INT) tree_low_cst (TYPE_SIZE (type), 1)
-            / align));
+         > tree_to_uhwi (TYPE_SIZE (type)) / align);
 }
-#endif
 
 /* RLI contains information about the layout of a RECORD_TYPE.  FIELD
    is a FIELD_DECL to be added after those fields already present in
@@ -1127,14 +1187,14 @@ place_field (record_layout_info rli, tree field)
   /* Work out the known alignment so far.  Note that A & (-A) is the
      value of the least-significant bit in A that is one.  */
   if (! integer_zerop (rli->bitpos))
-    known_align = (tree_low_cst (rli->bitpos, 1)
-                  & - tree_low_cst (rli->bitpos, 1));
+    known_align = (tree_to_uhwi (rli->bitpos)
+                  & - tree_to_uhwi (rli->bitpos));
   else if (integer_zerop (rli->offset))
     known_align = 0;
-  else if (host_integerp (rli->offset, 1))
+  else if (tree_fits_uhwi_p (rli->offset))
     known_align = (BITS_PER_UNIT
-                  * (tree_low_cst (rli->offset, 1)
-                     & - tree_low_cst (rli->offset, 1)));
+                  * (tree_to_uhwi (rli->offset)
+                     & - tree_to_uhwi (rli->offset)));
   else
     known_align = rli->offset_align;
 
@@ -1197,7 +1257,6 @@ place_field (record_layout_info rli, tree field)
 
   /* Handle compatibility with PCC.  Note that if the record has any
      variable-sized fields, we need not worry about compatibility.  */
-#ifdef PCC_BITFIELD_TYPE_MATTERS
   if (PCC_BITFIELD_TYPE_MATTERS
       && ! targetm.ms_bitfield_layout_p (rli->t)
       && TREE_CODE (field) == FIELD_DECL
@@ -1208,15 +1267,15 @@ place_field (record_layout_info rli, tree field)
          || TYPE_ALIGN (type) <= BITS_PER_UNIT)
       && maximum_field_alignment == 0
       && ! integer_zerop (DECL_SIZE (field))
-      && host_integerp (DECL_SIZE (field), 1)
-      && host_integerp (rli->offset, 1)
-      && host_integerp (TYPE_SIZE (type), 1))
+      && tree_fits_uhwi_p (DECL_SIZE (field))
+      && tree_fits_uhwi_p (rli->offset)
+      && tree_fits_uhwi_p (TYPE_SIZE (type)))
     {
       unsigned int type_align = TYPE_ALIGN (type);
       tree dsize = DECL_SIZE (field);
-      HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
-      HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
-      HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
+      HOST_WIDE_INT field_size = tree_to_uhwi (dsize);
+      HOST_WIDE_INT offset = tree_to_uhwi (rli->offset);
+      HOST_WIDE_INT bit_offset = tree_to_shwi (rli->bitpos);
 
 #ifdef ADJUST_FIELD_ALIGN
       if (! TYPE_USER_ALIGN (type))
@@ -1242,7 +1301,6 @@ place_field (record_layout_info rli, tree field)
       if (! DECL_PACKED (field))
        TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
     }
-#endif
 
 #ifdef BITFIELD_NBYTES_LIMITED
   if (BITFIELD_NBYTES_LIMITED
@@ -1252,15 +1310,15 @@ place_field (record_layout_info rli, tree field)
       && DECL_BIT_FIELD_TYPE (field)
       && ! DECL_PACKED (field)
       && ! integer_zerop (DECL_SIZE (field))
-      && host_integerp (DECL_SIZE (field), 1)
-      && host_integerp (rli->offset, 1)
-      && host_integerp (TYPE_SIZE (type), 1))
+      && tree_fits_uhwi_p (DECL_SIZE (field))
+      && tree_fits_uhwi_p (rli->offset)
+      && tree_fits_uhwi_p (TYPE_SIZE (type)))
     {
       unsigned int type_align = TYPE_ALIGN (type);
       tree dsize = DECL_SIZE (field);
-      HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
-      HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
-      HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
+      HOST_WIDE_INT field_size = tree_to_uhwi (dsize);
+      HOST_WIDE_INT offset = tree_to_uhwi (rli->offset);
+      HOST_WIDE_INT bit_offset = tree_to_shwi (rli->bitpos);
 
 #ifdef ADJUST_FIELD_ALIGN
       if (! TYPE_USER_ALIGN (type))
@@ -1314,18 +1372,18 @@ place_field (record_layout_info rli, tree field)
          if (DECL_BIT_FIELD_TYPE (field)
              && !integer_zerop (DECL_SIZE (field))
              && !integer_zerop (DECL_SIZE (rli->prev_field))
-             && host_integerp (DECL_SIZE (rli->prev_field), 0)
-             && host_integerp (TYPE_SIZE (type), 0)
+             && tree_fits_shwi_p (DECL_SIZE (rli->prev_field))
+             && tree_fits_uhwi_p (TYPE_SIZE (type))
              && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)))
            {
              /* We're in the middle of a run of equal type size fields; make
                 sure we realign if we run out of bits.  (Not decl size,
                 type size!) */
-             HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
+             HOST_WIDE_INT bitsize = tree_to_uhwi (DECL_SIZE (field));
 
              if (rli->remaining_in_alignment < bitsize)
                {
-                 HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+                 HOST_WIDE_INT typesize = tree_to_uhwi (TYPE_SIZE (type));
 
                  /* out of bits; bump up to next 'word'.  */
                  rli->bitpos
@@ -1364,7 +1422,7 @@ place_field (record_layout_info rli, tree field)
 
              /* Cause a new bitfield to be captured, either this time (if
                 currently a bitfield) or next time we see one.  */
-             if (!DECL_BIT_FIELD_TYPE(field)
+             if (!DECL_BIT_FIELD_TYPE (field)
                  || integer_zerop (DECL_SIZE (field)))
                rli->prev_field = NULL;
            }
@@ -1397,13 +1455,13 @@ place_field (record_layout_info rli, tree field)
             until we see a bitfield (and come by here again) we just skip
             calculating it.  */
          if (DECL_SIZE (field) != NULL
-             && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 1)
-             && host_integerp (DECL_SIZE (field), 1))
+             && tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (field)))
+             && tree_fits_uhwi_p (DECL_SIZE (field)))
            {
              unsigned HOST_WIDE_INT bitsize
-               = tree_low_cst (DECL_SIZE (field), 1);
+               = tree_to_uhwi (DECL_SIZE (field));
              unsigned HOST_WIDE_INT typesize
-               = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
+               = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (field)));
 
              if (typesize < bitsize)
                rli->remaining_in_alignment = 0;
@@ -1431,18 +1489,22 @@ place_field (record_layout_info rli, tree field)
   DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
   SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
 
+  /* Evaluate nonconstant offsets only once, either now or as soon as safe.  */
+  if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST)
+    DECL_FIELD_OFFSET (field) = variable_size (DECL_FIELD_OFFSET (field));
+
   /* If this field ended up more aligned than we thought it would be (we
      approximate this by seeing if its position changed), lay out the field
      again; perhaps we can use an integral mode for it now.  */
   if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field)))
-    actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
-                   & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
+    actual_align = (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
+                   & - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)));
   else if (integer_zerop (DECL_FIELD_OFFSET (field)))
     actual_align = MAX (BIGGEST_ALIGNMENT, rli->record_align);
-  else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
+  else if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field)))
     actual_align = (BITS_PER_UNIT
-                  * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
-                     & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
+                  * (tree_to_uhwi (DECL_FIELD_OFFSET (field))
+                     & - tree_to_uhwi (DECL_FIELD_OFFSET (field))));
   else
     actual_align = DECL_OFFSET_ALIGN (field);
   /* ACTUAL_ALIGN is still the actual alignment *within the record* .
@@ -1590,7 +1652,7 @@ void
 compute_record_mode (tree type)
 {
   tree field;
-  enum machine_mode mode = VOIDmode;
+  machine_mode mode = VOIDmode;
 
   /* Most RECORD_TYPEs have BLKmode, so we start off assuming that.
      However, if possible, we use a mode that fits in a register
@@ -1598,7 +1660,7 @@ compute_record_mode (tree type)
      line.  */
   SET_TYPE_MODE (type, BLKmode);
 
-  if (! host_integerp (TYPE_SIZE (type), 1))
+  if (! tree_fits_uhwi_p (TYPE_SIZE (type)))
     return;
 
   /* A record which has any BLKmode members must itself be
@@ -1614,9 +1676,9 @@ compute_record_mode (tree type)
              && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field))
              && !(TYPE_SIZE (TREE_TYPE (field)) != 0
                   && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))))
-         || ! host_integerp (bit_position (field), 1)
+         || ! tree_fits_uhwi_p (bit_position (field))
          || DECL_SIZE (field) == 0
-         || ! host_integerp (DECL_SIZE (field), 1))
+         || ! tree_fits_uhwi_p (DECL_SIZE (field)))
        return;
 
       /* If this field is the whole struct, remember its mode so
@@ -1635,8 +1697,8 @@ compute_record_mode (tree type)
      matches the type's size.  This only applies to RECORD_TYPE.  This
      does not apply to unions.  */
   if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
-      && host_integerp (TYPE_SIZE (type), 1)
-      && GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type)))
+      && tree_fits_uhwi_p (TYPE_SIZE (type))
+      && GET_MODE_BITSIZE (mode) == tree_to_uhwi (TYPE_SIZE (type)))
     SET_TYPE_MODE (type, mode);
   else
     SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1));
@@ -1665,12 +1727,9 @@ finalize_type_size (tree type)
      However, where strict alignment is not required, avoid
      over-aligning structures, since most compilers do not do this
      alignment.  */
-
-  if (TYPE_MODE (type) != BLKmode && TYPE_MODE (type) != VOIDmode
-      && (STRICT_ALIGNMENT
-         || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
-             && TREE_CODE (type) != QUAL_UNION_TYPE
-             && TREE_CODE (type) != ARRAY_TYPE)))
+  if (TYPE_MODE (type) != BLKmode
+      && TYPE_MODE (type) != VOIDmode
+      && (STRICT_ALIGNMENT || !AGGREGATE_TYPE_P (type)))
     {
       unsigned mode_align = GET_MODE_ALIGNMENT (TYPE_MODE (type));
 
@@ -1723,8 +1782,9 @@ finalize_type_size (tree type)
       tree size = TYPE_SIZE (type);
       tree size_unit = TYPE_SIZE_UNIT (type);
       unsigned int align = TYPE_ALIGN (type);
+      unsigned int precision = TYPE_PRECISION (type);
       unsigned int user_align = TYPE_USER_ALIGN (type);
-      enum machine_mode mode = TYPE_MODE (type);
+      machine_mode mode = TYPE_MODE (type);
 
       /* Copy it into all variants.  */
       for (variant = TYPE_MAIN_VARIANT (type);
@@ -1733,8 +1793,13 @@ finalize_type_size (tree type)
        {
          TYPE_SIZE (variant) = size;
          TYPE_SIZE_UNIT (variant) = size_unit;
-         TYPE_ALIGN (variant) = align;
-         TYPE_USER_ALIGN (variant) = user_align;
+         unsigned valign = align;
+         if (TYPE_USER_ALIGN (variant))
+           valign = MAX (valign, TYPE_ALIGN (variant));
+         else
+           TYPE_USER_ALIGN (variant) = user_align;
+         TYPE_ALIGN (variant) = valign;
+         TYPE_PRECISION (variant) = precision;
          SET_TYPE_MODE (variant, mode);
        }
     }
@@ -1772,16 +1837,18 @@ static void
 finish_bitfield_representative (tree repr, tree field)
 {
   unsigned HOST_WIDE_INT bitsize, maxbitsize;
-  enum machine_mode mode;
+  machine_mode mode;
   tree nextf, size;
 
   size = size_diffop (DECL_FIELD_OFFSET (field),
                      DECL_FIELD_OFFSET (repr));
-  gcc_assert (host_integerp (size, 1));
-  bitsize = (tree_low_cst (size, 1) * BITS_PER_UNIT
-            + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
-            - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1)
-            + tree_low_cst (DECL_SIZE (field), 1));
+  while (TREE_CODE (size) == COMPOUND_EXPR)
+    size = TREE_OPERAND (size, 1);
+  gcc_assert (tree_fits_uhwi_p (size));
+  bitsize = (tree_to_uhwi (size) * BITS_PER_UNIT
+            + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
+            - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr))
+            + tree_to_uhwi (DECL_SIZE (field)));
 
   /* Round up bitsize to multiples of BITS_PER_UNIT.  */
   bitsize = (bitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1);
@@ -1799,11 +1866,11 @@ finish_bitfield_representative (tree repr, tree field)
        return;
       maxsize = size_diffop (DECL_FIELD_OFFSET (nextf),
                             DECL_FIELD_OFFSET (repr));
-      if (host_integerp (maxsize, 1))
+      if (tree_fits_uhwi_p (maxsize))
        {
-         maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
-                       + tree_low_cst (DECL_FIELD_BIT_OFFSET (nextf), 1)
-                       - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+         maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT
+                       + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (nextf))
+                       - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
          /* If the group ends within a bitfield nextf does not need to be
             aligned to BITS_PER_UNIT.  Thus round up.  */
          maxbitsize = (maxbitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1);
@@ -1820,9 +1887,9 @@ finish_bitfield_representative (tree repr, tree field)
         use bitsize as fallback for this case.  */
       tree maxsize = size_diffop (TYPE_SIZE_UNIT (DECL_CONTEXT (field)),
                                  DECL_FIELD_OFFSET (repr));
-      if (host_integerp (maxsize, 1))
-       maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
-                     - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+      if (tree_fits_uhwi_p (maxsize))
+       maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT
+                     - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
       else
        maxbitsize = bitsize;
     }
@@ -1874,10 +1941,10 @@ finish_bitfield_representative (tree repr, tree field)
 }
 
 /* Compute and set FIELD_DECLs for the underlying objects we should
-   use for bitfield access for the structure laid out with RLI.  */
+   use for bitfield access for the structure T.  */
 
-static void
-finish_bitfield_layout (record_layout_info rli)
+void
+finish_bitfield_layout (tree t)
 {
   tree field, prev;
   tree repr = NULL_TREE;
@@ -1886,10 +1953,10 @@ finish_bitfield_layout (record_layout_info rli)
      we could use the underlying type as hint for the representative
      if the bitfield would fit and the representative would not exceed
      the union in size.  */
-  if (TREE_CODE (rli->t) != RECORD_TYPE)
+  if (TREE_CODE (t) != RECORD_TYPE)
     return;
 
-  for (prev = NULL_TREE, field = TYPE_FIELDS (rli->t);
+  for (prev = NULL_TREE, field = TYPE_FIELDS (t);
        field; field = DECL_CHAIN (field))
     {
       if (TREE_CODE (field) != FIELD_DECL)
@@ -1933,8 +2000,8 @@ finish_bitfield_layout (record_layout_info rli)
             representative to be generated.  That will at most
             generate worse code but still maintain correctness with
             respect to the C++ memory model.  */
-         else if (!((host_integerp (DECL_FIELD_OFFSET (repr), 1)
-                     && host_integerp (DECL_FIELD_OFFSET (field), 1))
+         else if (!((tree_fits_uhwi_p (DECL_FIELD_OFFSET (repr))
+                     && tree_fits_uhwi_p (DECL_FIELD_OFFSET (field)))
                     || operand_equal_p (DECL_FIELD_OFFSET (repr),
                                         DECL_FIELD_OFFSET (field), 0)))
            {
@@ -1976,7 +2043,7 @@ finish_record_layout (record_layout_info rli, int free_p)
   finalize_type_size (rli->t);
 
   /* Compute bitfield representatives.  */
-  finish_bitfield_layout (rli);
+  finish_bitfield_layout (rli->t);
 
   /* Propagate TYPE_PACKED to variants.  With C++ templates,
      handle_packed_attribute is too early to do this.  */
@@ -2053,6 +2120,10 @@ layout_type (tree type)
   if (type == error_mark_node)
     return;
 
+  /* We don't want finalize_type_size to copy an alignment attribute to
+     variants that don't have it.  */
+  type = TYPE_MAIN_VARIANT (type);
+
   /* Do nothing if type has been laid out before.  */
   if (TYPE_SIZE (type))
     return;
@@ -2064,21 +2135,13 @@ layout_type (tree type)
         of the language-specific code.  */
       gcc_unreachable ();
 
-    case BOOLEAN_TYPE:  /* Used for Java, Pascal, and Chill.  */
-      if (TYPE_PRECISION (type) == 0)
-       TYPE_PRECISION (type) = 1; /* default to one byte/boolean.  */
-
-      /* ... fall through ...  */
-
+    case BOOLEAN_TYPE:
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
-      if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
-         && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
-       TYPE_UNSIGNED (type) = 1;
-
       SET_TYPE_MODE (type,
                     smallest_mode_for_size (TYPE_PRECISION (type), MODE_INT));
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+      /* Don't set TYPE_PRECISION here, as it may be set by a bitfield.  */
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
 
@@ -2147,11 +2210,16 @@ layout_type (tree type)
       SET_TYPE_MODE (type, VOIDmode);
       break;
 
+    case POINTER_BOUNDS_TYPE:
+      TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+      TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
+      break;
+
     case OFFSET_TYPE:
       TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
-      TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
-      /* A pointer might be MODE_PARTIAL_INT,
-        but ptrdiff_t must be integral.  */
+      TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE_UNITS);
+      /* A pointer might be MODE_PARTIAL_INT, but ptrdiff_t must be
+        integral, which may be an __intN.  */
       SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
       TYPE_PRECISION (type) = POINTER_SIZE;
       break;
@@ -2169,7 +2237,7 @@ layout_type (tree type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-       enum machine_mode mode = TYPE_MODE (type);
+       machine_mode mode = TYPE_MODE (type);
        if (TREE_CODE (type) == REFERENCE_TYPE && reference_types_internal)
          {
            addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
@@ -2179,7 +2247,7 @@ layout_type (tree type)
        TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
        TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
        TYPE_UNSIGNED (type) = 1;
-       TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
+       TYPE_PRECISION (type) = GET_MODE_PRECISION (mode);
       }
       break;
 
@@ -2216,13 +2284,10 @@ layout_type (tree type)
                    && TYPE_UNSIGNED (TREE_TYPE (lb))
                    && tree_int_cst_lt (ub, lb))
                  {
-                   unsigned prec = TYPE_PRECISION (TREE_TYPE (lb));
-                   lb = double_int_to_tree
-                          (ssizetype,
-                           tree_to_double_int (lb).sext (prec));
-                   ub = double_int_to_tree
-                          (ssizetype,
-                           tree_to_double_int (ub).sext (prec));
+                   lb = wide_int_to_tree (ssizetype,
+                                          offset_int::from (lb, SIGNED));
+                   ub = wide_int_to_tree (ssizetype,
+                                          offset_int::from (ub, SIGNED));
                  }
                length
                  = fold_convert (sizetype,
@@ -2255,13 +2320,17 @@ layout_type (tree type)
        /* Now round the alignment and size,
           using machine-dependent criteria if any.  */
 
+       unsigned align = TYPE_ALIGN (element);
+       if (TYPE_USER_ALIGN (type))
+         align = MAX (align, TYPE_ALIGN (type));
+       else
+         TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
 #ifdef ROUND_TYPE_ALIGN
-       TYPE_ALIGN (type)
-         = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);
+       align = ROUND_TYPE_ALIGN (type, align, BITS_PER_UNIT);
 #else
-       TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
+       align = MAX (align, BITS_PER_UNIT);
 #endif
-       TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
+       TYPE_ALIGN (type) = align;
        SET_TYPE_MODE (type, BLKmode);
        if (TYPE_SIZE (type) != 0
            && ! targetm.member_type_forces_blk (type, VOIDmode)
@@ -2329,9 +2398,7 @@ layout_type (tree type)
   /* Compute the final TYPE_SIZE, TYPE_ALIGN, etc. for TYPE.  For
      records and unions, finish_record_layout already called this
      function.  */
-  if (TREE_CODE (type) != RECORD_TYPE
-      && TREE_CODE (type) != UNION_TYPE
-      && TREE_CODE (type) != QUAL_UNION_TYPE)
+  if (!RECORD_OR_UNION_TYPE_P (type))
     finalize_type_size (type);
 
   /* We should never see alias sets on incomplete aggregates.  And we
@@ -2340,6 +2407,29 @@ layout_type (tree type)
     gcc_assert (!TYPE_ALIAS_SET_KNOWN_P (type));
 }
 
+/* Return the least alignment required for type TYPE.  */
+
+unsigned int
+min_align_of_type (tree type)
+{
+  unsigned int align = TYPE_ALIGN (type);
+  if (!TYPE_USER_ALIGN (type))
+    {
+      align = MIN (align, BIGGEST_ALIGNMENT);
+#ifdef BIGGEST_FIELD_ALIGNMENT
+      align = MIN (align, BIGGEST_FIELD_ALIGNMENT);
+#endif
+      unsigned int field_align = align;
+#ifdef ADJUST_FIELD_ALIGN
+      tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, type);
+      field_align = ADJUST_FIELD_ALIGN (field, field_align);
+      ggc_free (field);
+#endif
+      align = MIN (align, field_align);
+    }
+  return align / BITS_PER_UNIT;
+}
+
 /* Vector types need to re-check the target flags each time we report
    the machine mode.  We need to do this because attribute target can
    change the result of vector_mode_supported_p and have_regs_of_mode
@@ -2349,10 +2439,10 @@ layout_type (tree type)
    referenced by a function and re-compute the TYPE_MODE once, rather
    than make the TYPE_MODE macro call a function.  */
 
-enum machine_mode
+machine_mode
 vector_type_mode (const_tree t)
 {
-  enum machine_mode mode;
+  machine_mode mode;
 
   gcc_assert (TREE_CODE (t) == VECTOR_TYPE);
 
@@ -2361,7 +2451,7 @@ vector_type_mode (const_tree t)
       && (!targetm.vector_mode_supported_p (mode)
          || !have_regs_of_mode[mode]))
     {
-      enum machine_mode innermode = TREE_TYPE (t)->type_common.mode;
+      machine_mode innermode = TREE_TYPE (t)->type_common.mode;
 
       /* For integers, try mapping it to a same-sized scalar mode.  */
       if (GET_MODE_CLASS (innermode) == MODE_INT)
@@ -2474,7 +2564,24 @@ initialize_sizetypes (void)
   else if (strcmp (SIZETYPE, "short unsigned int") == 0)
     precision = SHORT_TYPE_SIZE;
   else
-    gcc_unreachable ();
+    {
+      int i;
+
+      precision = -1;
+      for (i = 0; i < NUM_INT_N_ENTS; i++)
+       if (int_n_enabled_p[i])
+         {
+           char name[50];
+           sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
+
+           if (strcmp (name, SIZETYPE) == 0)
+             {
+               precision = int_n_data[i].bitsize;
+             }
+         }
+      if (precision == -1)
+       gcc_unreachable ();
+    }
 
   bprecision
     = MIN (precision + BITS_PER_UNIT_LOG + 1, MAX_FIXED_MODE_SIZE);
@@ -2498,16 +2605,14 @@ initialize_sizetypes (void)
   TYPE_ALIGN (sizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (sizetype));
   TYPE_SIZE (sizetype) = bitsize_int (precision);
   TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (sizetype)));
-  set_min_and_max_values_for_integral_type (sizetype, precision,
-                                           /*is_unsigned=*/true);
+  set_min_and_max_values_for_integral_type (sizetype, precision, UNSIGNED);
 
   SET_TYPE_MODE (bitsizetype, smallest_mode_for_size (bprecision, MODE_INT));
   TYPE_ALIGN (bitsizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype));
   TYPE_SIZE (bitsizetype) = bitsize_int (bprecision);
   TYPE_SIZE_UNIT (bitsizetype)
     = size_int (GET_MODE_SIZE (TYPE_MODE (bitsizetype)));
-  set_min_and_max_values_for_integral_type (bitsizetype, bprecision,
-                                           /*is_unsigned=*/true);
+  set_min_and_max_values_for_integral_type (bitsizetype, bprecision, UNSIGNED);
 
   /* Create the signed variants of *sizetype.  */
   ssizetype = make_signed_type (TYPE_PRECISION (sizetype));
@@ -2527,52 +2632,18 @@ initialize_sizetypes (void)
 void
 set_min_and_max_values_for_integral_type (tree type,
                                          int precision,
-                                         bool is_unsigned)
+                                         signop sgn)
 {
-  tree min_value;
-  tree max_value;
-
-  if (is_unsigned)
-    {
-      min_value = build_int_cst (type, 0);
-      max_value
-       = build_int_cst_wide (type, precision - HOST_BITS_PER_WIDE_INT >= 0
-                             ? -1
-                             : ((HOST_WIDE_INT) 1 << precision) - 1,
-                             precision - HOST_BITS_PER_WIDE_INT > 0
-                             ? ((unsigned HOST_WIDE_INT) ~0
-                                >> (HOST_BITS_PER_WIDE_INT
-                                    - (precision - HOST_BITS_PER_WIDE_INT)))
-                             : 0);
-    }
-  else
-    {
-      min_value
-       = build_int_cst_wide (type,
-                             (precision - HOST_BITS_PER_WIDE_INT > 0
-                              ? 0
-                              : (HOST_WIDE_INT) (-1) << (precision - 1)),
-                             (((HOST_WIDE_INT) (-1)
-                               << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
-                                   ? precision - HOST_BITS_PER_WIDE_INT - 1
-                                   : 0))));
-      max_value
-       = build_int_cst_wide (type,
-                             (precision - HOST_BITS_PER_WIDE_INT > 0
-                              ? -1
-                              : (HOST_WIDE_INT)
-                                (((unsigned HOST_WIDE_INT) 1
-                                  << (precision - 1)) - 1)),
-                             (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
-                              ? (HOST_WIDE_INT)
-                                ((((unsigned HOST_WIDE_INT) 1
-                                   << (precision - HOST_BITS_PER_WIDE_INT
-                                       - 1))) - 1)
-                              : 0));
-    }
+  /* For bitfields with zero width we end up creating integer types
+     with zero precision.  Don't assign any minimum/maximum values
+     to those types, they don't have any valid value.  */
+  if (precision < 1)
+    return;
 
-  TYPE_MIN_VALUE (type) = min_value;
-  TYPE_MAX_VALUE (type) = max_value;
+  TYPE_MIN_VALUE (type)
+    = wide_int_to_tree (type, wi::min_value (precision, sgn));
+  TYPE_MAX_VALUE (type)
+    = wide_int_to_tree (type, wi::max_value (precision, sgn));
 }
 
 /* Set the extreme values of TYPE based on its precision in bits,
@@ -2585,14 +2656,7 @@ fixup_signed_type (tree type)
 {
   int precision = TYPE_PRECISION (type);
 
-  /* We can not represent properly constants greater then
-     HOST_BITS_PER_DOUBLE_INT, still we need the types
-     as they are used by i386 vector extensions and friends.  */
-  if (precision > HOST_BITS_PER_DOUBLE_INT)
-    precision = HOST_BITS_PER_DOUBLE_INT;
-
-  set_min_and_max_values_for_integral_type (type, precision,
-                                           /*is_unsigned=*/false);
+  set_min_and_max_values_for_integral_type (type, precision, SIGNED);
 
   /* Lay out the type: set its alignment, size, etc.  */
   layout_type (type);
@@ -2607,16 +2671,9 @@ fixup_unsigned_type (tree type)
 {
   int precision = TYPE_PRECISION (type);
 
-  /* We can not represent properly constants greater then
-     HOST_BITS_PER_DOUBLE_INT, still we need the types
-     as they are used by i386 vector extensions and friends.  */
-  if (precision > HOST_BITS_PER_DOUBLE_INT)
-    precision = HOST_BITS_PER_DOUBLE_INT;
-
   TYPE_UNSIGNED (type) = 1;
 
-  set_min_and_max_values_for_integral_type (type, precision,
-                                           /*is_unsigned=*/true);
+  set_min_and_max_values_for_integral_type (type, precision, UNSIGNED);
 
   /* Lay out the type: set its alignment, size, etc.  */
   layout_type (type);
@@ -2639,12 +2696,12 @@ bit_field_mode_iterator
                           HOST_WIDE_INT bitregion_start,
                           HOST_WIDE_INT bitregion_end,
                           unsigned int align, bool volatilep)
-: mode_ (GET_CLASS_NARROWEST_MODE (MODE_INT)), bitsize_ (bitsize),
-  bitpos_ (bitpos), bitregion_start_ (bitregion_start),
-  bitregion_end_ (bitregion_end), align_ (align),
-  volatilep_ (volatilep), count_ (0)
+: m_mode (GET_CLASS_NARROWEST_MODE (MODE_INT)), m_bitsize (bitsize),
+  m_bitpos (bitpos), m_bitregion_start (bitregion_start),
+  m_bitregion_end (bitregion_end), m_align (align),
+  m_volatilep (volatilep), m_count (0)
 {
-  if (!bitregion_end_)
+  if (!m_bitregion_end)
     {
       /* We can assume that any aligned chunk of ALIGN bits that overlaps
         the bitfield is mapped and won't trap, provided that ALIGN isn't
@@ -2654,8 +2711,8 @@ bit_field_mode_iterator
        = MIN (align, MAX (BIGGEST_ALIGNMENT, BITS_PER_WORD));
       if (bitsize <= 0)
        bitsize = 1;
-      bitregion_end_ = bitpos + bitsize + units - 1;
-      bitregion_end_ -= bitregion_end_ % units + 1;
+      m_bitregion_end = bitpos + bitsize + units - 1;
+      m_bitregion_end -= m_bitregion_end % units + 1;
     }
 }
 
@@ -2664,14 +2721,14 @@ bit_field_mode_iterator
    available, storing it in *OUT_MODE if so.  */
 
 bool
-bit_field_mode_iterator::next_mode (enum machine_mode *out_mode)
+bit_field_mode_iterator::next_mode (machine_mode *out_mode)
 {
-  for (; mode_ != VOIDmode; mode_ = GET_MODE_WIDER_MODE (mode_))
+  for (; m_mode != VOIDmode; m_mode = GET_MODE_WIDER_MODE (m_mode))
     {
-      unsigned int unit = GET_MODE_BITSIZE (mode_);
+      unsigned int unit = GET_MODE_BITSIZE (m_mode);
 
       /* Skip modes that don't have full precision.  */
-      if (unit != GET_MODE_PRECISION (mode_))
+      if (unit != GET_MODE_PRECISION (m_mode))
        continue;
 
       /* Stop if the mode is too wide to handle efficiently.  */
@@ -2680,31 +2737,31 @@ bit_field_mode_iterator::next_mode (enum machine_mode *out_mode)
 
       /* Don't deliver more than one multiword mode; the smallest one
         should be used.  */
-      if (count_ > 0 && unit > BITS_PER_WORD)
+      if (m_count > 0 && unit > BITS_PER_WORD)
        break;
 
       /* Skip modes that are too small.  */
-      unsigned HOST_WIDE_INT substart = (unsigned HOST_WIDE_INT) bitpos_ % unit;
-      unsigned HOST_WIDE_INT subend = substart + bitsize_;
+      unsigned HOST_WIDE_INT substart = (unsigned HOST_WIDE_INT) m_bitpos % unit;
+      unsigned HOST_WIDE_INT subend = substart + m_bitsize;
       if (subend > unit)
        continue;
 
       /* Stop if the mode goes outside the bitregion.  */
-      HOST_WIDE_INT start = bitpos_ - substart;
-      if (bitregion_start_ && start < bitregion_start_)
+      HOST_WIDE_INT start = m_bitpos - substart;
+      if (m_bitregion_start && start < m_bitregion_start)
        break;
       HOST_WIDE_INT end = start + unit;
-      if (end > bitregion_end_ + 1)
+      if (end > m_bitregion_end + 1)
        break;
 
       /* Stop if the mode requires too much alignment.  */
-      if (GET_MODE_ALIGNMENT (mode_) > align_
-         && SLOW_UNALIGNED_ACCESS (mode_, align_))
+      if (GET_MODE_ALIGNMENT (m_mode) > m_align
+         && SLOW_UNALIGNED_ACCESS (m_mode, m_align))
        break;
 
-      *out_mode = mode_;
-      mode_ = GET_MODE_WIDER_MODE (mode_);
-      count_++;
+      *out_mode = m_mode;
+      m_mode = GET_MODE_WIDER_MODE (m_mode);
+      m_count++;
       return true;
     }
   return false;
@@ -2716,7 +2773,7 @@ bit_field_mode_iterator::next_mode (enum machine_mode *out_mode)
 bool
 bit_field_mode_iterator::prefer_smaller_modes ()
 {
-  return (volatilep_
+  return (m_volatilep
          ? targetm.narrow_volatile_bitfield ()
          : !SLOW_BYTE_ACCESS);
 }
@@ -2746,17 +2803,17 @@ bit_field_mode_iterator::prefer_smaller_modes ()
    If VOLATILEP is true the narrow_volatile_bitfields target hook is used to
    decide which of the above modes should be used.  */
 
-enum machine_mode
+machine_mode
 get_best_mode (int bitsize, int bitpos,
               unsigned HOST_WIDE_INT bitregion_start,
               unsigned HOST_WIDE_INT bitregion_end,
               unsigned int align,
-              enum machine_mode largest_mode, bool volatilep)
+              machine_mode largest_mode, bool volatilep)
 {
   bit_field_mode_iterator iter (bitsize, bitpos, bitregion_start,
                                bitregion_end, align, volatilep);
-  enum machine_mode widest_mode = VOIDmode;
-  enum machine_mode mode;
+  machine_mode widest_mode = VOIDmode;
+  machine_mode mode;
   while (iter.next_mode (&mode)
         /* ??? For historical reasons, reject modes that would normally
            receive greater alignment, even if unaligned accesses are
@@ -2829,16 +2886,30 @@ get_best_mode (int bitsize, int bitpos,
    SIGN).  The returned constants are made to be usable in TARGET_MODE.  */
 
 void
-get_mode_bounds (enum machine_mode mode, int sign,
-                enum machine_mode target_mode,
+get_mode_bounds (machine_mode mode, int sign,
+                machine_mode target_mode,
                 rtx *mmin, rtx *mmax)
 {
-  unsigned size = GET_MODE_BITSIZE (mode);
+  unsigned size = GET_MODE_PRECISION (mode);
   unsigned HOST_WIDE_INT min_val, max_val;
 
   gcc_assert (size <= HOST_BITS_PER_WIDE_INT);
 
-  if (sign)
+  /* Special case BImode, which has values 0 and STORE_FLAG_VALUE.  */
+  if (mode == BImode)
+    {
+      if (STORE_FLAG_VALUE < 0)
+       {
+         min_val = STORE_FLAG_VALUE;
+         max_val = 0;
+       }
+      else
+       {
+         min_val = 0;
+         max_val = STORE_FLAG_VALUE;
+       }
+    }
+  else if (sign)
     {
       min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1));
       max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1;