Re-factor tree.h - Part 1.
[platform/upstream/gcc.git] / gcc / builtins.c
index 72e2591..7a04664 100644 (file)
@@ -1,7 +1,5 @@
 /* Expand builtin functions.
-   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-   2012 Free Software Foundation, Inc.
+   Copyright (C) 1988-2013 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -45,16 +43,15 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "langhooks.h"
 #include "basic-block.h"
-#include "tree-mudflap.h"
-#include "tree-flow.h"
+#include "tree-ssanames.h"
+#include "tree-dfa.h"
 #include "value-prof.h"
 #include "diagnostic-core.h"
 #include "builtins.h"
+#include "ubsan.h"
+#include "cilk.h"
 
 
-#ifndef PAD_VARARGS_DOWN
-#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
-#endif
 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
 
 struct target_builtins default_target_builtins;
@@ -63,7 +60,7 @@ struct target_builtins *this_target_builtins = &default_target_builtins;
 #endif
 
 /* Define the names of the builtin function types and codes.  */
-const char *const built_in_class_names[4]
+const char *const built_in_class_names[BUILT_IN_LAST]
   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
 
 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
@@ -77,6 +74,9 @@ const char * built_in_names[(int) END_BUILTINS] =
    initialized to NULL_TREE.  */
 builtin_info_type builtin_info;
 
+/* Non-zero if __builtin_constant_p should be folded right away.  */
+bool force_folding_builtin_constant_p;
+
 static const char *c_getstr (tree);
 static rtx c_readstr (const char *, enum machine_mode);
 static int target_char_cast (tree, char *);
@@ -236,6 +236,10 @@ is_builtin_name (const char *name)
     return true;
   if (strncmp (name, "__atomic_", 9) == 0)
     return true;
+  if (flag_enable_cilkplus 
+      && (!strcmp (name, "__cilkrts_detach")   
+         || !strcmp (name, "__cilkrts_pop_frame")))
+    return true;
   return false;
 }
 
@@ -248,6 +252,30 @@ is_builtin_fn (tree decl)
   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
 }
 
+/* By default we assume that c99 functions are present at the runtime,
+   but sincos is not.  */
+bool
+default_libc_has_function (enum function_class fn_class)
+{
+  if (fn_class == function_c94
+      || fn_class == function_c99_misc
+      || fn_class == function_c99_math_complex)
+    return true;
+
+  return false;
+}
+
+bool
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
+bool
+no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+{
+  return false;
+}
 
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
@@ -263,24 +291,31 @@ called_as_built_in (tree node)
   return is_builtin_name (name);
 }
 
-/* Compute values M and N such that M divides (address of EXP - N) and
-   such that N < M.  Store N in *BITPOSP and return M.
+/* Compute values M and N such that M divides (address of EXP - N) and such
+   that N < M.  If these numbers can be determined, store M in alignp and N in
+   *BITPOSP and return true.  Otherwise return false and store BITS_PER_UNIT to
+   *alignp and any bit-offset to *bitposp.
 
    Note that the address (and thus the alignment) computed here is based
    on the address to which a symbol resolves, whereas DECL_ALIGN is based
    on the address at which an object is actually located.  These two
    addresses are not always the same.  For example, on ARM targets,
    the address &foo of a Thumb function foo() has the lowest bit set,
-   whereas foo() itself starts on an even address.  */
+   whereas foo() itself starts on an even address.
 
-unsigned int
-get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
+   If ADDR_P is true we are taking the address of the memory reference EXP
+   and thus cannot rely on the access taking place.  */
+
+static bool
+get_object_alignment_2 (tree exp, unsigned int *alignp,
+                       unsigned HOST_WIDE_INT *bitposp, bool addr_p)
 {
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   enum machine_mode mode;
   int unsignedp, volatilep;
-  unsigned int align, inner;
+  unsigned int align = BITS_PER_UNIT;
+  bool known_alignment = false;
 
   /* Get the innermost object and the constant (bitpos) and possibly
      variable (offset) offset of the access.  */
@@ -289,40 +324,45 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
 
   /* Extract alignment information from the innermost object and
      possibly adjust bitpos and offset.  */
-  if (TREE_CODE (exp) == CONST_DECL)
-    exp = DECL_INITIAL (exp);
-  if (DECL_P (exp)
-      && TREE_CODE (exp) != LABEL_DECL)
-    {
-      if (TREE_CODE (exp) == FUNCTION_DECL)
-       {
-         /* Function addresses can encode extra information besides their
-            alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
-            allows the low bit to be used as a virtual bit, we know
-            that the address itself must be 2-byte aligned.  */
-         if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
-           align = 2 * BITS_PER_UNIT;
-         else
-           align = BITS_PER_UNIT;
-       }
-      else
-       align = DECL_ALIGN (exp);
+  if (TREE_CODE (exp) == FUNCTION_DECL)
+    {
+      /* Function addresses can encode extra information besides their
+        alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
+        allows the low bit to be used as a virtual bit, we know
+        that the address itself must be at least 2-byte aligned.  */
+      if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
+       align = 2 * BITS_PER_UNIT;
     }
-  else if (CONSTANT_CLASS_P (exp))
+  else if (TREE_CODE (exp) == LABEL_DECL)
+    ;
+  else if (TREE_CODE (exp) == CONST_DECL)
     {
+      /* The alignment of a CONST_DECL is determined by its initializer.  */
+      exp = DECL_INITIAL (exp);
       align = TYPE_ALIGN (TREE_TYPE (exp));
 #ifdef CONSTANT_ALIGNMENT
-      align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
+      if (CONSTANT_CLASS_P (exp))
+       align = (unsigned) CONSTANT_ALIGNMENT (exp, align);
 #endif
+      known_alignment = true;
+    }
+  else if (DECL_P (exp))
+    {
+      align = DECL_ALIGN (exp);
+      known_alignment = true;
     }
   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
-    align = TYPE_ALIGN (TREE_TYPE (exp));
-  else if (TREE_CODE (exp) == INDIRECT_REF)
-    align = TYPE_ALIGN (TREE_TYPE (exp));
-  else if (TREE_CODE (exp) == MEM_REF)
+    {
+      align = TYPE_ALIGN (TREE_TYPE (exp));
+    }
+  else if (TREE_CODE (exp) == INDIRECT_REF
+          || TREE_CODE (exp) == MEM_REF
+          || TREE_CODE (exp) == TARGET_MEM_REF)
     {
       tree addr = TREE_OPERAND (exp, 0);
-      struct ptr_info_def *pi;
+      unsigned ptr_align;
+      unsigned HOST_WIDE_INT ptr_bitpos;
+
       if (TREE_CODE (addr) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
        {
@@ -331,106 +371,84 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
          align *= BITS_PER_UNIT;
          addr = TREE_OPERAND (addr, 0);
        }
-      else
-       align = BITS_PER_UNIT;
-      if (TREE_CODE (addr) == SSA_NAME
-         && (pi = SSA_NAME_PTR_INFO (addr)))
-       {
-         bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
-         align = MAX (pi->align * BITS_PER_UNIT, align);
-       }
-      else if (TREE_CODE (addr) == ADDR_EXPR)
-       align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
-      bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
-    }
-  else if (TREE_CODE (exp) == TARGET_MEM_REF)
-    {
-      struct ptr_info_def *pi;
-      tree addr = TMR_BASE (exp);
-      if (TREE_CODE (addr) == BIT_AND_EXPR
-         && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
+
+      known_alignment
+       = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos);
+      align = MAX (ptr_align, align);
+
+      /* The alignment of the pointer operand in a TARGET_MEM_REF
+        has to take the variable offset parts into account.  */
+      if (TREE_CODE (exp) == TARGET_MEM_REF)
        {
-         align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
-                  & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
-         align *= BITS_PER_UNIT;
-         addr = TREE_OPERAND (addr, 0);
+         if (TMR_INDEX (exp))
+           {
+             unsigned HOST_WIDE_INT step = 1;
+             if (TMR_STEP (exp))
+               step = TREE_INT_CST_LOW (TMR_STEP (exp));
+             align = MIN (align, (step & -step) * BITS_PER_UNIT);
+           }
+         if (TMR_INDEX2 (exp))
+           align = BITS_PER_UNIT;
+         known_alignment = false;
        }
+
+      /* When EXP is an actual memory reference then we can use
+        TYPE_ALIGN of a pointer indirection to derive alignment.
+        Do so only if get_pointer_alignment_1 did not reveal absolute
+        alignment knowledge and if using that alignment would
+        improve the situation.  */
+      if (!addr_p && !known_alignment
+         && TYPE_ALIGN (TREE_TYPE (exp)) > align)
+       align = TYPE_ALIGN (TREE_TYPE (exp));
       else
-       align = BITS_PER_UNIT;
-      if (TREE_CODE (addr) == SSA_NAME
-         && (pi = SSA_NAME_PTR_INFO (addr)))
-       {
-         bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
-         align = MAX (pi->align * BITS_PER_UNIT, align);
-       }
-      else if (TREE_CODE (addr) == ADDR_EXPR)
-       align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
-      if (TMR_OFFSET (exp))
-       bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
-      if (TMR_INDEX (exp) && TMR_STEP (exp))
        {
-         unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
-         align = MIN (align, (step & -step) * BITS_PER_UNIT);
+         /* Else adjust bitpos accordingly.  */
+         bitpos += ptr_bitpos;
+         if (TREE_CODE (exp) == MEM_REF
+             || TREE_CODE (exp) == TARGET_MEM_REF)
+           bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
        }
-      else if (TMR_INDEX (exp))
-       align = BITS_PER_UNIT;
-      if (TMR_INDEX2 (exp))
-       align = BITS_PER_UNIT;
     }
-  else
-    align = BITS_PER_UNIT;
+  else if (TREE_CODE (exp) == STRING_CST)
+    {
+      /* STRING_CST are the only constant objects we allow to be not
+         wrapped inside a CONST_DECL.  */
+      align = TYPE_ALIGN (TREE_TYPE (exp));
+#ifdef CONSTANT_ALIGNMENT
+      if (CONSTANT_CLASS_P (exp))
+       align = (unsigned) CONSTANT_ALIGNMENT (exp, align);
+#endif
+      known_alignment = true;
+    }
 
   /* If there is a non-constant offset part extract the maximum
      alignment that can prevail.  */
-  inner = ~0U;
-  while (offset)
+  if (offset)
     {
-      tree next_offset;
-
-      if (TREE_CODE (offset) == PLUS_EXPR)
+      int trailing_zeros = tree_ctz (offset);
+      if (trailing_zeros < HOST_BITS_PER_INT)
        {
-         next_offset = TREE_OPERAND (offset, 0);
-         offset = TREE_OPERAND (offset, 1);
+         unsigned int inner = (1U << trailing_zeros) * BITS_PER_UNIT;
+         if (inner)
+           align = MIN (align, inner);
        }
-      else
-       next_offset = NULL;
-      if (host_integerp (offset, 1))
-       {
-         /* Any overflow in calculating offset_bits won't change
-            the alignment.  */
-         unsigned offset_bits
-           = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
-
-         if (offset_bits)
-           inner = MIN (inner, (offset_bits & -offset_bits));
-       }
-      else if (TREE_CODE (offset) == MULT_EXPR
-              && host_integerp (TREE_OPERAND (offset, 1), 1))
-       {
-         /* Any overflow in calculating offset_factor won't change
-            the alignment.  */
-         unsigned offset_factor
-           = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
-              * BITS_PER_UNIT);
-
-         if (offset_factor)
-           inner = MIN (inner, (offset_factor & -offset_factor));
-       }
-      else
-       {
-         inner = MIN (inner, BITS_PER_UNIT);
-         break;
-       }
-      offset = next_offset;
     }
 
-  /* Alignment is innermost object alignment adjusted by the constant
-     and non-constant offset parts.  */
-  align = MIN (align, inner);
-  bitpos = bitpos & (align - 1);
+  *alignp = align;
+  *bitposp = bitpos & (*alignp - 1);
+  return known_alignment;
+}
 
-  *bitposp = bitpos;
-  return align;
+/* For a memory reference expression EXP compute values M and N such that M
+   divides (&EXP - N) and such that N < M.  If these numbers can be determined,
+   store M in alignp and N in *BITPOSP and return true.  Otherwise return false
+   and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp.  */
+
+bool
+get_object_alignment_1 (tree exp, unsigned int *alignp,
+                       unsigned HOST_WIDE_INT *bitposp)
+{
+  return get_object_alignment_2 (exp, alignp, bitposp, false);
 }
 
 /* Return the alignment in bits of EXP, an object.  */
@@ -441,69 +459,63 @@ get_object_alignment (tree exp)
   unsigned HOST_WIDE_INT bitpos = 0;
   unsigned int align;
 
-  align = get_object_alignment_1 (exp, &bitpos);
+  get_object_alignment_1 (exp, &align, &bitpos);
 
   /* align and bitpos now specify known low bits of the pointer.
      ptr & (align - 1) == bitpos.  */
 
   if (bitpos != 0)
     align = (bitpos & -bitpos);
-
-  return align;
-}
-
-/* Return the alignment of object EXP, also considering its type when we do
-   not know of explicit misalignment.  Only handle MEM_REF and TARGET_MEM_REF.
-
-   ??? Note that, in the general case, the type of an expression is not kept
-   consistent with misalignment information by the front-end, for example when
-   taking the address of a member of a packed structure.  However, in most of
-   the cases, expressions have the alignment of their type so we optimistically
-   fall back to this alignment when we cannot compute a misalignment.  */
-
-unsigned int
-get_object_or_type_alignment (tree exp)
-{
-  unsigned HOST_WIDE_INT misalign;
-  unsigned int align = get_object_alignment_1 (exp, &misalign);
-
-  gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF);
-
-  if (misalign != 0)
-    align = (misalign & -misalign);
-  else
-    align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
-
   return align;
 }
 
-/* For a pointer valued expression EXP compute values M and N such that
-   M divides (EXP - N) and such that N < M.  Store N in *BITPOSP and return M.
+/* For a pointer valued expression EXP compute values M and N such that M
+   divides (EXP - N) and such that N < M.  If these numbers can be determined,
+   store M in alignp and N in *BITPOSP and return true.  Return false if
+   the results are just a conservative approximation.
 
-   If EXP is not a pointer, 0 is returned.  */
+   If EXP is not a pointer, false is returned too.  */
 
-unsigned int
-get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
+bool
+get_pointer_alignment_1 (tree exp, unsigned int *alignp,
+                        unsigned HOST_WIDE_INT *bitposp)
 {
   STRIP_NOPS (exp);
 
   if (TREE_CODE (exp) == ADDR_EXPR)
-    return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp);
+    return get_object_alignment_2 (TREE_OPERAND (exp, 0),
+                                  alignp, bitposp, true);
   else if (TREE_CODE (exp) == SSA_NAME
           && POINTER_TYPE_P (TREE_TYPE (exp)))
     {
+      unsigned int ptr_align, ptr_misalign;
       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
-      if (!pi)
+
+      if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign))
+       {
+         *bitposp = ptr_misalign * BITS_PER_UNIT;
+         *alignp = ptr_align * BITS_PER_UNIT;
+         /* We cannot really tell whether this result is an approximation.  */
+         return true;
+       }
+      else
        {
          *bitposp = 0;
-         return BITS_PER_UNIT;
+         *alignp = BITS_PER_UNIT;
+         return false;
        }
-      *bitposp = pi->misalign * BITS_PER_UNIT;
-      return pi->align * BITS_PER_UNIT;
+    }
+  else if (TREE_CODE (exp) == INTEGER_CST)
+    {
+      *alignp = BIGGEST_ALIGNMENT;
+      *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT)
+                 & (BIGGEST_ALIGNMENT - 1));
+      return true;
     }
 
   *bitposp = 0;
-  return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
+  *alignp = BITS_PER_UNIT;
+  return false;
 }
 
 /* Return the alignment in bits of EXP, a pointer valued expression.
@@ -518,8 +530,8 @@ get_pointer_alignment (tree exp)
 {
   unsigned HOST_WIDE_INT bitpos = 0;
   unsigned int align;
-  
-  align = get_pointer_alignment_1 (exp, &bitpos);
+
+  get_pointer_alignment_1 (exp, &align, &bitpos);
 
   /* align and bitpos now specify known low bits of the pointer.
      ptr & (align - 1) == bitpos.  */
@@ -677,7 +689,7 @@ c_readstr (const char *str, enum machine_mode mode)
          && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
        j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
       j *= BITS_PER_UNIT;
-      gcc_assert (j < 2 * HOST_BITS_PER_WIDE_INT);
+      gcc_assert (j < HOST_BITS_PER_DOUBLE_INT);
 
       if (ch)
        ch = (unsigned char) str[i];
@@ -808,7 +820,7 @@ expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
   tem = RETURN_ADDR_RTX (count, tem);
 #else
   tem = memory_address (Pmode,
-                       plus_constant (tem, GET_MODE_SIZE (Pmode)));
+                       plus_constant (Pmode, tem, GET_MODE_SIZE (Pmode)));
   tem = gen_frame_mem (Pmode, tem);
 #endif
   return tem;
@@ -843,14 +855,15 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
   set_mem_alias_set (mem, setjmp_alias_set);
   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
 
-  mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
+  mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
+                                          GET_MODE_SIZE (Pmode))),
   set_mem_alias_set (mem, setjmp_alias_set);
 
   emit_move_insn (validize_mem (mem),
                  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
 
   stack_save = gen_rtx_MEM (sa_mode,
-                           plus_constant (buf_addr,
+                           plus_constant (Pmode, buf_addr,
                                           2 * GET_MODE_SIZE (Pmode)));
   set_mem_alias_set (stack_save, setjmp_alias_set);
   emit_stack_save (SAVE_NONLOCAL, &stack_save);
@@ -866,14 +879,15 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
 }
 
 /* Construct the trailing part of a __builtin_setjmp call.  This is
-   also called directly by the SJLJ exception handling code.  */
+   also called directly by the SJLJ exception handling code.
+   If RECEIVER_LABEL is NULL, instead contruct a nonlocal goto handler.  */
 
 void
 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 {
   rtx chain;
 
-  /* Clobber the FP when we get here, so we have to make sure it's
+  /* Mark the FP as used when we get here, so we have to make sure it's
      marked as used by this function.  */
   emit_use (hard_frame_pointer_rtx);
 
@@ -888,17 +902,28 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 #ifdef HAVE_nonlocal_goto
   if (! HAVE_nonlocal_goto)
 #endif
-    {
-      emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
-      /* This might change the hard frame pointer in ways that aren't
-        apparent to early optimization passes, so force a clobber.  */
-      emit_clobber (hard_frame_pointer_rtx);
-    }
+    /* First adjust our frame pointer to its actual value.  It was
+       previously set to the start of the virtual area corresponding to
+       the stacked variables when we branched here and now needs to be
+       adjusted to the actual hardware fp value.
+
+       Assignments to virtual registers are converted by
+       instantiate_virtual_regs into the corresponding assignment
+       to the underlying register (fp in this case) that makes
+       the original assignment true.
+       So the following insn will actually be decrementing fp by
+       STARTING_FRAME_OFFSET.  */
+    emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
 
 #if !HARD_FRAME_POINTER_IS_ARG_POINTER
   if (fixed_regs[ARG_POINTER_REGNUM])
     {
 #ifdef ELIMINABLE_REGS
+      /* If the argument pointer can be eliminated in favor of the
+        frame pointer, we don't need to restore it.  We assume here
+        that if such an elimination is present, it can always be used.
+        This is the case on all known machines; if we don't make this
+        assumption, we do unnecessary saving on many machines.  */
       size_t i;
       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
 
@@ -919,7 +944,7 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 #endif
 
 #ifdef HAVE_builtin_setjmp_receiver
-  if (HAVE_builtin_setjmp_receiver)
+  if (receiver_label != NULL && HAVE_builtin_setjmp_receiver)
     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
   else
 #endif
@@ -932,7 +957,8 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
 
   /* We must not allow the code we just generated to be reordered by
      scheduling.  Specifically, the update of the frame pointer must
-     happen immediately, not later.  */
+     happen immediately, not later.  Similarly, we must block
+     (frame-related) register values to be used across this code.  */
   emit_insn (gen_blockage ());
 }
 
@@ -971,10 +997,10 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
 #endif
     {
       fp = gen_rtx_MEM (Pmode, buf_addr);
-      lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
+      lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
                                               GET_MODE_SIZE (Pmode)));
 
-      stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
+      stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, buf_addr,
                                                   2 * GET_MODE_SIZE (Pmode)));
       set_mem_alias_set (fp, setjmp_alias_set);
       set_mem_alias_set (lab, setjmp_alias_set);
@@ -1024,6 +1050,63 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
     }
 }
 
+static inline bool
+more_const_call_expr_args_p (const const_call_expr_arg_iterator *iter)
+{
+  return (iter->i < iter->n);
+}
+
+/* This function validates the types of a function call argument list
+   against a specified list of tree_codes.  If the last specifier is a 0,
+   that represents an ellipses, otherwise the last specifier must be a
+   VOID_TYPE.  */
+
+static bool
+validate_arglist (const_tree callexpr, ...)
+{
+  enum tree_code code;
+  bool res = 0;
+  va_list ap;
+  const_call_expr_arg_iterator iter;
+  const_tree arg;
+
+  va_start (ap, callexpr);
+  init_const_call_expr_arg_iterator (callexpr, &iter);
+
+  do
+    {
+      code = (enum tree_code) va_arg (ap, int);
+      switch (code)
+       {
+       case 0:
+         /* This signifies an ellipses, any further arguments are all ok.  */
+         res = true;
+         goto end;
+       case VOID_TYPE:
+         /* This signifies an endlink, if no arguments remain, return
+            true, otherwise return false.  */
+         res = !more_const_call_expr_args_p (&iter);
+         goto end;
+       default:
+         /* If no parameters remain or the parameter's code does not
+            match the specified code, return false.  Otherwise continue
+            checking any remaining arguments.  */
+         arg = next_const_call_expr_arg (&iter);
+         if (!validate_arg (arg, code))
+           goto end;
+         break;
+       }
+    }
+  while (1);
+
+  /* We need gotos here since we can only have one VA_CLOSE in a
+     function.  */
+ end: ;
+  va_end (ap);
+
+  return res;
+}
+
 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
    and the address of the save area.  */
 
@@ -1048,7 +1131,8 @@ expand_builtin_nonlocal_goto (tree exp)
   r_save_area = copy_to_reg (r_save_area);
   r_fp = gen_rtx_MEM (Pmode, r_save_area);
   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
-                     plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
+                     plus_constant (Pmode, r_save_area,
+                                    GET_MODE_SIZE (Pmode)));
 
   crtl->has_nonlocal_goto = 1;
 
@@ -1118,7 +1202,8 @@ expand_builtin_update_setjmp_buf (rtx buf_addr)
     = gen_rtx_MEM (sa_mode,
                   memory_address
                   (sa_mode,
-                   plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
+                   plus_constant (Pmode, buf_addr,
+                                  2 * GET_MODE_SIZE (Pmode))));
 
   emit_stack_save (SAVE_NONLOCAL, &stack_save);
 }
@@ -1213,7 +1298,6 @@ get_memory_rtx (tree exp, tree len)
 {
   tree orig_exp = exp;
   rtx addr, mem;
-  HOST_WIDE_INT off;
 
   /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
      from its expression, for expr->a.b only <variable>.a.b is recorded.  */
@@ -1224,120 +1308,38 @@ get_memory_rtx (tree exp, tree len)
   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
 
   /* Get an expression we can use to find the attributes to assign to MEM.
-     If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
-     we can.  First remove any nops.  */
+     First remove any nops.  */
   while (CONVERT_EXPR_P (exp)
         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
     exp = TREE_OPERAND (exp, 0);
 
-  off = 0;
-  if (TREE_CODE (exp) == POINTER_PLUS_EXPR
-      && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
-      && host_integerp (TREE_OPERAND (exp, 1), 0)
-      && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
-    exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-  else if (TREE_CODE (exp) == ADDR_EXPR)
-    exp = TREE_OPERAND (exp, 0);
-  else if (POINTER_TYPE_P (TREE_TYPE (exp)))
-    exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
-  else
-    exp = NULL;
-
-  /* Honor attributes derived from exp, except for the alias set
-     (as builtin stringops may alias with anything) and the size
-     (as stringops may access multiple array elements).  */
-  if (exp)
-    {
+  /* Build a MEM_REF representing the whole accessed area as a byte blob,
+     (as builtin stringops may alias with anything).  */
+  exp = fold_build2 (MEM_REF,
+                    build_array_type (char_type_node,
+                                      build_range_type (sizetype,
+                                                        size_one_node, len)),
+                    exp, build_int_cst (ptr_type_node, 0));
+
+  /* If the MEM_REF has no acceptable address, try to get the base object
+     from the original address we got, and build an all-aliasing
+     unknown-sized access to that one.  */
+  if (is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0)))
+    set_mem_attributes (mem, exp, 0);
+  else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
+          && (exp = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0),
+                                                    0))))
+    {
+      exp = build_fold_addr_expr (exp);
+      exp = fold_build2 (MEM_REF,
+                        build_array_type (char_type_node,
+                                          build_range_type (sizetype,
+                                                            size_zero_node,
+                                                            NULL)),
+                        exp, build_int_cst (ptr_type_node, 0));
       set_mem_attributes (mem, exp, 0);
-
-      if (off)
-       mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
-
-      /* Allow the string and memory builtins to overflow from one
-        field into another, see http://gcc.gnu.org/PR23561.
-        Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
-        memory accessed by the string or memory builtin will fit
-        within the field.  */
-      if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
-       {
-         tree mem_expr = MEM_EXPR (mem);
-         HOST_WIDE_INT offset = -1, length = -1;
-         tree inner = exp;
-
-         while (TREE_CODE (inner) == ARRAY_REF
-                || CONVERT_EXPR_P (inner)
-                || TREE_CODE (inner) == VIEW_CONVERT_EXPR
-                || TREE_CODE (inner) == SAVE_EXPR)
-           inner = TREE_OPERAND (inner, 0);
-
-         gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
-
-         if (MEM_OFFSET_KNOWN_P (mem))
-           offset = MEM_OFFSET (mem);
-
-         if (offset >= 0 && len && host_integerp (len, 0))
-           length = tree_low_cst (len, 0);
-
-         while (TREE_CODE (inner) == COMPONENT_REF)
-           {
-             tree field = TREE_OPERAND (inner, 1);
-             gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
-             gcc_assert (field == TREE_OPERAND (mem_expr, 1));
-
-             /* Bitfields are generally not byte-addressable.  */
-             gcc_assert (!DECL_BIT_FIELD (field)
-                         || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
-                              % BITS_PER_UNIT) == 0
-                             && host_integerp (DECL_SIZE (field), 0)
-                             && (TREE_INT_CST_LOW (DECL_SIZE (field))
-                                 % BITS_PER_UNIT) == 0));
-
-             /* If we can prove that the memory starting at XEXP (mem, 0) and
-                ending at XEXP (mem, 0) + LENGTH will fit into this field, we
-                can keep the COMPONENT_REF in MEM_EXPR.  But be careful with
-                fields without DECL_SIZE_UNIT like flexible array members.  */
-             if (length >= 0
-                 && DECL_SIZE_UNIT (field)
-                 && host_integerp (DECL_SIZE_UNIT (field), 0))
-               {
-                 HOST_WIDE_INT size
-                   = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
-                 if (offset <= size
-                     && length <= size
-                     && offset + length <= size)
-                   break;
-               }
-
-             if (offset >= 0
-                 && host_integerp (DECL_FIELD_OFFSET (field), 0))
-               offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
-                         + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
-                           / BITS_PER_UNIT;
-             else
-               {
-                 offset = -1;
-                 length = -1;
-               }
-
-             mem_expr = TREE_OPERAND (mem_expr, 0);
-             inner = TREE_OPERAND (inner, 0);
-           }
-
-         if (mem_expr == NULL)
-           offset = -1;
-         if (mem_expr != MEM_EXPR (mem))
-           {
-             set_mem_expr (mem, mem_expr);
-             if (offset >= 0)
-               set_mem_offset (mem, offset);
-             else
-               clear_mem_offset (mem);
-           }
-       }
-      set_mem_alias_set (mem, 0);
-      clear_mem_size (mem);
     }
-
+  set_mem_alias_set (mem, 0);
   return mem;
 }
 \f
@@ -1503,7 +1505,7 @@ expand_builtin_apply_args_1 (void)
      as we might have pretended they were passed.  Make sure it's a valid
      operand, as emit_move_insn isn't expected to handle a PLUS.  */
   tem
-    = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
+    = force_operand (plus_constant (Pmode, tem, crtl->args.pretend_args_size),
                     NULL_RTX);
 #endif
   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
@@ -1624,7 +1626,7 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
   dest = virtual_outgoing_args_rtx;
 #ifndef STACK_GROWS_DOWNWARD
   if (CONST_INT_P (argsize))
-    dest = plus_constant (dest, -INTVAL (argsize));
+    dest = plus_constant (Pmode, dest, -INTVAL (argsize));
   else
     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
 #endif
@@ -1726,7 +1728,7 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
   else
 #endif
     emit_stack_restore (SAVE_BLOCK, old_stack_level);
-  fixup_args_size_notes (call_insn, get_last_insn(), 0);
+  fixup_args_size_notes (call_insn, get_last_insn (), 0);
 
   OK_DEFER_POP;
 
@@ -1990,7 +1992,8 @@ expand_errno_check (tree exp, rtx target)
       rtx errno_rtx
          = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
 #endif
-      emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
+      emit_move_insn (errno_rtx,
+                     gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
       emit_label (lab);
       return;
     }
@@ -2021,6 +2024,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
   tree fndecl = get_callee_fndecl (exp);
   enum machine_mode mode;
   bool errno_set = false;
+  bool try_widening = false;
   tree arg;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -2032,6 +2036,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
     {
     CASE_FLT_FN (BUILT_IN_SQRT):
       errno_set = ! tree_expr_nonnegative_p (arg);
+      try_widening = true;
       builtin_optab = sqrt_optab;
       break;
     CASE_FLT_FN (BUILT_IN_EXP):
@@ -2088,11 +2093,13 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
   if (! flag_errno_math || ! HONOR_NANS (mode))
     errno_set = false;
 
-  /* Before working hard, check whether the instruction is available.  */
-  if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
+  /* Before working hard, check whether the instruction is available, but try
+     to widen the mode for specific operations.  */
+  if ((optab_handler (builtin_optab, mode) != CODE_FOR_nothing
+       || (try_widening && !excess_precision_type (TREE_TYPE (exp))))
       && (!errno_set || !optimize_insn_for_size_p ()))
     {
-      target = gen_reg_rtx (mode);
+      rtx result = gen_reg_rtx (mode);
 
       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
         need to expand the argument again.  This way, we will not perform
@@ -2103,20 +2110,20 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
 
       start_sequence ();
 
-      /* Compute into TARGET.
-        Set TARGET to wherever the result comes back.  */
-      target = expand_unop (mode, builtin_optab, op0, target, 0);
+      /* Compute into RESULT.
+        Set RESULT to wherever the result comes back.  */
+      result = expand_unop (mode, builtin_optab, op0, result, 0);
 
-      if (target != 0)
+      if (result != 0)
        {
          if (errno_set)
-           expand_errno_check (exp, target);
+           expand_errno_check (exp, result);
 
          /* Output the entire sequence.  */
          insns = get_insns ();
          end_sequence ();
          emit_insn (insns);
-         return target;
+         return result;
        }
 
       /* If we were unable to expand via the builtin, stop the sequence
@@ -2139,7 +2146,7 @@ static rtx
 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
 {
   optab builtin_optab;
-  rtx op0, op1, insns;
+  rtx op0, op1, insns, result;
   int op1_type = REAL_TYPE;
   tree fndecl = get_callee_fndecl (exp);
   tree arg0, arg1;
@@ -2195,7 +2202,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
     return NULL_RTX;
 
-  target = gen_reg_rtx (mode);
+  result = gen_reg_rtx (mode);
 
   if (! flag_errno_math || ! HONOR_NANS (mode))
     errno_set = false;
@@ -2212,29 +2219,29 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
 
   start_sequence ();
 
-  /* Compute into TARGET.
-     Set TARGET to wherever the result comes back.  */
-  target = expand_binop (mode, builtin_optab, op0, op1,
-                        target, 0, OPTAB_DIRECT);
+  /* Compute into RESULT.
+     Set RESULT to wherever the result comes back.  */
+  result = expand_binop (mode, builtin_optab, op0, op1,
+                        result, 0, OPTAB_DIRECT);
 
   /* If we were unable to expand via the builtin, stop the sequence
      (without outputting the insns) and call to the library function
      with the stabilized argument list.  */
-  if (target == 0)
+  if (result == 0)
     {
       end_sequence ();
       return expand_call (exp, target, target == const0_rtx);
     }
 
   if (errno_set)
-    expand_errno_check (exp, target);
+    expand_errno_check (exp, result);
 
   /* Output the entire sequence.  */
   insns = get_insns ();
   end_sequence ();
   emit_insn (insns);
 
-  return target;
+  return result;
 }
 
 /* Expand a call to the builtin trinary math functions (fma).
@@ -2248,7 +2255,7 @@ static rtx
 expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
 {
   optab builtin_optab;
-  rtx op0, op1, op2, insns;
+  rtx op0, op1, op2, insns, result;
   tree fndecl = get_callee_fndecl (exp);
   tree arg0, arg1, arg2;
   enum machine_mode mode;
@@ -2275,7 +2282,7 @@ expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
     return NULL_RTX;
 
-  target = gen_reg_rtx (mode);
+  result = gen_reg_rtx (mode);
 
   /* Always stabilize the argument list.  */
   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
@@ -2288,15 +2295,15 @@ expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
 
   start_sequence ();
 
-  /* Compute into TARGET.
-     Set TARGET to wherever the result comes back.  */
-  target = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
-                             target, 0);
+  /* Compute into RESULT.
+     Set RESULT to wherever the result comes back.  */
+  result = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
+                             result, 0);
 
   /* If we were unable to expand via the builtin, stop the sequence
      (without outputting the insns) and call to the library function
      with the stabilized argument list.  */
-  if (target == 0)
+  if (result == 0)
     {
       end_sequence ();
       return expand_call (exp, target, target == const0_rtx);
@@ -2307,7 +2314,7 @@ expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
   end_sequence ();
   emit_insn (insns);
 
-  return target;
+  return result;
 }
 
 /* Expand a call to the builtin sin and cos math functions.
@@ -2359,7 +2366,7 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
   /* Before working hard, check whether the instruction is available.  */
   if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing)
     {
-      target = gen_reg_rtx (mode);
+      rtx result = gen_reg_rtx (mode);
 
       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
         need to expand the argument again.  This way, we will not perform
@@ -2370,37 +2377,35 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
 
       start_sequence ();
 
-      /* Compute into TARGET.
-        Set TARGET to wherever the result comes back.  */
+      /* Compute into RESULT.
+        Set RESULT to wherever the result comes back.  */
       if (builtin_optab == sincos_optab)
        {
-         int result;
+         int ok;
 
          switch (DECL_FUNCTION_CODE (fndecl))
            {
            CASE_FLT_FN (BUILT_IN_SIN):
-             result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
+             ok = expand_twoval_unop (builtin_optab, op0, 0, result, 0);
              break;
            CASE_FLT_FN (BUILT_IN_COS):
-             result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
+             ok = expand_twoval_unop (builtin_optab, op0, result, 0, 0);
              break;
            default:
              gcc_unreachable ();
            }
-         gcc_assert (result);
+         gcc_assert (ok);
        }
       else
-       {
-         target = expand_unop (mode, builtin_optab, op0, target, 0);
-       }
+       result = expand_unop (mode, builtin_optab, op0, result, 0);
 
-      if (target != 0)
+      if (result != 0)
        {
          /* Output the entire sequence.  */
          insns = get_insns ();
          end_sequence ();
          emit_insn (insns);
-         return target;
+         return result;
        }
 
       /* If we were unable to expand via the builtin, stop the sequence
@@ -2409,9 +2414,7 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
       end_sequence ();
     }
 
-  target = expand_call (exp, target, target == const0_rtx);
-
-  return target;
+  return expand_call (exp, target, target == const0_rtx);
 }
 
 /* Given an interclass math builtin decl FNDECL and it's argument ARG
@@ -2422,7 +2425,7 @@ static enum insn_code
 interclass_mathfn_icode (tree arg, tree fndecl)
 {
   bool errno_set = false;
-  optab builtin_optab = 0;
+  optab builtin_optab = unknown_optab;
   enum machine_mode mode;
 
   switch (DECL_FUNCTION_CODE (fndecl))
@@ -2596,7 +2599,7 @@ expand_builtin_cexpi (tree exp, rtx target)
       /* Compute into op1 and op2.  */
       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
     }
-  else if (TARGET_HAS_SINCOS)
+  else if (targetm.libc_has_function (function_sincos))
     {
       tree call, fn = NULL_TREE;
       tree top1, top2;
@@ -2611,8 +2614,8 @@ expand_builtin_cexpi (tree exp, rtx target)
       else
        gcc_unreachable ();
 
-      op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
-      op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
+      op1 = assign_temp (TREE_TYPE (arg), 1, 1);
+      op2 = assign_temp (TREE_TYPE (arg), 1, 1);
       op1a = copy_addr_to_reg (XEXP (op1, 0));
       op2a = copy_addr_to_reg (XEXP (op2, 0));
       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
@@ -2818,6 +2821,7 @@ expand_builtin_int_roundingfn (tree exp, rtx target)
   exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg);
 
   tmp = expand_normal (exp);
+  tmp = maybe_emit_group_store (tmp, TREE_TYPE (exp));
 
   /* Truncate the result of floating point optab to integer
      via expand_fix ().  */
@@ -2880,7 +2884,7 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
   /* There's no easy way to detect the case we need to set EDOM.  */
   if (!flag_errno_math)
     {
-      target = gen_reg_rtx (mode);
+      rtx result = gen_reg_rtx (mode);
 
       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
         need to expand the argument again.  This way, we will not perform
@@ -2891,13 +2895,13 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
 
       start_sequence ();
 
-      if (expand_sfix_optab (target, op0, builtin_optab))
+      if (expand_sfix_optab (result, op0, builtin_optab))
        {
          /* Output the entire sequence.  */
          insns = get_insns ();
          end_sequence ();
          emit_insn (insns);
-         return target;
+         return result;
        }
 
       /* If we were unable to expand via the builtin, stop the sequence
@@ -2921,12 +2925,11 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
                                   fallback_fndecl, 1, arg);
 
       target = expand_call (exp, NULL_RTX, target == const0_rtx);
+      target = maybe_emit_group_store (target, TREE_TYPE (exp));
       return convert_to_mode (mode, target, 0);
     }
 
-  target = expand_call (exp, target, target == const0_rtx);
-
-  return target;
+  return expand_call (exp, target, target == const0_rtx);
 }
 
 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
@@ -3316,7 +3319,8 @@ expand_movstr (tree dest, tree src, rtx target, int endp)
         adjust it.  */
       if (endp == 1)
        {
-         rtx tem = plus_constant (gen_lowpart (GET_MODE (target), target), 1);
+         rtx tem = plus_constant (GET_MODE (target),
+                                  gen_lowpart (GET_MODE (target), target), 1);
          emit_move_insn (target, force_operand (tem, NULL_RTX));
        }
     }
@@ -3415,7 +3419,7 @@ expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
                  if (GET_MODE (target) != GET_MODE (ret))
                    ret = gen_lowpart (GET_MODE (target), ret);
 
-                 ret = plus_constant (ret, INTVAL (len_rtx));
+                 ret = plus_constant (GET_MODE (ret), ret, INTVAL (len_rtx));
                  ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
                  gcc_assert (ret);
 
@@ -4193,7 +4197,7 @@ std_canonical_va_list_type (tree type)
 
   if (INDIRECT_REF_P (type))
     type = TREE_TYPE (type);
-  else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
+  else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (type)))
     type = TREE_TYPE (type);
   wtype = va_list_type_node;
   htype = type;
@@ -4258,219 +4262,6 @@ expand_builtin_va_start (tree exp)
   return const0_rtx;
 }
 
-/* The "standard" implementation of va_arg: read the value from the
-   current (padded) address and increment by the (padded) size.  */
-
-tree
-std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
-                         gimple_seq *post_p)
-{
-  tree addr, t, type_size, rounded_size, valist_tmp;
-  unsigned HOST_WIDE_INT align, boundary;
-  bool indirect;
-
-#ifdef ARGS_GROW_DOWNWARD
-  /* All of the alignment and movement below is for args-grow-up machines.
-     As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
-     implement their own specialized gimplify_va_arg_expr routines.  */
-  gcc_unreachable ();
-#endif
-
-  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
-  if (indirect)
-    type = build_pointer_type (type);
-
-  align = PARM_BOUNDARY / BITS_PER_UNIT;
-  boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
-
-  /* When we align parameter on stack for caller, if the parameter
-     alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
-     aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
-     here with caller.  */
-  if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
-    boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
-
-  boundary /= BITS_PER_UNIT;
-
-  /* Hoist the valist value into a temporary for the moment.  */
-  valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
-
-  /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
-     requires greater alignment, we must perform dynamic alignment.  */
-  if (boundary > align
-      && !integer_zerop (TYPE_SIZE (type)))
-    {
-      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
-                 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
-      gimplify_and_add (t, pre_p);
-
-      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
-                 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
-                              valist_tmp,
-                              build_int_cst (TREE_TYPE (valist), -boundary)));
-      gimplify_and_add (t, pre_p);
-    }
-  else
-    boundary = align;
-
-  /* If the actual alignment is less than the alignment of the type,
-     adjust the type accordingly so that we don't assume strict alignment
-     when dereferencing the pointer.  */
-  boundary *= BITS_PER_UNIT;
-  if (boundary < TYPE_ALIGN (type))
-    {
-      type = build_variant_type_copy (type);
-      TYPE_ALIGN (type) = boundary;
-    }
-
-  /* Compute the rounded size of the type.  */
-  type_size = size_in_bytes (type);
-  rounded_size = round_up (type_size, align);
-
-  /* Reduce rounded_size so it's sharable with the postqueue.  */
-  gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
-
-  /* Get AP.  */
-  addr = valist_tmp;
-  if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
-    {
-      /* Small args are padded downward.  */
-      t = fold_build2_loc (input_location, GT_EXPR, sizetype,
-                      rounded_size, size_int (align));
-      t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
-                      size_binop (MINUS_EXPR, rounded_size, type_size));
-      addr = fold_build_pointer_plus (addr, t);
-    }
-
-  /* Compute new value for AP.  */
-  t = fold_build_pointer_plus (valist_tmp, rounded_size);
-  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
-  gimplify_and_add (t, pre_p);
-
-  addr = fold_convert (build_pointer_type (type), addr);
-
-  if (indirect)
-    addr = build_va_arg_indirect_ref (addr);
-
-  return build_va_arg_indirect_ref (addr);
-}
-
-/* Build an indirect-ref expression over the given TREE, which represents a
-   piece of a va_arg() expansion.  */
-tree
-build_va_arg_indirect_ref (tree addr)
-{
-  addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
-
-  if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
-    mf_mark (addr);
-
-  return addr;
-}
-
-/* Return a dummy expression of type TYPE in order to keep going after an
-   error.  */
-
-static tree
-dummy_object (tree type)
-{
-  tree t = build_int_cst (build_pointer_type (type), 0);
-  return build2 (MEM_REF, type, t, t);
-}
-
-/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
-   builtin function, but a very special sort of operator.  */
-
-enum gimplify_status
-gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
-{
-  tree promoted_type, have_va_type;
-  tree valist = TREE_OPERAND (*expr_p, 0);
-  tree type = TREE_TYPE (*expr_p);
-  tree t;
-  location_t loc = EXPR_LOCATION (*expr_p);
-
-  /* Verify that valist is of the proper type.  */
-  have_va_type = TREE_TYPE (valist);
-  if (have_va_type == error_mark_node)
-    return GS_ERROR;
-  have_va_type = targetm.canonical_va_list_type (have_va_type);
-
-  if (have_va_type == NULL_TREE)
-    {
-      error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
-      return GS_ERROR;
-    }
-
-  /* Generate a diagnostic for requesting data of a type that cannot
-     be passed through `...' due to type promotion at the call site.  */
-  if ((promoted_type = lang_hooks.types.type_promotes_to (type))
-          != type)
-    {
-      static bool gave_help;
-      bool warned;
-
-      /* Unfortunately, this is merely undefined, rather than a constraint
-        violation, so we cannot make this an error.  If this call is never
-        executed, the program is still strictly conforming.  */
-      warned = warning_at (loc, 0,
-                          "%qT is promoted to %qT when passed through %<...%>",
-                          type, promoted_type);
-      if (!gave_help && warned)
-       {
-         gave_help = true;
-         inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
-                 promoted_type, type);
-       }
-
-      /* We can, however, treat "undefined" any way we please.
-        Call abort to encourage the user to fix the program.  */
-      if (warned)
-       inform (loc, "if this code is reached, the program will abort");
-      /* Before the abort, allow the evaluation of the va_list
-        expression to exit or longjmp.  */
-      gimplify_and_add (valist, pre_p);
-      t = build_call_expr_loc (loc,
-                              builtin_decl_implicit (BUILT_IN_TRAP), 0);
-      gimplify_and_add (t, pre_p);
-
-      /* This is dead code, but go ahead and finish so that the
-        mode of the result comes out right.  */
-      *expr_p = dummy_object (type);
-      return GS_ALL_DONE;
-    }
-  else
-    {
-      /* Make it easier for the backends by protecting the valist argument
-        from multiple evaluations.  */
-      if (TREE_CODE (have_va_type) == ARRAY_TYPE)
-       {
-         /* For this case, the backends will be expecting a pointer to
-            TREE_TYPE (abi), but it's possible we've
-            actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
-            So fix it.  */
-         if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
-           {
-             tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
-             valist = fold_convert_loc (loc, p1,
-                                        build_fold_addr_expr_loc (loc, valist));
-           }
-
-         gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
-       }
-      else
-       gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
-
-      if (!targetm.gimplify_va_arg_expr)
-       /* FIXME: Once most targets are converted we should merely
-          assert this is non-null.  */
-       return GS_ALL_DONE;
-
-      *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
-      return GS_OK;
-    }
-}
-
 /* Expand EXP, a call to __builtin_va_end.  */
 
 static rtx
@@ -4599,10 +4390,6 @@ expand_builtin_alloca (tree exp, bool cannot_accumulate)
   bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp))
                            == BUILT_IN_ALLOCA_WITH_ALIGN);
 
-  /* Emit normal call if we use mudflap.  */
-  if (flag_mudflap)
-    return NULL_RTX;
-
   valid_arglist
     = (alloca_with_align
        ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)
@@ -4727,7 +4514,14 @@ expand_builtin_trap (void)
 {
 #ifdef HAVE_trap
   if (HAVE_trap)
-    emit_insn (gen_trap ());
+    {
+      rtx insn = emit_insn (gen_trap ());
+      /* For trap insns when not accumulating outgoing args force
+        REG_ARGS_SIZE note to prevent crossjumping of calls with
+        different args sizes.  */
+      if (!ACCUMULATE_OUTGOING_ARGS)
+       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+    }
   else
 #endif
     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
@@ -4877,8 +4671,8 @@ round_trampoline_addr (rtx tramp)
 
   /* Round address up to desired boundary.  */
   temp = gen_reg_rtx (Pmode);
-  addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
-  mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
+  addend = gen_int_mode (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1, Pmode);
+  mask = gen_int_mode (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT, Pmode);
 
   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
                               temp, 0, OPTAB_LIB_WIDEN);
@@ -4910,8 +4704,7 @@ expand_builtin_init_trampoline (tree exp, bool onstack)
      within the local function's FRAME decl.  Either way, let's see if
      we can fill in the MEM_ATTRs for this memory.  */
   if (TREE_CODE (t_tramp) == ADDR_EXPR)
-    set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
-                                    true, 0);
+    set_mem_attributes (m_tramp, TREE_OPERAND (t_tramp, 0), true);
 
   /* Creator of a heap trampoline is responsible for making sure the
      address is aligned to at least STACK_BOUNDARY.  Normally malloc
@@ -5051,7 +4844,7 @@ expand_builtin_signbit (tree exp, rtx target)
 
   if (bitpos < GET_MODE_BITSIZE (rmode))
     {
-      double_int mask = double_int_setbit (double_int_zero, bitpos);
+      double_int mask = double_int_zero.set_bit (bitpos);
 
       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
        temp = gen_lowpart (rmode, temp);
@@ -5357,7 +5150,7 @@ get_memmodel (tree exp)
       return MEMMODEL_SEQ_CST;
     }
 
-  if ((INTVAL(op) & MEMMODEL_MASK) >= MEMMODEL_LAST)
+  if ((INTVAL (op) & MEMMODEL_MASK) >= MEMMODEL_LAST)
     {
       warning (OPT_Winvalid_memory_model,
               "invalid memory model argument to builtin");
@@ -5437,6 +5230,7 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
 
   expect = expand_normal (CALL_EXPR_ARG (exp, 1));
   expect = convert_memory_address (Pmode, expect);
+  expect = gen_rtx_MEM (mode, expect);
   desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
 
   weak = CALL_EXPR_ARG (exp, 3);
@@ -5444,14 +5238,15 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
   if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
     is_weak = true;
 
-  oldval = copy_to_reg (gen_rtx_MEM (mode, expect));
-
+  oldval = expect;
   if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
                                       &oldval, mem, oldval, desired,
                                       is_weak, success, failure))
     return NULL_RTX;
 
-  emit_move_insn (gen_rtx_MEM (mode, expect), oldval);
+  if (oldval != expect)
+    emit_move_insn (expect, oldval);
+
   return target;
 }
 
@@ -5559,7 +5354,7 @@ expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
   STRIP_NOPS (addr);
 
   gcc_assert (TREE_OPERAND (addr, 0) == fndecl);
-  TREE_OPERAND (addr, 0) = builtin_decl_explicit(ext_call);
+  TREE_OPERAND (addr, 0) = builtin_decl_explicit (ext_call);
 
   /* Expand the call here so we can emit trailing code.  */
   ret = expand_call (exp, target, ignore);
@@ -5784,26 +5579,92 @@ expand_builtin_atomic_thread_fence (tree exp)
   expand_mem_thread_fence (model);
 }
 
-/* Expand the __atomic_signal_fence intrinsic:
-       void __atomic_signal_fence (enum memmodel)
-   EXP is the CALL_EXPR.  */
+/* Expand the __atomic_signal_fence intrinsic:
+       void __atomic_signal_fence (enum memmodel)
+   EXP is the CALL_EXPR.  */
+
+static void
+expand_builtin_atomic_signal_fence (tree exp)
+{
+  enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
+  expand_mem_signal_fence (model);
+}
+
+/* Expand the __sync_synchronize intrinsic.  */
+
+static void
+expand_builtin_sync_synchronize (void)
+{
+  expand_mem_thread_fence (MEMMODEL_SEQ_CST);
+}
+
+static rtx
+expand_builtin_thread_pointer (tree exp, rtx target)
+{
+  enum insn_code icode;
+  if (!validate_arglist (exp, VOID_TYPE))
+    return const0_rtx;
+  icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
+  if (icode != CODE_FOR_nothing)
+    {
+      struct expand_operand op;
+      if (!REG_P (target) || GET_MODE (target) != Pmode)
+       target = gen_reg_rtx (Pmode);
+      create_output_operand (&op, target, Pmode);
+      expand_insn (icode, 1, &op);
+      return target;
+    }
+  error ("__builtin_thread_pointer is not supported on this target");
+  return const0_rtx;
+}
+
+static void
+expand_builtin_set_thread_pointer (tree exp)
+{
+  enum insn_code icode;
+  if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
+    return;
+  icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
+  if (icode != CODE_FOR_nothing)
+    {
+      struct expand_operand op;
+      rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+                            Pmode, EXPAND_NORMAL);      
+      create_input_operand (&op, val, Pmode);
+      expand_insn (icode, 1, &op);
+      return;
+    }
+  error ("__builtin_set_thread_pointer is not supported on this target");
+}
+
+\f
+/* Emit code to restore the current value of stack.  */
 
 static void
-expand_builtin_atomic_signal_fence (tree exp)
+expand_stack_restore (tree var)
 {
-  enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
-  expand_mem_signal_fence (model);
+  rtx prev, sa = expand_normal (var);
+
+  sa = convert_memory_address (Pmode, sa);
+
+  prev = get_last_insn ();
+  emit_stack_restore (SAVE_BLOCK, sa);
+  fixup_args_size_notes (prev, get_last_insn (), 0);
 }
 
-/* Expand the __sync_synchronize intrinsic.  */
 
-static void
-expand_builtin_sync_synchronize (void)
+/* Emit code to save the current value of stack.  */
+
+static rtx
+expand_stack_save (void)
 {
-  expand_mem_thread_fence (MEMMODEL_SEQ_CST);
+  rtx ret = NULL_RTX;
+
+  do_pending_stack_adjust ();
+  emit_stack_save (SAVE_BLOCK, &ret);
+  return ret;
 }
 
-\f
 /* Expand an expression EXP that calls a built-in function,
    with result going to TARGET if that's convenient
    (and in mode MODE if that's convenient).
@@ -5826,9 +5687,27 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
      set of builtins.  */
   if (!optimize
       && !called_as_built_in (fndecl)
+      && fcode != BUILT_IN_FORK
+      && fcode != BUILT_IN_EXECL
+      && fcode != BUILT_IN_EXECV
+      && fcode != BUILT_IN_EXECLP
+      && fcode != BUILT_IN_EXECLE
+      && fcode != BUILT_IN_EXECVP
+      && fcode != BUILT_IN_EXECVE
       && fcode != BUILT_IN_ALLOCA
       && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
-      && fcode != BUILT_IN_FREE)
+      && fcode != BUILT_IN_FREE
+      && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
+      && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS
+      && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND
+      && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND)
     return expand_call (exp, target, ignore);
 
   /* The built-in function expanders test for target == const0_rtx
@@ -5865,6 +5744,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
   switch (fcode)
     {
     CASE_FLT_FN (BUILT_IN_FABS):
+    case BUILT_IN_FABSD32:
+    case BUILT_IN_FABSD64:
+    case BUILT_IN_FABSD128:
       target = expand_builtin_fabs (exp, target, subtarget);
       if (target)
        return target;
@@ -6107,7 +5989,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       break;
 
     CASE_INT_FN (BUILT_IN_FFS):
-    case BUILT_IN_FFSIMAX:
       target = expand_builtin_unop (target_mode, exp, target,
                                    subtarget, ffs_optab);
       if (target)
@@ -6115,7 +5996,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       break;
 
     CASE_INT_FN (BUILT_IN_CLZ):
-    case BUILT_IN_CLZIMAX:
       target = expand_builtin_unop (target_mode, exp, target,
                                    subtarget, clz_optab);
       if (target)
@@ -6123,7 +6003,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       break;
 
     CASE_INT_FN (BUILT_IN_CTZ):
-    case BUILT_IN_CTZIMAX:
       target = expand_builtin_unop (target_mode, exp, target,
                                    subtarget, ctz_optab);
       if (target)
@@ -6131,7 +6010,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       break;
 
     CASE_INT_FN (BUILT_IN_CLRSB):
-    case BUILT_IN_CLRSBIMAX:
       target = expand_builtin_unop (target_mode, exp, target,
                                    subtarget, clrsb_optab);
       if (target)
@@ -6139,7 +6017,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       break;
 
     CASE_INT_FN (BUILT_IN_POPCOUNT):
-    case BUILT_IN_POPCOUNTIMAX:
       target = expand_builtin_unop (target_mode, exp, target,
                                    subtarget, popcount_optab);
       if (target)
@@ -6147,7 +6024,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       break;
 
     CASE_INT_FN (BUILT_IN_PARITY):
-    case BUILT_IN_PARITYIMAX:
       target = expand_builtin_unop (target_mode, exp, target,
                                    subtarget, parity_optab);
       if (target)
@@ -6601,7 +6477,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
       {
        unsigned int nargs, z;
-       VEC(tree,gc) *vec;
+       vec<tree, va_gc> *vec;
 
        mode = 
            get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
@@ -6612,12 +6488,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
        /* If this is turned into an external library call, the weak parameter
           must be dropped to match the expected parameter list.  */
        nargs = call_expr_nargs (exp);
-       vec = VEC_alloc (tree, gc, nargs - 1);
+       vec_alloc (vec, nargs - 1);
        for (z = 0; z < 3; z++)
-         VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
+         vec->quick_push (CALL_EXPR_ARG (exp, z));
        /* Skip the boolean weak parameter.  */
        for (z = 4; z < 6; z++)
-         VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
+         vec->quick_push (CALL_EXPR_ARG (exp, z));
        exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
        break;
       }
@@ -6868,6 +6744,66 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
        maybe_emit_free_warning (exp);
       break;
 
+    case BUILT_IN_THREAD_POINTER:
+      return expand_builtin_thread_pointer (exp, target);
+
+    case BUILT_IN_SET_THREAD_POINTER:
+      expand_builtin_set_thread_pointer (exp);
+      return const0_rtx;
+
+    case BUILT_IN_CILK_DETACH:
+      expand_builtin_cilk_detach (exp);
+      return const0_rtx;
+      
+    case BUILT_IN_CILK_POP_FRAME:
+      expand_builtin_cilk_pop_frame (exp);
+      return const0_rtx;
+
+    case BUILT_IN_CHKP_INIT_PTR_BOUNDS:
+    case BUILT_IN_CHKP_NULL_PTR_BOUNDS:
+    case BUILT_IN_CHKP_COPY_PTR_BOUNDS:
+      return expand_normal (CALL_EXPR_ARG (exp, 0));
+
+    case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS:
+    case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS:
+    case BUILT_IN_CHKP_CHECK_PTR_BOUNDS:
+    case BUILT_IN_CHKP_SET_PTR_BOUNDS:
+    case BUILT_IN_CHKP_NARROW_PTR_BOUNDS:
+    case BUILT_IN_CHKP_STORE_PTR_BOUNDS:
+    case BUILT_IN_CHKP_GET_PTR_LBOUND:
+    case BUILT_IN_CHKP_GET_PTR_UBOUND:
+      /* We allow user CHKP builtins if Pointer Bounds
+        Checker is off.  */
+      if (!flag_check_pointer_bounds)
+       {
+         if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS
+             || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS)
+           return expand_normal (CALL_EXPR_ARG (exp, 0));
+         else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND)
+           return expand_normal (size_zero_node);
+         else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND)
+           return expand_normal (size_int (-1));
+         else
+           return const0_rtx;
+       }
+      /* FALLTHROUGH */
+
+    case BUILT_IN_CHKP_BNDMK:
+    case BUILT_IN_CHKP_BNDSTX:
+    case BUILT_IN_CHKP_BNDCL:
+    case BUILT_IN_CHKP_BNDCU:
+    case BUILT_IN_CHKP_BNDLDX:
+    case BUILT_IN_CHKP_BNDRET:
+    case BUILT_IN_CHKP_INTERSECT:
+    case BUILT_IN_CHKP_ARG_BND:
+    case BUILT_IN_CHKP_NARROW:
+    case BUILT_IN_CHKP_EXTRACT_LOWER:
+    case BUILT_IN_CHKP_EXTRACT_UPPER:
+      /* Software implementation of pointers checker is NYI.
+        Target support is required.  */
+      error ("Your target platform does not support -fcheck-pointers");
+      break;
+
     default:   /* just do library call, if unknown builtin */
       break;
     }
@@ -6986,7 +6922,8 @@ fold_builtin_constant_p (tree arg)
       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
       || POINTER_TYPE_P (TREE_TYPE (arg))
       || cfun == 0
-      || folding_initializer)
+      || folding_initializer
+      || force_folding_builtin_constant_p)
     return integer_zero_node;
 
   return NULL_TREE;
@@ -7808,7 +7745,7 @@ fold_builtin_sincos (location_t loc,
     return res;
 
   /* Canonicalize sincos to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex))
     return NULL_TREE;
   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
   if (!fn)
@@ -7848,7 +7785,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
 
   /* In case we can figure out the real part of arg0 and it is constant zero
      fold to cexpi.  */
-  if (!TARGET_C99_FUNCTIONS)
+  if (!targetm.libc_has_function (function_c99_math_complex))
     return NULL_TREE;
   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
   if (!ifn)
@@ -8103,15 +8040,14 @@ fold_builtin_bitop (tree fndecl, tree arg)
       if (width > HOST_BITS_PER_WIDE_INT)
        {
          hi = TREE_INT_CST_HIGH (arg);
-         if (width < 2 * HOST_BITS_PER_WIDE_INT)
-           hi &= ~((unsigned HOST_WIDE_INT) (-1)
-                   << (width - HOST_BITS_PER_WIDE_INT));
+         if (width < HOST_BITS_PER_DOUBLE_INT)
+           hi &= ~(HOST_WIDE_INT_M1U << (width - HOST_BITS_PER_WIDE_INT));
        }
       else
        {
          hi = 0;
          if (width < HOST_BITS_PER_WIDE_INT)
-           lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
+           lo &= ~(HOST_WIDE_INT_M1U << width);
        }
 
       switch (DECL_FUNCTION_CODE (fndecl))
@@ -8144,17 +8080,19 @@ fold_builtin_bitop (tree fndecl, tree arg)
          break;
 
        CASE_INT_FN (BUILT_IN_CLRSB):
+         if (width > 2 * HOST_BITS_PER_WIDE_INT)
+           return NULL_TREE;
          if (width > HOST_BITS_PER_WIDE_INT
              && (hi & ((unsigned HOST_WIDE_INT) 1
                        << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
            {
-             hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
+             hi = ~hi & ~(HOST_WIDE_INT_M1U
                           << (width - HOST_BITS_PER_WIDE_INT - 1));
              lo = ~lo;
            }
          else if (width <= HOST_BITS_PER_WIDE_INT
                   && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
-           lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
+           lo = ~lo & ~(HOST_WIDE_INT_M1U << (width - 1));
          if (hi != 0)
            result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
          else if (lo != 0)
@@ -8834,14 +8772,14 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
                  if (! operand_equal_p (TREE_OPERAND (src_base, 0),
                                         TREE_OPERAND (dest_base, 0), 0))
                    return NULL_TREE;
-                 off = double_int_add (mem_ref_offset (src_base),
-                                       shwi_to_double_int (src_offset));
-                 if (!double_int_fits_in_shwi_p (off))
+                 off = mem_ref_offset (src_base) +
+                                       double_int::from_shwi (src_offset);
+                 if (!off.fits_shwi ())
                    return NULL_TREE;
                  src_offset = off.low;
-                 off = double_int_add (mem_ref_offset (dest_base),
-                                       shwi_to_double_int (dest_offset));
-                 if (!double_int_fits_in_shwi_p (off))
+                 off = mem_ref_offset (dest_base) +
+                                       double_int::from_shwi (dest_offset);
+                 if (!off.fits_shwi ())
                    return NULL_TREE;
                  dest_offset = off.low;
                  if (ranges_overlap_p (src_offset, maxsize,
@@ -9605,8 +9543,8 @@ static tree
 fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
 {
   if (validate_arg (arg0, REAL_TYPE)
-      && validate_arg(arg1, REAL_TYPE)
-      && validate_arg(arg2, REAL_TYPE))
+      && validate_arg (arg1, REAL_TYPE)
+      && validate_arg (arg2, REAL_TYPE))
     {
       tree tem = fold_fma (loc, type, arg0, arg1, arg2);
       if (tem)
@@ -9706,7 +9644,16 @@ fold_builtin_logb (location_t loc, tree arg, tree rettype)
       case rvc_inf:
        /* If arg is Inf or NaN and we're logb, return it.  */
        if (TREE_CODE (rettype) == REAL_TYPE)
-         return fold_convert_loc (loc, rettype, arg);
+         {
+           /* For logb(-Inf) we have to return +Inf.  */
+           if (real_isinf (value) && real_isneg (value))
+             {
+               REAL_VALUE_TYPE tem;
+               real_inf (&tem);
+               return build_real (rettype, tem);
+             }
+           return fold_convert_loc (loc, rettype, arg);
+         }
        /* Fall through... */
       case rvc_zero:
        /* Zero may set errno and/or raise an exception for logb, also
@@ -10264,6 +10211,14 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
     case BUILT_IN_CLASSIFY_TYPE:
       return fold_builtin_classify_type (NULL_TREE);
 
+    case BUILT_IN_UNREACHABLE:
+      if (flag_sanitize & SANITIZE_UNREACHABLE
+         && (current_function_decl == NULL
+             || !lookup_attribute ("no_sanitize_undefined",
+                                   DECL_ATTRIBUTES (current_function_decl))))
+       return ubsan_instrument_unreachable (loc);
+      break;
+
     default:
       break;
     }
@@ -10301,6 +10256,9 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
       return fold_builtin_strlen (loc, type, arg0);
 
     CASE_FLT_FN (BUILT_IN_FABS):
+    case BUILT_IN_FABSD32:
+    case BUILT_IN_FABSD64:
+    case BUILT_IN_FABSD128:
       return fold_builtin_fabs (loc, arg0, type);
 
     case BUILT_IN_ABS:
@@ -10328,13 +10286,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
     break;
 
     CASE_FLT_FN (BUILT_IN_CCOS):
-      return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
+      return fold_builtin_ccos (loc, arg0, type, fndecl, /*hyper=*/ false);
 
     CASE_FLT_FN (BUILT_IN_CCOSH):
-      return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
+      return fold_builtin_ccos (loc, arg0, type, fndecl, /*hyper=*/ true);
 
     CASE_FLT_FN (BUILT_IN_CPROJ):
-      return fold_builtin_cproj(loc, arg0, type);
+      return fold_builtin_cproj (loc, arg0, type);
 
     CASE_FLT_FN (BUILT_IN_CSIN):
       if (validate_arg (arg0, COMPLEX_TYPE)
@@ -10709,26 +10667,26 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
     CASE_FLT_FN (BUILT_IN_DREM):
     CASE_FLT_FN (BUILT_IN_REMAINDER):
       if (validate_arg (arg0, REAL_TYPE)
-          && validate_arg(arg1, REAL_TYPE))
+          && validate_arg (arg1, REAL_TYPE))
         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
     break;
 
     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
       if (validate_arg (arg0, REAL_TYPE)
-         && validate_arg(arg1, POINTER_TYPE))
+         && validate_arg (arg1, POINTER_TYPE))
        return do_mpfr_lgamma_r (arg0, arg1, type);
     break;
 
     CASE_FLT_FN (BUILT_IN_ATAN2):
       if (validate_arg (arg0, REAL_TYPE)
-         && validate_arg(arg1, REAL_TYPE))
+         && validate_arg (arg1, REAL_TYPE))
        return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
     break;
 
     CASE_FLT_FN (BUILT_IN_FDIM):
       if (validate_arg (arg0, REAL_TYPE)
-         && validate_arg(arg1, REAL_TYPE))
+         && validate_arg (arg1, REAL_TYPE))
        return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
     break;
 
@@ -10910,8 +10868,8 @@ fold_builtin_3 (location_t loc, tree fndecl,
 
     CASE_FLT_FN (BUILT_IN_REMQUO):
       if (validate_arg (arg0, REAL_TYPE)
-         && validate_arg(arg1, REAL_TYPE)
-         && validate_arg(arg2, POINTER_TYPE))
+         && validate_arg (arg1, REAL_TYPE)
+         && validate_arg (arg2, POINTER_TYPE))
        return do_mpfr_remquo (arg0, arg1, arg2);
     break;
 
@@ -11088,47 +11046,51 @@ fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
   return NULL_TREE;
 }
 
-/* Builtins with folding operations that operate on "..." arguments
-   need special handling; we need to store the arguments in a convenient
-   data structure before attempting any folding.  Fortunately there are
-   only a few builtins that fall into this category.  FNDECL is the
-   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
-   result of the function call is ignored.  */
+/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
+   list ARGS along with N new arguments in NEWARGS.  SKIP is the number
+   of arguments in ARGS to be omitted.  OLDNARGS is the number of
+   elements in ARGS.  */
 
 static tree
-fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
-                     bool ignore ATTRIBUTE_UNUSED)
+rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
+                         int skip, tree fndecl, int n, va_list newargs)
 {
-  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
-  tree ret = NULL_TREE;
+  int nargs = oldnargs - skip + n;
+  tree *buffer;
 
-  switch (fcode)
+  if (n > 0)
     {
-    case BUILT_IN_SPRINTF_CHK:
-    case BUILT_IN_VSPRINTF_CHK:
-      ret = fold_builtin_sprintf_chk (loc, exp, fcode);
-      break;
+      int i, j;
 
-    case BUILT_IN_SNPRINTF_CHK:
-    case BUILT_IN_VSNPRINTF_CHK:
-      ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
-      break;
+      buffer = XALLOCAVEC (tree, nargs);
+      for (i = 0; i < n; i++)
+       buffer[i] = va_arg (newargs, tree);
+      for (j = skip; j < oldnargs; j++, i++)
+       buffer[i] = args[j];
+    }
+  else
+    buffer = args + skip;
 
-    case BUILT_IN_FPCLASSIFY:
-      ret = fold_builtin_fpclassify (loc, exp);
-      break;
+  return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
+}
 
-    default:
-      break;
-    }
-  if (ret)
-    {
-      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
-      SET_EXPR_LOCATION (ret, loc);
-      TREE_NO_WARNING (ret) = 1;
-      return ret;
-    }
-  return NULL_TREE;
+/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
+   list ARGS along with N new arguments specified as the "..."
+   parameters.  SKIP is the number of arguments in ARGS to be omitted.
+   OLDNARGS is the number of elements in ARGS.  */
+
+static tree
+rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
+                        int skip, tree fndecl, int n, ...)
+{
+  va_list ap;
+  tree t;
+
+  va_start (ap, n);
+  t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
+  va_end (ap);
+
+  return t;
 }
 
 /* Return true if FNDECL shouldn't be folded right now.
@@ -11219,10 +11181,10 @@ build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
    VEC.  */
 
 tree
-build_call_expr_loc_vec (location_t loc, tree fndecl, VEC(tree,gc) *vec)
+build_call_expr_loc_vec (location_t loc, tree fndecl, vec<tree, va_gc> *vec)
 {
-  return build_call_expr_loc_array (loc, fndecl, VEC_length (tree, vec),
-                                   VEC_address (tree, vec));
+  return build_call_expr_loc_array (loc, fndecl, vec_safe_length (vec),
+                                   vec_safe_address (vec));
 }
 
 
@@ -11319,53 +11281,6 @@ fold_builtin_call_array (location_t loc, tree type,
   return build_call_array_loc (loc, type, fn, n, argarray);
 }
 
-/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
-   list ARGS along with N new arguments in NEWARGS.  SKIP is the number
-   of arguments in ARGS to be omitted.  OLDNARGS is the number of
-   elements in ARGS.  */
-
-static tree
-rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
-                         int skip, tree fndecl, int n, va_list newargs)
-{
-  int nargs = oldnargs - skip + n;
-  tree *buffer;
-
-  if (n > 0)
-    {
-      int i, j;
-
-      buffer = XALLOCAVEC (tree, nargs);
-      for (i = 0; i < n; i++)
-       buffer[i] = va_arg (newargs, tree);
-      for (j = skip; j < oldnargs; j++, i++)
-       buffer[i] = args[j];
-    }
-  else
-    buffer = args + skip;
-
-  return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
-}
-
-/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
-   list ARGS along with N new arguments specified as the "..."
-   parameters.  SKIP is the number of arguments in ARGS to be omitted.
-   OLDNARGS is the number of elements in ARGS.  */
-
-static tree
-rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
-                        int skip, tree fndecl, int n, ...)
-{
-  va_list ap;
-  tree t;
-
-  va_start (ap, n);
-  t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
-  va_end (ap);
-
-  return t;
-}
-
 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
    along with N new arguments specified as the "..." parameters.  SKIP
    is the number of arguments in EXP to be omitted.  This function is used
@@ -11455,57 +11370,6 @@ validate_gimple_arglist (const_gimple call, ...)
   return res;
 }
 
-/* This function validates the types of a function call argument list
-   against a specified list of tree_codes.  If the last specifier is a 0,
-   that represents an ellipses, otherwise the last specifier must be a
-   VOID_TYPE.  */
-
-bool
-validate_arglist (const_tree callexpr, ...)
-{
-  enum tree_code code;
-  bool res = 0;
-  va_list ap;
-  const_call_expr_arg_iterator iter;
-  const_tree arg;
-
-  va_start (ap, callexpr);
-  init_const_call_expr_arg_iterator (callexpr, &iter);
-
-  do
-    {
-      code = (enum tree_code) va_arg (ap, int);
-      switch (code)
-       {
-       case 0:
-         /* This signifies an ellipses, any further arguments are all ok.  */
-         res = true;
-         goto end;
-       case VOID_TYPE:
-         /* This signifies an endlink, if no arguments remain, return
-            true, otherwise return false.  */
-         res = !more_const_call_expr_args_p (&iter);
-         goto end;
-       default:
-         /* If no parameters remain or the parameter's code does not
-            match the specified code, return false.  Otherwise continue
-            checking any remaining arguments.  */
-         arg = next_const_call_expr_arg (&iter);
-         if (!validate_arg (arg, code))
-           goto end;
-         break;
-       }
-    }
-  while (1);
-
-  /* We need gotos here since we can only have one VA_CLOSE in a
-     function.  */
- end: ;
-  va_end (ap);
-
-  return res;
-}
-
 /* Default target-specific builtin expander that does nothing.  */
 
 rtx
@@ -11949,7 +11813,7 @@ fold_builtin_strspn (location_t loc, tree s1, tree s2)
       if (p1 && p2)
        {
          const size_t r = strspn (p1, p2);
-         return size_int (r);
+         return build_int_cst (size_type_node, r);
        }
 
       /* If either argument is "", return NULL_TREE.  */
@@ -11994,7 +11858,7 @@ fold_builtin_strcspn (location_t loc, tree s1, tree s2)
       if (p1 && p2)
        {
          const size_t r = strcspn (p1, p2);
-         return size_int (r);
+         return build_int_cst (size_type_node, r);
        }
 
       /* If the first argument is "", return NULL_TREE.  */
@@ -12755,7 +12619,7 @@ fold_builtin_object_size (tree ptr, tree ost)
     {
       bytes = compute_builtin_object_size (ptr, object_size_type);
       if (double_int_fits_to_tree_p (size_type_node,
-                                    uhwi_to_double_int (bytes)))
+                                    double_int::from_uhwi (bytes)))
        return build_int_cstu (size_type_node, bytes);
     }
   else if (TREE_CODE (ptr) == SSA_NAME)
@@ -12766,7 +12630,7 @@ fold_builtin_object_size (tree ptr, tree ost)
       bytes = compute_builtin_object_size (ptr, object_size_type);
       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
           && double_int_fits_to_tree_p (size_type_node,
-                                       uhwi_to_double_int (bytes)))
+                                       double_int::from_uhwi (bytes)))
        return build_int_cstu (size_type_node, bytes);
     }
 
@@ -13277,7 +13141,7 @@ fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
    passed as second argument.  */
 
-tree
+static tree
 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
                           enum built_in_function fcode)
 {
@@ -13285,6 +13149,49 @@ fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
                                      CALL_EXPR_ARGP (exp), maxlen, fcode);
 }
 
+/* Builtins with folding operations that operate on "..." arguments
+   need special handling; we need to store the arguments in a convenient
+   data structure before attempting any folding.  Fortunately there are
+   only a few builtins that fall into this category.  FNDECL is the
+   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
+   result of the function call is ignored.  */
+
+static tree
+fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
+                     bool ignore ATTRIBUTE_UNUSED)
+{
+  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+  tree ret = NULL_TREE;
+
+  switch (fcode)
+    {
+    case BUILT_IN_SPRINTF_CHK:
+    case BUILT_IN_VSPRINTF_CHK:
+      ret = fold_builtin_sprintf_chk (loc, exp, fcode);
+      break;
+
+    case BUILT_IN_SNPRINTF_CHK:
+    case BUILT_IN_VSNPRINTF_CHK:
+      ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
+      break;
+
+    case BUILT_IN_FPCLASSIFY:
+      ret = fold_builtin_fpclassify (loc, exp);
+      break;
+
+    default:
+      break;
+    }
+  if (ret)
+    {
+      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
+      SET_EXPR_LOCATION (ret, loc);
+      TREE_NO_WARNING (ret) = 1;
+      return ret;
+    }
+  return NULL_TREE;
+}
+
 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
    FMT and ARG are the arguments to the call; we don't fold cases with
    more than 2 arguments, and ARG may be null if this is a 1-argument case.
@@ -13884,7 +13791,7 @@ do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
       && host_integerp (arg1, 0)
       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
     {
-      const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
+      const HOST_WIDE_INT n = tree_low_cst (arg1, 0);
       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
 
       if (n == (long)n
@@ -14012,7 +13919,7 @@ do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
         negative integer.  */
       if (real_isfinite (ra)
          && ra->cl != rvc_zero
-         && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
+         && !(real_isneg (ra) && real_isinteger (ra, TYPE_MODE (type))))
         {
          const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
          const int prec = fmt->p;
@@ -14081,8 +13988,8 @@ do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
          mpc_t m;
 
          mpc_init2 (m, prec);
-         mpfr_from_real (mpc_realref(m), re, rnd);
-         mpfr_from_real (mpc_imagref(m), im, rnd);
+         mpfr_from_real (mpc_realref (m), re, rnd);
+         mpfr_from_real (mpc_imagref (m), im, rnd);
          mpfr_clear_flags ();
          inexact = func (m, m, crnd);
          result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
@@ -14137,10 +14044,10 @@ do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
 
          mpc_init2 (m0, prec);
          mpc_init2 (m1, prec);
-         mpfr_from_real (mpc_realref(m0), re0, rnd);
-         mpfr_from_real (mpc_imagref(m0), im0, rnd);
-         mpfr_from_real (mpc_realref(m1), re1, rnd);
-         mpfr_from_real (mpc_imagref(m1), im1, rnd);
+         mpfr_from_real (mpc_realref (m0), re0, rnd);
+         mpfr_from_real (mpc_imagref (m0), im0, rnd);
+         mpfr_from_real (mpc_realref (m1), re1, rnd);
+         mpfr_from_real (mpc_imagref (m1), im1, rnd);
          mpfr_clear_flags ();
          inexact = func (m0, m0, m1, crnd);
          result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);