recog.h (constrain_operands): Add an alternative_mask parameter.
[gcc.git] / gcc / config / i386 / i386.c
index 6ffb7884008fd64b8070e5b050e16455a51669b8..ec3e056a3d2aeb6c892d032eb2324957750367a7 100644 (file)
@@ -38,6 +38,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-attr.h"
 #include "flags.h"
 #include "except.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "machmode.h"
+#include "input.h"
 #include "function.h"
 #include "recog.h"
 #include "expr.h"
@@ -52,9 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "reload.h"
 #include "cgraph.h"
-#include "pointer-set.h"
 #include "hash-table.h"
-#include "vec.h"
 #include "basic-block.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
@@ -84,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target-globals.h"
 #include "tree-vectorizer.h"
 #include "shrink-wrap.h"
+#include "builtins.h"
 
 static rtx legitimize_dllimport_symbol (rtx, bool);
 static rtx legitimize_pe_coff_extern_decl (rtx, bool);
@@ -2522,7 +2526,6 @@ const pass_data pass_data_insert_vzeroupper =
   RTL_PASS, /* type */
   "vzeroupper", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  true, /* has_execute */
   TV_NONE, /* tv_id */
   0, /* properties_required */
   0, /* properties_provided */
@@ -2593,6 +2596,9 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
     { "-mavx512er",    OPTION_MASK_ISA_AVX512ER },
     { "-mavx512cd",    OPTION_MASK_ISA_AVX512CD },
     { "-mavx512pf",    OPTION_MASK_ISA_AVX512PF },
+    { "-mavx512dq",    OPTION_MASK_ISA_AVX512DQ },
+    { "-mavx512bw",    OPTION_MASK_ISA_AVX512BW },
+    { "-mavx512vl",    OPTION_MASK_ISA_AVX512VL },
     { "-msse4a",       OPTION_MASK_ISA_SSE4A },
     { "-msse4.2",      OPTION_MASK_ISA_SSE4_2 },
     { "-msse4.1",      OPTION_MASK_ISA_SSE4_1 },
@@ -3123,6 +3129,9 @@ ix86_option_override_internal (bool main_args_p,
 #define PTA_CLFLUSHOPT         (HOST_WIDE_INT_1 << 47)
 #define PTA_XSAVEC             (HOST_WIDE_INT_1 << 48)
 #define PTA_XSAVES             (HOST_WIDE_INT_1 << 49)
+#define PTA_AVX512DQ           (HOST_WIDE_INT_1 << 50)
+#define PTA_AVX512BW           (HOST_WIDE_INT_1 << 51)
+#define PTA_AVX512VL           (HOST_WIDE_INT_1 << 52)
 
 #define PTA_CORE2 \
   (PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 \
@@ -3267,12 +3276,13 @@ ix86_option_override_internal (bool main_args_p,
        | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE 
        | PTA_XSAVEOPT | PTA_FSGSBASE},
      {"bdver4", PROCESSOR_BDVER4, CPU_BDVER4,
-        PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
-        | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1
-        | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2 
+       PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
+       | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1
+       | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2 
        | PTA_FMA4 | PTA_XOP | PTA_LWP | PTA_BMI | PTA_BMI2 
        | PTA_TBM | PTA_F16C | PTA_FMA | PTA_PRFCHW | PTA_FXSR 
-       | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE},
+       | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE | PTA_RDRND
+       | PTA_MOVBE},
       {"btver1", PROCESSOR_BTVER1, CPU_GENERIC,
        PTA_64BIT | PTA_MMX |  PTA_SSE  | PTA_SSE2 | PTA_SSE3
        | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW
@@ -3340,8 +3350,9 @@ ix86_option_override_internal (bool main_args_p,
       /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ABI_X32 is
         on and OPTION_MASK_ABI_64 is off.  We turn off
         OPTION_MASK_ABI_X32 if OPTION_MASK_ABI_64 is turned on by
-        -m64.  */
-      if (TARGET_LP64_P (opts->x_ix86_isa_flags))
+        -m64 or OPTION_MASK_CODE16 is turned on by -m16.  */
+      if (TARGET_LP64_P (opts->x_ix86_isa_flags)
+         || TARGET_16BIT_P (opts->x_ix86_isa_flags))
        opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
 #endif
     }
@@ -3689,6 +3700,15 @@ ix86_option_override_internal (bool main_args_p,
        if (processor_alias_table[i].flags & PTA_XSAVES
            && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVES))
          opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVES;
+       if (processor_alias_table[i].flags & PTA_AVX512DQ
+           && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512DQ))
+         opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512DQ;
+       if (processor_alias_table[i].flags & PTA_AVX512BW
+           && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512BW))
+         opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512BW;
+       if (processor_alias_table[i].flags & PTA_AVX512VL
+           && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512VL))
+         opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512VL;
        if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE))
          x86_prefetch_sse = true;
 
@@ -3959,6 +3979,13 @@ ix86_option_override_internal (bool main_args_p,
        }
     }
 
+#ifndef NO_PROFILE_COUNTERS
+  if (flag_nop_mcount)
+    error ("-mnop-mcount is not compatible with this target");
+#endif
+  if (flag_nop_mcount && flag_pic)
+    error ("-mnop-mcount is not implemented for -fPIC");
+
   /* Accept -msseregparm only if at least SSE support is enabled.  */
   if (TARGET_SSEREGPARM_P (opts->x_target_flags)
       && ! TARGET_SSE_P (opts->x_ix86_isa_flags))
@@ -4545,6 +4572,9 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
     IX86_ATTR_ISA ("avx512pf", OPT_mavx512pf),
     IX86_ATTR_ISA ("avx512er", OPT_mavx512er),
     IX86_ATTR_ISA ("avx512cd", OPT_mavx512cd),
+    IX86_ATTR_ISA ("avx512dq", OPT_mavx512dq),
+    IX86_ATTR_ISA ("avx512bw", OPT_mavx512bw),
+    IX86_ATTR_ISA ("avx512vl", OPT_mavx512vl),
     IX86_ATTR_ISA ("mmx",      OPT_mmmx),
     IX86_ATTR_ISA ("pclmul",   OPT_mpclmul),
     IX86_ATTR_ISA ("popcnt",   OPT_mpopcnt),
@@ -5027,7 +5057,7 @@ ix86_in_large_data_p (tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
       if (strcmp (section, ".ldata") == 0
          || strcmp (section, ".lbss") == 0)
        return true;
@@ -5038,8 +5068,11 @@ ix86_in_large_data_p (tree exp)
       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
 
       /* If this is an incomplete type with size 0, then we can't put it
-        in data because it might be too big when completed.  */
-      if (!size || size > ix86_section_threshold)
+        in data because it might be too big when completed.  Also,
+        int_size_in_bytes returns -1 if size can vary or is larger than
+        an integer in which case also it is safer to assume that it goes in
+        large data.  */
+      if (size <= 0 || size > ix86_section_threshold)
        return true;
     }
 
@@ -5147,7 +5180,7 @@ x86_64_elf_unique_section (tree decl, int reloc)
     {
       const char *prefix = NULL;
       /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
-      bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
+      bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
 
       switch (categorize_decl_for_section (decl, reloc))
        {
@@ -5192,7 +5225,7 @@ x86_64_elf_unique_section (tree decl, int reloc)
 
          string = ACONCAT ((linkonce, prefix, ".", name, NULL));
 
-         DECL_SECTION_NAME (decl) = build_string (strlen (string), string);
+         set_decl_section_name (decl, string);
          return;
        }
     }
@@ -5225,9 +5258,8 @@ x86_elf_aligned_common (FILE *file,
    ASM_OUTPUT_ALIGNED_BSS.  */
 
 void
-x86_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
-                       const char *name, unsigned HOST_WIDE_INT size,
-                       int align)
+x86_output_aligned_bss (FILE *file, tree decl, const char *name,
+                       unsigned HOST_WIDE_INT size, int align)
 {
   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
       && size > (unsigned int)ix86_section_threshold)
@@ -5357,7 +5389,7 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
 static tree
 ix86_handle_cconv_attribute (tree *node, tree name,
                                   tree args,
-                                  int flags ATTRIBUTE_UNUSED,
+                                  int,
                                   bool *no_add_attrs)
 {
   if (TREE_CODE (*node) != FUNCTION_TYPE
@@ -5501,8 +5533,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
    attributes that we expect elsewhere.  */
 
 static tree
-ix86_handle_tm_regparm_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
-                                 tree args ATTRIBUTE_UNUSED,
+ix86_handle_tm_regparm_attribute (tree *node, tree, tree,
                                  int flags, bool *no_add_attrs)
 {
   tree alt;
@@ -5645,7 +5676,7 @@ ix86_function_regparm (const_tree type, const_tree decl)
       && !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
-      struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE (decl));
+      cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE (decl));
       if (i && i->local && i->can_change_signature)
        {
          int local_regparm, globals = 0, regno;
@@ -5722,7 +5753,7 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
       && !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
-      struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
+      cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE(decl));
       if (i && i->local && i->can_change_signature)
        return TARGET_SSE2 ? 2 : 1;
     }
@@ -5814,7 +5845,7 @@ ix86_return_pops_args (tree fundecl, tree funtype, int size)
 /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook.  */
 
 static bool
-ix86_legitimate_combined_insn (rtx insn)
+ix86_legitimate_combined_insn (rtx_insn *insn)
 {
   /* Check operand constraints in case hard registers were propagated
      into insn pattern.  This check prevents combine pass from
@@ -5826,13 +5857,15 @@ ix86_legitimate_combined_insn (rtx insn)
       int i;
 
       extract_insn (insn);
-      preprocess_constraints ();
+      preprocess_constraints (insn);
 
-      for (i = 0; i < recog_data.n_operands; i++)
+      int n_operands = recog_data.n_operands;
+      int n_alternatives = recog_data.n_alternatives;
+      for (i = 0; i < n_operands; i++)
        {
          rtx op = recog_data.operand[i];
          enum machine_mode mode = GET_MODE (op);
-         struct operand_alternative *op_alt;
+         const operand_alternative *op_alt;
          int offset = 0;
          bool win;
          int j;
@@ -5867,19 +5900,22 @@ ix86_legitimate_combined_insn (rtx insn)
          if (!(REG_P (op) && HARD_REGISTER_P (op)))
            continue;
 
-         op_alt = recog_op_alt[i];
+         op_alt = recog_op_alt;
 
          /* Operand has no constraints, anything is OK.  */
-         win = !recog_data.n_alternatives;
+         win = !n_alternatives;
 
-         for (j = 0; j < recog_data.n_alternatives; j++)
+         alternative_mask preferred = get_preferred_alternatives (insn);
+         for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
            {
-             if (op_alt[j].anything_ok
-                 || (op_alt[j].matches != -1
+             if (!TEST_BIT (preferred, j))
+               continue;
+             if (op_alt[i].anything_ok
+                 || (op_alt[i].matches != -1
                      && operands_match_p
                          (recog_data.operand[i],
-                          recog_data.operand[op_alt[j].matches]))
-                 || reg_fits_class_p (op, op_alt[j].cl, offset, mode))
+                          recog_data.operand[op_alt[i].matches]))
+                 || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
                {
                  win = true;
                  break;
@@ -6109,6 +6145,68 @@ ix86_maybe_switch_abi (void)
     reinit_regs ();
 }
 
+/* Return 1 if pseudo register should be created and used to hold
+   GOT address for PIC code.  */
+static bool
+ix86_use_pseudo_pic_reg (void)
+{
+  if ((TARGET_64BIT
+       && (ix86_cmodel == CM_SMALL_PIC
+          || TARGET_PECOFF))
+      || !flag_pic)
+    return false;
+  return true;
+}
+
+/* Create and initialize PIC register if required.  */
+static void
+ix86_init_pic_reg (void)
+{
+  edge entry_edge;
+  rtx_insn *seq;
+
+  if (!ix86_use_pseudo_pic_reg ())
+    return;
+
+  start_sequence ();
+
+  if (TARGET_64BIT)
+    {
+      if (ix86_cmodel == CM_LARGE_PIC)
+       {
+         rtx_code_label *label;
+         rtx tmp_reg;
+
+         gcc_assert (Pmode == DImode);
+         label = gen_label_rtx ();
+         emit_label (label);
+         LABEL_PRESERVE_P (label) = 1;
+         tmp_reg = gen_rtx_REG (Pmode, R11_REG);
+         gcc_assert (REGNO (pic_offset_table_rtx) != REGNO (tmp_reg));
+         emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
+                                       label));
+         emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
+         emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
+                                   pic_offset_table_rtx, tmp_reg));
+       }
+      else
+       emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
+    }
+  else
+    {
+      rtx insn = emit_insn (gen_set_got (pic_offset_table_rtx));
+      RTX_FRAME_RELATED_P (insn) = 1;
+      add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
+    }
+
+  seq = get_insns ();
+  end_sequence ();
+
+  entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  insert_insn_on_edge (seq, entry_edge);
+  commit_one_edge_insertion (entry_edge);
+}
+
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
@@ -6126,7 +6224,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
 
   if (fndecl)
     {
-      i = cgraph_local_info (fndecl);
+      i = cgraph_node::local_info (fndecl);
       cum->call_abi = ix86_function_abi (fndecl);
     }
   else
@@ -6573,7 +6671,7 @@ classify_argument (enum machine_mode mode, const_tree type,
                                           bit_offset);
                  if (!num)
                    return 0;
-                 for (i = 0; i < num; i++)
+                 for (i = 0; i < num && i < words; i++)
                    classes[i] = merge_classes (subclasses[i], classes[i]);
                }
            }
@@ -7536,7 +7634,7 @@ ix86_function_arg (cumulative_args_t cum_v, enum machine_mode omode,
 
 static bool
 ix86_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode,
-                       const_tree type, bool named ATTRIBUTE_UNUSED)
+                       const_tree type, bool)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
@@ -7773,8 +7871,9 @@ ix86_function_value_regno_p (const unsigned int regno)
   switch (regno)
     {
     case AX_REG:
-    case DX_REG:
       return true;
+    case DX_REG:
+      return (!TARGET_64BIT || ix86_abi != MS_ABI);
     case DI_REG:
     case SI_REG:
       return TARGET_64BIT && ix86_abi != MS_ABI;
@@ -7964,8 +8063,7 @@ ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
 }
 
 static rtx
-ix86_function_value (const_tree valtype, const_tree fntype_or_decl,
-                    bool outgoing ATTRIBUTE_UNUSED)
+ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
 {
   enum machine_mode mode, orig_mode;
 
@@ -8239,7 +8337,8 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
   if (ix86_varargs_fpr_size)
     {
       enum machine_mode smode;
-      rtx label, test;
+      rtx_code_label *label;
+      rtx test;
 
       /* Now emit code to save SSE registers.  The AX parameter contains number
         of SSE parameter registers used to call this function, though all we
@@ -8306,8 +8405,7 @@ setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
 
 static void
 ix86_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode,
-                            tree type, int *pretend_size ATTRIBUTE_UNUSED,
-                            int no_rtl)
+                            tree type, int *, int no_rtl)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   CUMULATIVE_ARGS next_cum;
@@ -8377,7 +8475,8 @@ ix86_va_start (tree valist, rtx nextarg)
       scratch_regno = split_stack_prologue_scratch_regno ();
       if (scratch_regno != INVALID_REGNUM)
        {
-         rtx reg, seq;
+         rtx reg;
+         rtx_insn *seq;
 
          reg = gen_reg_rtx (Pmode);
          cfun->machine->split_stack_varargs_pointer = reg;
@@ -8966,7 +9065,7 @@ standard_sse_constant_p (rtx x)
    the constant X.  */
 
 const char *
-standard_sse_constant_opcode (rtx insn, rtx x)
+standard_sse_constant_opcode (rtx_insn *insn, rtx x)
 {
   switch (standard_sse_constant_p (x))
     {
@@ -8974,19 +9073,24 @@ standard_sse_constant_opcode (rtx insn, rtx x)
       switch (get_attr_mode (insn))
        {
        case MODE_XI:
-       case MODE_V16SF:
          return "vpxord\t%g0, %g0, %g0";
+       case MODE_V16SF:
+         return TARGET_AVX512DQ ? "vxorps\t%g0, %g0, %g0"
+                                : "vpxord\t%g0, %g0, %g0";
        case MODE_V8DF:
-         return "vpxorq\t%g0, %g0, %g0";
+         return TARGET_AVX512DQ ? "vxorpd\t%g0, %g0, %g0"
+                                : "vpxorq\t%g0, %g0, %g0";
        case MODE_TI:
-         return "%vpxor\t%0, %d0";
+         return TARGET_AVX512VL ? "vpxord\t%t0, %t0, %t0"
+                                : "%vpxor\t%0, %d0";
        case MODE_V2DF:
          return "%vxorpd\t%0, %d0";
        case MODE_V4SF:
          return "%vxorps\t%0, %d0";
 
        case MODE_OI:
-         return "vpxor\t%x0, %x0, %x0";
+         return TARGET_AVX512VL ? "vpxord\t%x0, %x0, %x0"
+                                : "vpxor\t%x0, %x0, %x0";
        case MODE_V4DF:
          return "vxorpd\t%x0, %x0, %x0";
        case MODE_V8SF:
@@ -8997,7 +9101,8 @@ standard_sse_constant_opcode (rtx insn, rtx x)
        }
 
     case 2:
-      if (get_attr_mode (insn) == MODE_XI
+      if (TARGET_AVX512VL
+         || get_attr_mode (insn) == MODE_XI
          || get_attr_mode (insn) == MODE_V8DF
          || get_attr_mode (insn) == MODE_V16SF)
        return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
@@ -9183,7 +9288,7 @@ ix86_code_end (void)
 #endif
       if (USE_HIDDEN_LINKONCE)
        {
-         DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
+         cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
 
          targetm.asm_out.unique_section (decl, 0);
          switch_to_section (get_named_section (decl, NULL, 0));
@@ -9344,6 +9449,9 @@ gen_pop (rtx arg)
 static unsigned int
 ix86_select_alt_pic_regnum (void)
 {
+  if (ix86_use_pseudo_pic_reg ())
+    return INVALID_REGNUM;
+
   if (crtl->is_leaf
       && !crtl->profile
       && !ix86_current_function_calls_tls_descriptor)
@@ -9368,6 +9476,7 @@ static bool
 ix86_save_reg (unsigned int regno, bool maybe_eh_return)
 {
   if (pic_offset_table_rtx
+      && !ix86_use_pseudo_pic_reg ()
       && regno == REAL_PIC_OFFSET_TABLE_REGNUM
       && (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
          || crtl->profile
@@ -9549,7 +9658,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
            && cfun->machine->use_fast_prologue_epilogue_nregs != frame->nregs)
     {
       int count = frame->nregs;
-      struct cgraph_node *node = cgraph_get_node (current_function_decl);
+      struct cgraph_node *node = cgraph_node::get (current_function_decl);
 
       cfun->machine->use_fast_prologue_epilogue_nregs = count;
 
@@ -10182,7 +10291,7 @@ ix86_get_drap_rtx (void)
       unsigned int regno = find_drap_reg ();
       rtx drap_vreg;
       rtx arg_ptr;
-      rtx seq, insn;
+      rtx_insn *seq, *insn;
 
       arg_ptr = gen_rtx_REG (Pmode, regno);
       crtl->drap_reg = arg_ptr;
@@ -10669,7 +10778,7 @@ ix86_finalize_stack_realign_flags (void)
                           HARD_FRAME_POINTER_REGNUM);
       FOR_EACH_BB_FN (bb, cfun)
         {
-          rtx insn;
+          rtx_insn *insn;
          FOR_BB_INSNS (bb, insn)
            if (NONDEBUG_INSN_P (insn)
                && requires_stack_frame_p (insn, prologue_used,
@@ -10720,7 +10829,6 @@ ix86_expand_prologue (void)
 {
   struct machine_function *m = cfun->machine;
   rtx insn, t;
-  bool pic_reg_used;
   struct ix86_frame frame;
   HOST_WIDE_INT allocate;
   bool int_registers_saved;
@@ -11167,59 +11275,6 @@ ix86_expand_prologue (void)
   if (!sse_registers_saved)
     ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
 
-  pic_reg_used = false;
-  /* We don't use pic-register for pe-coff target.  */
-  if (pic_offset_table_rtx
-      && !TARGET_PECOFF
-      && (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
-         || crtl->profile))
-    {
-      unsigned int alt_pic_reg_used = ix86_select_alt_pic_regnum ();
-
-      if (alt_pic_reg_used != INVALID_REGNUM)
-       SET_REGNO (pic_offset_table_rtx, alt_pic_reg_used);
-
-      pic_reg_used = true;
-    }
-
-  if (pic_reg_used)
-    {
-      if (TARGET_64BIT)
-       {
-         if (ix86_cmodel == CM_LARGE_PIC)
-           {
-             rtx label, tmp_reg;
-
-             gcc_assert (Pmode == DImode);
-             label = gen_label_rtx ();
-             emit_label (label);
-             LABEL_PRESERVE_P (label) = 1;
-             tmp_reg = gen_rtx_REG (Pmode, R11_REG);
-             gcc_assert (REGNO (pic_offset_table_rtx) != REGNO (tmp_reg));
-             insn = emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
-                                                  label));
-             insn = emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
-             insn = emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
-                                              pic_offset_table_rtx, tmp_reg));
-           }
-         else
-            insn = emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
-       }
-      else
-       {
-          insn = emit_insn (gen_set_got (pic_offset_table_rtx));
-         RTX_FRAME_RELATED_P (insn) = 1;
-         add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
-       }
-    }
-
-  /* In the pic_reg_used case, make sure that the got load isn't deleted
-     when mcount needs it.  Blockage to avoid call movement across mcount
-     call is emitted in generic code after the NOTE_INSN_PROLOGUE_END
-     note.  */
-  if (crtl->profile && !flag_fentry && pic_reg_used)
-    emit_insn (gen_prologue_use (pic_offset_table_rtx));
-
   if (crtl->drap_reg && !crtl->stack_realign_needed)
     {
       /* vDRAP is setup but after reload it turns out stack realign
@@ -11758,17 +11813,17 @@ ix86_expand_epilogue (int style)
 /* Reset from the function's potential modifications.  */
 
 static void
-ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
-                              HOST_WIDE_INT size ATTRIBUTE_UNUSED)
+ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED, HOST_WIDE_INT)
 {
-  if (pic_offset_table_rtx)
+  if (pic_offset_table_rtx
+      && !ix86_use_pseudo_pic_reg ())
     SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
 #if TARGET_MACHO
   /* Mach-O doesn't support labels at the end of objects, so if
      it looks like we might want one, insert a NOP.  */
   {
-    rtx insn = get_last_insn ();
-    rtx deleted_debug_label = NULL_RTX;
+    rtx_insn *insn = get_last_insn ();
+    rtx_insn *deleted_debug_label = NULL;
     while (insn
           && NOTE_P (insn)
           && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
@@ -11879,9 +11934,10 @@ ix86_expand_split_stack_prologue (void)
   struct ix86_frame frame;
   HOST_WIDE_INT allocate;
   unsigned HOST_WIDE_INT args_size;
-  rtx label, limit, current, jump_insn, allocate_rtx, call_insn, call_fusage;
+  rtx_code_label *label;
+  rtx limit, current, jump_insn, allocate_rtx, call_insn, call_fusage;
   rtx scratch_reg = NULL_RTX;
-  rtx varargs_label = NULL_RTX;
+  rtx_code_label *varargs_label = NULL;
   rtx fn;
 
   gcc_assert (flag_split_stack && reload_completed);
@@ -11947,7 +12003,10 @@ ix86_expand_split_stack_prologue (void)
                    REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100);
 
   if (split_stack_fn == NULL_RTX)
-    split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
+    {
+      split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
+      SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
+    }
   fn = split_stack_fn;
 
   /* Get more stack space.  We pass in the desired stack space and the
@@ -11992,12 +12051,15 @@ ix86_expand_split_stack_prologue (void)
          gcc_assert ((args_size & 0xffffffff) == args_size);
 
          if (split_stack_fn_large == NULL_RTX)
-           split_stack_fn_large =
-             gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
-
+           {
+             split_stack_fn_large =
+               gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
+             SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
+           }
          if (ix86_cmodel == CM_LARGE_PIC)
            {
-             rtx label, x;
+             rtx_code_label *label;
+             rtx x;
 
              label = gen_label_rtx ();
              emit_label (label);
@@ -12381,9 +12443,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
    requires to two regs - that would mean more pseudos with longer
    lifetimes.  */
 static int
-ix86_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
-                  addr_space_t as ATTRIBUTE_UNUSED,
-                  bool speed ATTRIBUTE_UNUSED)
+ix86_address_cost (rtx x, enum machine_mode, addr_space_t, bool)
 {
   struct ix86_address parts;
   int cost = 1;
@@ -12404,9 +12464,18 @@ ix86_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
              || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)))
     cost++;
 
+  /* When address base or index is "pic_offset_table_rtx" we don't increase
+     address cost.  When a memopt with "pic_offset_table_rtx" is not invariant
+     itself it most likely means that base or index is not invariant.
+     Therefore only "pic_offset_table_rtx" could be hoisted out, which is not
+     profitable for x86.  */
   if (parts.base
+      && (!pic_offset_table_rtx
+         || REGNO (pic_offset_table_rtx) != REGNO(parts.base))
       && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
       && parts.index
+      && (!pic_offset_table_rtx
+         || REGNO (pic_offset_table_rtx) != REGNO(parts.index))
       && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
       && parts.base != parts.index)
     cost++;
@@ -12450,7 +12519,7 @@ darwin_local_data_pic (rtx disp)
    satisfies CONSTANT_P.  */
 
 static bool
-ix86_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+ix86_legitimate_constant_p (enum machine_mode, rtx x)
 {
   switch (GET_CODE (x))
     {
@@ -12775,10 +12844,8 @@ legitimate_pic_address_disp_p (rtx disp)
    0 if it should not.  */
 
 bool
-ix86_legitimize_reload_address (rtx x,
-                               enum machine_mode mode ATTRIBUTE_UNUSED,
-                               int opnum, int type,
-                               int ind_levels ATTRIBUTE_UNUSED)
+ix86_legitimize_reload_address (rtx x, enum machine_mode, int opnum, int type,
+                               int)
 {
   /* Reload can generate:
 
@@ -12875,8 +12942,7 @@ ix86_validate_address_register (rtx op)
    be recognized.  */
 
 static bool
-ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
-                          rtx addr, bool strict)
+ix86_legitimate_address_p (enum machine_mode, rtx addr, bool strict)
 {
   struct ix86_address parts;
   rtx base, index, disp;
@@ -13084,6 +13150,15 @@ ix86_GOT_alias_set (void)
   return set;
 }
 
+/* Set regs_ever_live for PIC base address register
+   to true if required.  */
+static void
+set_pic_reg_ever_live ()
+{
+  if (reload_in_progress)
+    df_set_regs_ever_live (REGNO (pic_offset_table_rtx), true);
+}
+
 /* Return a legitimate reference for ORIG (an address) using the
    register REG.  If REG is 0, a new pseudo is generated.
 
@@ -13134,8 +13209,7 @@ legitimize_pic_address (rtx orig, rtx reg)
       /* This symbol may be referenced via a displacement from the PIC
         base address (@GOTOFF).  */
 
-      if (reload_in_progress)
-       df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
+      set_pic_reg_ever_live ();
       if (GET_CODE (addr) == CONST)
        addr = XEXP (addr, 0);
       if (GET_CODE (addr) == PLUS)
@@ -13167,8 +13241,7 @@ legitimize_pic_address (rtx orig, rtx reg)
       /* This symbol may be referenced via a displacement from the PIC
         base address (@GOTOFF).  */
 
-      if (reload_in_progress)
-       df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
+      set_pic_reg_ever_live ();
       if (GET_CODE (addr) == CONST)
        addr = XEXP (addr, 0);
       if (GET_CODE (addr) == PLUS)
@@ -13229,8 +13302,7 @@ legitimize_pic_address (rtx orig, rtx reg)
          /* This symbol must be referenced via a load from the
             Global Offset Table (@GOT).  */
 
-         if (reload_in_progress)
-           df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
+         set_pic_reg_ever_live ();
          new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
          new_rtx = gen_rtx_CONST (Pmode, new_rtx);
          if (TARGET_64BIT)
@@ -13282,8 +13354,7 @@ legitimize_pic_address (rtx orig, rtx reg)
            {
              if (!TARGET_64BIT)
                {
-                 if (reload_in_progress)
-                   df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
+                 set_pic_reg_ever_live ();
                  new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
                                            UNSPEC_GOTOFF);
                  new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
@@ -13467,7 +13538,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
          if (TARGET_64BIT)
            {
              rtx rax = gen_rtx_REG (Pmode, AX_REG);
-             rtx insns;
+             rtx_insn *insns;
 
              start_sequence ();
              emit_call_insn
@@ -13520,7 +13591,8 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
          if (TARGET_64BIT)
            {
              rtx rax = gen_rtx_REG (Pmode, AX_REG);
-             rtx insns, eqv;
+             rtx_insn *insns;
+             rtx eqv;
 
              start_sequence ();
              emit_call_insn
@@ -13578,8 +13650,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
        }
       else if (flag_pic)
        {
-         if (reload_in_progress)
-           df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
+         set_pic_reg_ever_live ();
          pic = pic_offset_table_rtx;
          type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
        }
@@ -13816,8 +13887,7 @@ legitimize_pe_coff_symbol (rtx addr, bool inreg)
    See comments by legitimize_pic_address in i386.c for details.  */
 
 static rtx
-ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
-                        enum machine_mode mode)
+ix86_legitimize_address (rtx x, rtx, enum machine_mode mode)
 {
   int changed = 0;
   unsigned log;
@@ -14211,8 +14281,20 @@ ix86_pic_register_p (rtx x)
   if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
     return (pic_offset_table_rtx
            && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
+  else if (!REG_P (x))
+    return false;
+  else if (pic_offset_table_rtx)
+    {
+      if (REGNO (x) == REGNO (pic_offset_table_rtx))
+       return true;
+      if (HARD_REGISTER_P (x)
+         && !HARD_REGISTER_P (pic_offset_table_rtx)
+         && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
+       return true;
+      return false;
+    }
   else
-    return REG_P (x) && REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
+    return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
 }
 
 /* Helper function for ix86_delegitimize_address.
@@ -14385,11 +14467,20 @@ ix86_delegitimize_address (rtx x)
         leal (%ebx, %ecx, 4), %ecx
         ...
         movl foo@GOTOFF(%ecx), %edx
-        in which case we return (%ecx - %ebx) + foo.  */
-      if (pic_offset_table_rtx)
+        in which case we return (%ecx - %ebx) + foo
+        or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
+        and reload has completed.  */
+      if (pic_offset_table_rtx
+         && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
         result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
                                                     pic_offset_table_rtx),
                               result);
+      else if (pic_offset_table_rtx && !TARGET_MACHO && !TARGET_VXWORKS_RTP)
+       {
+         rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
+         tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
+         result = gen_rtx_PLUS (Pmode, tmp, result);
+       }
       else
        return orig_x;
     }
@@ -14679,7 +14770,7 @@ print_reg (rtx x, int code, FILE *file)
     case 8:
     case 4:
     case 12:
-      if (! ANY_FP_REG_P (x))
+      if (! ANY_FP_REG_P (x) && ! ANY_MASK_REG_P (x))
        putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file);
       /* FALLTHRU */
     case 16:
@@ -14728,41 +14819,6 @@ print_reg (rtx x, int code, FILE *file)
     }
 }
 
-/* Locate some local-dynamic symbol still in use by this function
-   so that we can print its name in some tls_local_dynamic_base
-   pattern.  */
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
-  rtx x = *px;
-
-  if (GET_CODE (x) == SYMBOL_REF
-      && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
-    {
-      cfun->machine->some_ld_name = XSTR (x, 0);
-      return 1;
-    }
-
-  return 0;
-}
-
-static const char *
-get_some_local_dynamic_name (void)
-{
-  rtx insn;
-
-  if (cfun->machine->some_ld_name)
-    return cfun->machine->some_ld_name;
-
-  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
-    if (NONDEBUG_INSN_P (insn)
-       && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
-      return cfun->machine->some_ld_name;
-
-  return NULL;
-}
-
 /* Meaning of CODE:
    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
    C -- print opcode suffix for set/cmov insn.
@@ -16059,7 +16115,7 @@ output_387_binary_op (rtx insn, rtx *operands)
 /* Check if a 256bit AVX register is referenced inside of EXP.   */
 
 static int
-ix86_check_avx256_register (rtx *pexp, void *data ATTRIBUTE_UNUSED)
+ix86_check_avx256_register (rtx *pexp, void *)
 {
   rtx exp = *pexp;
 
@@ -16076,7 +16132,7 @@ ix86_check_avx256_register (rtx *pexp, void *data ATTRIBUTE_UNUSED)
 /* Return needed mode for entity in optimize_mode_switching pass.  */
 
 static int
-ix86_avx_u128_mode_needed (rtx insn)
+ix86_avx_u128_mode_needed (rtx_insn *insn)
 {
   if (CALL_P (insn))
     {
@@ -16114,7 +16170,7 @@ ix86_avx_u128_mode_needed (rtx insn)
    prior to the execution of insn.  */
 
 static int
-ix86_i387_mode_needed (int entity, rtx insn)
+ix86_i387_mode_needed (int entity, rtx_insn *insn)
 {
   enum attr_i387_cw mode;
 
@@ -16167,7 +16223,7 @@ ix86_i387_mode_needed (int entity, rtx insn)
    prior to the execution of insn.  */
 
 static int
-ix86_mode_needed (int entity, rtx insn)
+ix86_mode_needed (int entity, rtx_insn *insn)
 {
   switch (entity)
     {
@@ -16187,7 +16243,7 @@ ix86_mode_needed (int entity, rtx insn)
 /* Check if a 256bit AVX register is referenced in stores.   */
  
 static void
-ix86_check_avx256_stores (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data)
+ix86_check_avx256_stores (rtx dest, const_rtx, void *data)
  {
    if (ix86_check_avx256_register (&dest, NULL))
     {
@@ -16199,7 +16255,7 @@ ix86_check_avx256_stores (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data)
 /* Calculate mode of upper 128bit AVX registers after the insn.  */
 
 static int
-ix86_avx_u128_mode_after (int mode, rtx insn)
+ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
 {
   rtx pat = PATTERN (insn);
 
@@ -16226,7 +16282,7 @@ ix86_avx_u128_mode_after (int mode, rtx insn)
 /* Return the mode that an insn results in.  */
 
 int
-ix86_mode_after (int entity, int mode, rtx insn)
+ix86_mode_after (int entity, int mode, rtx_insn *insn)
 {
   switch (entity)
     {
@@ -16315,7 +16371,7 @@ ix86_mode_exit (int entity)
 }
 
 static int
-ix86_mode_priority (int entity ATTRIBUTE_UNUSED, int n)
+ix86_mode_priority (int, int n)
 {
   return n;
 }
@@ -16440,7 +16496,8 @@ ix86_avx_emit_vzeroupper (HARD_REG_SET regs_live)
    are to be inserted.  */
 
 static void
-ix86_emit_mode_set (int entity, int mode, HARD_REG_SET regs_live)
+ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
+                   HARD_REG_SET regs_live)
 {
   switch (entity)
     {
@@ -16466,7 +16523,7 @@ ix86_emit_mode_set (int entity, int mode, HARD_REG_SET regs_live)
    operand may be [SDX]Fmode.  */
 
 const char *
-output_fix_trunc (rtx insn, rtx *operands, bool fisttp)
+output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
 {
   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
   int dimode_p = GET_MODE (operands[0]) == DImode;
@@ -17507,8 +17564,10 @@ ix86_expand_vector_logical_operator (enum rtx_code code, enum machine_mode mode,
        {
        case V4SFmode:
        case V8SFmode:
+       case V16SFmode:
        case V2DFmode:
        case V4DFmode:
+       case V8DFmode:
          dst = gen_reg_rtx (GET_MODE (SUBREG_REG (op1)));
          if (GET_CODE (op2) == CONST_VECTOR)
            {
@@ -17644,7 +17703,7 @@ void
 ix86_split_idivmod (enum machine_mode mode, rtx operands[],
                    bool signed_p)
 {
-  rtx end_label, qimode_label;
+  rtx_code_label *end_label, *qimode_label;
   rtx insn, div, mod;
   rtx scratch, tmp0, tmp1, tmp2;
   rtx (*gen_divmod4_1) (rtx, rtx, rtx, rtx);
@@ -17738,14 +17797,6 @@ ix86_split_idivmod (enum machine_mode mode, rtx operands[],
   emit_label (end_label);
 }
 
-/* Whether it is OK to emit CFI directives when emitting asm code.  */
-
-bool
-ix86_emit_cfi ()
-{
-  return dwarf2out_do_cfi_asm ();
-}
-
 #define LEA_MAX_STALL (3)
 #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
 
@@ -17755,10 +17806,9 @@ ix86_emit_cfi ()
    go to next cycle if there is some dependecy.  */
 
 static unsigned int
-increase_distance (rtx prev, rtx next, unsigned int distance)
+increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
 {
-  df_ref *use_rec;
-  df_ref *def_rec;
+  df_ref def, use;
 
   if (!prev || !next)
     return distance + (distance & 1) + 2;
@@ -17766,10 +17816,10 @@ increase_distance (rtx prev, rtx next, unsigned int distance)
   if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
     return distance + 1;
 
-  for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++)
-    for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++)
-      if (!DF_REF_IS_ARTIFICIAL (*def_rec)
-         && DF_REF_REGNO (*use_rec) == DF_REF_REGNO (*def_rec))
+  FOR_EACH_INSN_USE (use, next)
+    FOR_EACH_INSN_DEF (def, prev)
+      if (!DF_REF_IS_ARTIFICIAL (def)
+         && DF_REF_REGNO (use) == DF_REF_REGNO (def))
        return distance + (distance & 1) + 2;
 
   return distance + 1;
@@ -17782,16 +17832,14 @@ static bool
 insn_defines_reg (unsigned int regno1, unsigned int regno2,
                  rtx insn)
 {
-  df_ref *def_rec;
+  df_ref def;
 
-  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
-    if (DF_REF_REG_DEF_P (*def_rec)
-       && !DF_REF_IS_ARTIFICIAL (*def_rec)
-       && (regno1 == DF_REF_REGNO (*def_rec)
-           || regno2 == DF_REF_REGNO (*def_rec)))
-      {
-       return true;
-      }
+  FOR_EACH_INSN_DEF (def, insn)
+    if (DF_REF_REG_DEF_P (def)
+       && !DF_REF_IS_ARTIFICIAL (def)
+       && (regno1 == DF_REF_REGNO (def)
+           || regno2 == DF_REF_REGNO (def)))
+      return true;
 
   return false;
 }
@@ -17802,10 +17850,10 @@ insn_defines_reg (unsigned int regno1, unsigned int regno2,
 static bool
 insn_uses_reg_mem (unsigned int regno, rtx insn)
 {
-  df_ref *use_rec;
+  df_ref use;
 
-  for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
-    if (DF_REF_REG_MEM_P (*use_rec) && regno == DF_REF_REGNO (*use_rec))
+  FOR_EACH_INSN_USE (use, insn)
+    if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
       return true;
 
   return false;
@@ -17823,12 +17871,12 @@ insn_uses_reg_mem (unsigned int regno, rtx insn)
 
 static int
 distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
-                              rtx insn, int distance,
-                              rtx start, bool *found)
+                              rtx_insn *insn, int distance,
+                              rtx_insn *start, bool *found)
 {
   basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
-  rtx prev = start;
-  rtx next = NULL;
+  rtx_insn *prev = start;
+  rtx_insn *next = NULL;
 
   *found = false;
 
@@ -17870,7 +17918,7 @@ distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
 
 static int
 distance_non_agu_define (unsigned int regno1, unsigned int regno2,
-                        rtx insn)
+                        rtx_insn *insn)
 {
   basic_block bb = BLOCK_FOR_INSN (insn);
   int distance = 0;
@@ -17947,12 +17995,12 @@ distance_non_agu_define (unsigned int regno1, unsigned int regno2,
 
 static int
 distance_agu_use_in_bb (unsigned int regno,
-                       rtx insn, int distance, rtx start,
+                       rtx_insn *insn, int distance, rtx_insn *start,
                        bool *found, bool *redefined)
 {
   basic_block bb = NULL;
-  rtx next = start;
-  rtx prev = NULL;
+  rtx_insn *next = start;
+  rtx_insn *prev = NULL;
 
   *found = false;
   *redefined = false;
@@ -18006,7 +18054,7 @@ distance_agu_use_in_bb (unsigned int regno,
    a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set.  */
 
 static int
-distance_agu_use (unsigned int regno0, rtx insn)
+distance_agu_use (unsigned int regno0, rtx_insn *insn)
 {
   basic_block bb = BLOCK_FOR_INSN (insn);
   int distance = 0;
@@ -18080,7 +18128,7 @@ distance_agu_use (unsigned int regno0, rtx insn)
    SPLIT_COST cycles higher latency than lea latency.  */
 
 static bool
-ix86_lea_outperforms (rtx insn, unsigned int regno0, unsigned int regno1,
+ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
                      unsigned int regno2, int split_cost, bool has_scale)
 {
   int dist_define, dist_use;
@@ -18134,18 +18182,18 @@ ix86_lea_outperforms (rtx insn, unsigned int regno0, unsigned int regno1,
    false otherwise.  */
 
 static bool
-ix86_ok_to_clobber_flags (rtx insn)
+ix86_ok_to_clobber_flags (rtx_insn *insn)
 {
   basic_block bb = BLOCK_FOR_INSN (insn);
-  df_ref *use;
+  df_ref use;
   bitmap live;
 
   while (insn)
     {
       if (NONDEBUG_INSN_P (insn))
        {
-         for (use = DF_INSN_USES (insn); *use; use++)
-           if (DF_REF_REG_USE_P (*use) && DF_REF_REGNO (*use) == FLAGS_REG)
+         FOR_EACH_INSN_USE (use, insn)
+           if (DF_REF_REG_USE_P (use) && DF_REF_REGNO (use) == FLAGS_REG)
              return false;
 
          if (insn_defines_reg (FLAGS_REG, INVALID_REGNUM, insn))
@@ -18166,7 +18214,7 @@ ix86_ok_to_clobber_flags (rtx insn)
    move and add to avoid AGU stalls.  */
 
 bool
-ix86_avoid_lea_for_add (rtx insn, rtx operands[])
+ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
 {
   unsigned int regno0, regno1, regno2;
 
@@ -18194,7 +18242,7 @@ ix86_avoid_lea_for_add (rtx insn, rtx operands[])
    instruction.  */
 
 bool
-ix86_use_lea_for_mov (rtx insn, rtx operands[])
+ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
 {
   unsigned int regno0, regno1;
 
@@ -18216,7 +18264,7 @@ ix86_use_lea_for_mov (rtx insn, rtx operands[])
    instructions to avoid AGU stalls. */
 
 bool
-ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
+ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
 {
   unsigned int regno0, regno1, regno2;
   int split_cost;
@@ -18320,10 +18368,10 @@ ix86_emit_binop (enum rtx_code code, enum machine_mode mode,
 /* Return true if regno1 def is nearest to the insn.  */
 
 static bool
-find_nearest_reg_def (rtx insn, int regno1, int regno2)
+find_nearest_reg_def (rtx_insn *insn, int regno1, int regno2)
 {
-  rtx prev = insn;
-  rtx start = BB_HEAD (BLOCK_FOR_INSN (insn));
+  rtx_insn *prev = insn;
+  rtx_insn *start = BB_HEAD (BLOCK_FOR_INSN (insn));
 
   if (insn == start)
     return false;
@@ -18351,7 +18399,7 @@ find_nearest_reg_def (rtx insn, int regno1, int regno2)
    at lea position.  */
 
 void
-ix86_split_lea_for_addr (rtx insn, rtx operands[], enum machine_mode mode)
+ix86_split_lea_for_addr (rtx_insn *insn, rtx operands[], enum machine_mode mode)
 {
   unsigned int regno0, regno1, regno2;
   struct ix86_address parts;
@@ -18471,7 +18519,7 @@ ix86_split_lea_for_addr (rtx insn, rtx operands[], enum machine_mode mode)
    used soon, LEA is better and otherwise ADD is better.  */
 
 bool
-ix86_lea_for_add_ok (rtx insn, rtx operands[])
+ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
 {
   unsigned int regno0 = true_regnum (operands[0]);
   unsigned int regno1 = true_regnum (operands[1]);
@@ -18570,8 +18618,8 @@ ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
    appropriate constraints.  */
 
 bool
-ix86_unary_operator_ok (enum rtx_code code ATTRIBUTE_UNUSED,
-                       enum machine_mode mode ATTRIBUTE_UNUSED,
+ix86_unary_operator_ok (enum rtx_code,
+                       enum machine_mode,
                        rtx operands[2])
 {
   /* If one of operands is memory, source and destination must match.  */
@@ -18725,8 +18773,7 @@ ix86_expand_convert_uns_didf_sse (rtx target, rtx input)
 
 /* Not used, but eases macroization of patterns.  */
 void
-ix86_expand_convert_uns_sixf_sse (rtx target ATTRIBUTE_UNUSED,
-                                 rtx input ATTRIBUTE_UNUSED)
+ix86_expand_convert_uns_sixf_sse (rtx, rtx)
 {
   gcc_unreachable ();
 }
@@ -19346,7 +19393,7 @@ ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1)
    Return the appropriate mode to use.  */
 
 enum machine_mode
-ix86_fp_compare_mode (enum rtx_code code ATTRIBUTE_UNUSED)
+ix86_fp_compare_mode (enum rtx_code)
 {
   /* ??? In order to make all comparisons reversible, we do all comparisons
      non-trapping when compiling for IEEE.  Once gcc is able to distinguish
@@ -19561,7 +19608,7 @@ ix86_fp_comparison_cost (enum rtx_code code)
    (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test).  */
 
 enum ix86_fpcmp_strategy
-ix86_fp_comparison_strategy (enum rtx_code code ATTRIBUTE_UNUSED)
+ix86_fp_comparison_strategy (enum rtx_code)
 {
   /* Do fcomi/sahf based test when profitable.  */
 
@@ -19906,7 +19953,8 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
     case TImode:
       /* Expand DImode branch into multiple compare+branch.  */
       {
-       rtx lo[2], hi[2], label2;
+       rtx lo[2], hi[2];
+       rtx_code_label *label2;
        enum rtx_code code1, code2, code3;
        enum machine_mode submode;
 
@@ -20078,7 +20126,8 @@ ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop)
 
   if (SCALAR_FLOAT_MODE_P (mode))
     {
-      rtx compare_op, compare_seq;
+      rtx compare_op;
+      rtx_insn *compare_seq;
 
       gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
 
@@ -20196,7 +20245,8 @@ bool
 ix86_expand_int_movcc (rtx operands[])
 {
   enum rtx_code code = GET_CODE (operands[1]), compare_code;
-  rtx compare_seq, compare_op;
+  rtx_insn *compare_seq;
+  rtx compare_op;
   enum machine_mode mode = GET_MODE (operands[0]);
   bool sign_bit_compare_p = false;
   rtx op0 = XEXP (operands[1], 0);
@@ -21006,6 +21056,12 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
            }
          break;
 
+       case V64QImode:
+         gen = gen_avx512bw_blendmv64qi;
+         break;
+       case V32HImode:
+         gen = gen_avx512bw_blendmv32hi;
+         break;
        case V16SImode:
          gen = gen_avx512f_blendmv16si;
          break;
@@ -21322,6 +21378,8 @@ ix86_expand_int_vcond (rtx operands[])
                }
              break;
 
+           case V64QImode:
+           case V32HImode:
            case V32QImode:
            case V16HImode:
            case V16QImode:
@@ -21364,33 +21422,132 @@ ix86_expand_int_vcond (rtx operands[])
   return true;
 }
 
+/* AVX512F does support 64-byte integer vector operations,
+   thus the longest vector we are faced with is V64QImode.  */
+#define MAX_VECT_LEN   64
+
+struct expand_vec_perm_d
+{
+  rtx target, op0, op1;
+  unsigned char perm[MAX_VECT_LEN];
+  enum machine_mode vmode;
+  unsigned char nelt;
+  bool one_operand_p;
+  bool testing_p;
+};
+
 static bool
-ix86_expand_vec_perm_vpermi2 (rtx target, rtx op0, rtx mask, rtx op1)
+ix86_expand_vec_perm_vpermi2 (rtx target, rtx op0, rtx mask, rtx op1,
+                             struct expand_vec_perm_d *d)
 {
-  enum machine_mode mode = GET_MODE (op0);
+  /* ix86_expand_vec_perm_vpermi2 is called from both const and non-const
+     expander, so args are either in d, or in op0, op1 etc.  */
+  enum machine_mode mode = GET_MODE (d ? d->op0 : op0);
+  enum machine_mode maskmode = mode;
+  rtx (*gen) (rtx, rtx, rtx, rtx) = NULL;
+
   switch (mode)
     {
+    case V8HImode:
+      if (TARGET_AVX512VL && TARGET_AVX512BW)
+       gen = gen_avx512vl_vpermi2varv8hi3;
+      break;
+    case V16HImode:
+      if (TARGET_AVX512VL && TARGET_AVX512BW)
+       gen = gen_avx512vl_vpermi2varv16hi3;
+      break;
+    case V32HImode:
+      if (TARGET_AVX512BW)
+       gen = gen_avx512bw_vpermi2varv32hi3;
+      break;
+    case V4SImode:
+      if (TARGET_AVX512VL)
+       gen = gen_avx512vl_vpermi2varv4si3;
+      break;
+    case V8SImode:
+      if (TARGET_AVX512VL)
+       gen = gen_avx512vl_vpermi2varv8si3;
+      break;
     case V16SImode:
-      emit_insn (gen_avx512f_vpermi2varv16si3 (target, op0,
-                                             force_reg (V16SImode, mask),
-                                             op1));
-      return true;
+      if (TARGET_AVX512F)
+       gen = gen_avx512f_vpermi2varv16si3;
+      break;
+    case V4SFmode:
+      if (TARGET_AVX512VL)
+       {
+         gen = gen_avx512vl_vpermi2varv4sf3;
+         maskmode = V4SImode;
+       }
+      break;
+    case V8SFmode:
+      if (TARGET_AVX512VL)
+       {
+         gen = gen_avx512vl_vpermi2varv8sf3;
+         maskmode = V8SImode;
+       }
+      break;
     case V16SFmode:
-      emit_insn (gen_avx512f_vpermi2varv16sf3 (target, op0,
-                                             force_reg (V16SImode, mask),
-                                             op1));
-      return true;
+      if (TARGET_AVX512F)
+       {
+         gen = gen_avx512f_vpermi2varv16sf3;
+         maskmode = V16SImode;
+       }
+      break;
+    case V2DImode:
+      if (TARGET_AVX512VL)
+       gen = gen_avx512vl_vpermi2varv2di3;
+      break;
+    case V4DImode:
+      if (TARGET_AVX512VL)
+       gen = gen_avx512vl_vpermi2varv4di3;
+      break;
     case V8DImode:
-      emit_insn (gen_avx512f_vpermi2varv8di3 (target, op0,
-                                            force_reg (V8DImode, mask), op1));
-      return true;
+      if (TARGET_AVX512F)
+       gen = gen_avx512f_vpermi2varv8di3;
+      break;
+    case V2DFmode:
+      if (TARGET_AVX512VL)
+       {
+         gen = gen_avx512vl_vpermi2varv2df3;
+         maskmode = V2DImode;
+       }
+      break;
+    case V4DFmode:
+      if (TARGET_AVX512VL)
+       {
+         gen = gen_avx512vl_vpermi2varv4df3;
+         maskmode = V4DImode;
+       }
+      break;
     case V8DFmode:
-      emit_insn (gen_avx512f_vpermi2varv8df3 (target, op0,
-                                            force_reg (V8DImode, mask), op1));
-      return true;
+      if (TARGET_AVX512F)
+       {
+         gen = gen_avx512f_vpermi2varv8df3;
+         maskmode = V8DImode;
+       }
+      break;
     default:
-      return false;
+      break;
+    }
+
+  if (gen == NULL)
+    return false;
+
+  /* ix86_expand_vec_perm_vpermi2 is called from both const and non-const
+     expander, so args are either in d, or in op0, op1 etc.  */
+  if (d)
+    {
+      rtx vec[64];
+      target = d->target;
+      op0 = d->op0;
+      op1 = d->op1;
+      for (int i = 0; i < d->nelt; ++i)
+       vec[i] = GEN_INT (d->perm[i]);
+      mask = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (d->nelt, vec));
     }
+
+  emit_insn (gen (target, op0, force_reg (maskmode, mask), op1));
+  return true;
 }
 
 /* Expand a variable vector permutation.  */
@@ -21413,7 +21570,7 @@ ix86_expand_vec_perm (rtx operands[])
   e = GET_MODE_UNIT_SIZE (mode);
   gcc_assert (w <= 64);
 
-  if (ix86_expand_vec_perm_vpermi2 (target, op0, mask, op1))
+  if (ix86_expand_vec_perm_vpermi2 (target, op0, mask, op1, NULL))
     return;
 
   if (TARGET_AVX2)
@@ -21541,7 +21698,7 @@ ix86_expand_vec_perm (rtx operands[])
          t1 = gen_reg_rtx (V32QImode);
          t2 = gen_reg_rtx (V32QImode);
          t3 = gen_reg_rtx (V32QImode);
-         vt2 = GEN_INT (128);
+         vt2 = GEN_INT (-128);
          for (i = 0; i < 32; i++)
            vec[i] = vt2;
          vt = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, vec));
@@ -21785,6 +21942,15 @@ ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
 
       switch (imode)
        {
+       case V64QImode:
+         if (unsigned_p)
+           unpack = gen_avx512bw_zero_extendv32qiv32hi2;
+         else
+           unpack = gen_avx512bw_sign_extendv32qiv32hi2;
+         halfmode = V32QImode;
+         extract
+           = high_p ? gen_vec_extract_hi_v64qi : gen_vec_extract_lo_v64qi;
+         break;
        case V32QImode:
          if (unsigned_p)
            unpack = gen_avx2_zero_extendv16qiv16hi2;
@@ -22715,10 +22881,10 @@ predict_jump (int prob)
 
 /* Helper function for the string operations below.  Dest VARIABLE whether
    it is aligned to VALUE bytes.  If true, jump to the label.  */
-static rtx
+static rtx_code_label *
 ix86_expand_aligntest (rtx variable, int value, bool epilogue)
 {
-  rtx label = gen_label_rtx ();
+  rtx_code_label *label = gen_label_rtx ();
   rtx tmpcount = gen_reg_rtx (GET_MODE (variable));
   if (GET_MODE (variable) == DImode)
     emit_insn (gen_anddi3 (tmpcount, variable, GEN_INT (value)));
@@ -22813,7 +22979,8 @@ expand_set_or_movmem_via_loop (rtx destmem, rtx srcmem,
                               rtx count, enum machine_mode mode, int unroll,
                               int expected_size, bool issetmem)
 {
-  rtx out_label, top_label, iter, tmp;
+  rtx_code_label *out_label, *top_label;
+  rtx iter, tmp;
   enum machine_mode iter_mode = counter_mode (count);
   int piece_size_n = GET_MODE_SIZE (mode) * unroll;
   rtx piece_size = GEN_INT (piece_size_n);
@@ -23130,7 +23297,7 @@ expand_movmem_epilogue (rtx destmem, rtx srcmem,
     {
       if (max_size > 4)
        {
-         rtx label = ix86_expand_aligntest (count, 4, true);
+         rtx_code_label *label = ix86_expand_aligntest (count, 4, true);
          src = change_address (srcmem, SImode, srcptr);
          dest = change_address (destmem, SImode, destptr);
          emit_insn (gen_strmov (destptr, dest, srcptr, src));
@@ -23139,7 +23306,7 @@ expand_movmem_epilogue (rtx destmem, rtx srcmem,
        }
       if (max_size > 2)
        {
-         rtx label = ix86_expand_aligntest (count, 2, true);
+         rtx_code_label *label = ix86_expand_aligntest (count, 2, true);
          src = change_address (srcmem, HImode, srcptr);
          dest = change_address (destmem, HImode, destptr);
          emit_insn (gen_strmov (destptr, dest, srcptr, src));
@@ -23148,7 +23315,7 @@ expand_movmem_epilogue (rtx destmem, rtx srcmem,
        }
       if (max_size > 1)
        {
-         rtx label = ix86_expand_aligntest (count, 1, true);
+         rtx_code_label *label = ix86_expand_aligntest (count, 1, true);
          src = change_address (srcmem, QImode, srcptr);
          dest = change_address (destmem, QImode, destptr);
          emit_insn (gen_strmov (destptr, dest, srcptr, src));
@@ -23163,7 +23330,7 @@ expand_movmem_epilogue (rtx destmem, rtx srcmem,
 
       if (max_size > 4)
        {
-         rtx label = ix86_expand_aligntest (count, 4, true);
+         rtx_code_label *label = ix86_expand_aligntest (count, 4, true);
          src = change_address (srcmem, SImode, srcptr);
          dest = change_address (destmem, SImode, destptr);
          emit_move_insn (dest, src);
@@ -23176,7 +23343,7 @@ expand_movmem_epilogue (rtx destmem, rtx srcmem,
        }
       if (max_size > 2)
        {
-         rtx label = ix86_expand_aligntest (count, 2, true);
+         rtx_code_label *label = ix86_expand_aligntest (count, 2, true);
          tmp = gen_rtx_PLUS (Pmode, srcptr, offset);
          src = change_address (srcmem, HImode, tmp);
          tmp = gen_rtx_PLUS (Pmode, destptr, offset);
@@ -23191,7 +23358,7 @@ expand_movmem_epilogue (rtx destmem, rtx srcmem,
        }
       if (max_size > 1)
        {
-         rtx label = ix86_expand_aligntest (count, 1, true);
+         rtx_code_label *label = ix86_expand_aligntest (count, 1, true);
          tmp = gen_rtx_PLUS (Pmode, srcptr, offset);
          src = change_address (srcmem, QImode, tmp);
          tmp = gen_rtx_PLUS (Pmode, destptr, offset);
@@ -23307,7 +23474,7 @@ expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
     }
   if (max_size > 16)
     {
-      rtx label = ix86_expand_aligntest (count, 16, true);
+      rtx_code_label *label = ix86_expand_aligntest (count, 16, true);
       if (TARGET_64BIT)
        {
          dest = change_address (destmem, DImode, destptr);
@@ -23331,7 +23498,7 @@ expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
     }
   if (max_size > 8)
     {
-      rtx label = ix86_expand_aligntest (count, 8, true);
+      rtx_code_label *label = ix86_expand_aligntest (count, 8, true);
       if (TARGET_64BIT)
        {
          dest = change_address (destmem, DImode, destptr);
@@ -23349,7 +23516,7 @@ expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
     }
   if (max_size > 4)
     {
-      rtx label = ix86_expand_aligntest (count, 4, true);
+      rtx_code_label *label = ix86_expand_aligntest (count, 4, true);
       dest = change_address (destmem, SImode, destptr);
       emit_insn (gen_strset (destptr, dest, gen_lowpart (SImode, value)));
       emit_label (label);
@@ -23357,7 +23524,7 @@ expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
     }
   if (max_size > 2)
     {
-      rtx label = ix86_expand_aligntest (count, 2, true);
+      rtx_code_label *label = ix86_expand_aligntest (count, 2, true);
       dest = change_address (destmem, HImode, destptr);
       emit_insn (gen_strset (destptr, dest, gen_lowpart (HImode, value)));
       emit_label (label);
@@ -23365,7 +23532,7 @@ expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
     }
   if (max_size > 1)
     {
-      rtx label = ix86_expand_aligntest (count, 1, true);
+      rtx_code_label *label = ix86_expand_aligntest (count, 1, true);
       dest = change_address (destmem, QImode, destptr);
       emit_insn (gen_strset (destptr, dest, gen_lowpart (QImode, value)));
       emit_label (label);
@@ -23389,7 +23556,7 @@ expand_set_or_movmem_prologue (rtx destmem, rtx srcmem,
     {
       if (align <= i)
        {
-         rtx label = ix86_expand_aligntest (destptr, i, false);
+         rtx_code_label *label = ix86_expand_aligntest (destptr, i, false);
          if (issetmem)
            {
              if (vec_value && i > GET_MODE_SIZE (GET_MODE (value)))
@@ -23418,7 +23585,7 @@ expand_small_movmem_or_setmem (rtx destmem, rtx srcmem,
                               rtx count, int size,
                               rtx done_label, bool issetmem)
 {
-  rtx label = ix86_expand_aligntest (count, size, false);
+  rtx_code_label *label = ix86_expand_aligntest (count, size, false);
   enum machine_mode mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 1);
   rtx modesize;
   int n;
@@ -23543,7 +23710,7 @@ expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src
                                                            enum machine_mode mode,
                                                            rtx value, rtx vec_value,
                                                            rtx *count,
-                                                           rtx *done_label,
+                                                           rtx_code_label **done_label,
                                                            int size,
                                                            int desired_align,
                                                            int align,
@@ -23551,7 +23718,7 @@ expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src
                                                            bool dynamic_check,
                                                            bool issetmem)
 {
-  rtx loop_label = NULL, label;
+  rtx_code_label *loop_label = NULL, *label;
   int n;
   rtx modesize;
   int prolog_size = 0;
@@ -23828,7 +23995,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size,
 {
   const struct stringop_algs * algs;
   bool optimize_for_speed;
-  int max = -1;
+  int max = 0;
   const struct processor_costs *cost;
   int i;
   bool any_alg_usable_p = false;
@@ -23866,7 +24033,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size,
   /* If expected size is not known but max size is small enough
      so inline version is a win, set expected size into
      the range.  */
-  if (max > 1 && (unsigned HOST_WIDE_INT) max >= max_size
+  if (((max > 1 && (unsigned HOST_WIDE_INT) max >= max_size) || max == -1)
       && expected_size == -1)
     expected_size = min_size / 2 + max_size / 2;
 
@@ -23955,7 +24122,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size,
             *dynamic_check = 128;
           return loop_1_byte;
         }
-      if (max == -1)
+      if (max <= 0)
        max = 4096;
       alg = decide_alg (count, max / 2, min_size, max_size, memset,
                        zero_memset, dynamic_check, noalign);
@@ -24149,9 +24316,9 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
 {
   rtx destreg;
   rtx srcreg = NULL;
-  rtx label = NULL;
+  rtx_code_label *label = NULL;
   rtx tmp;
-  rtx jump_around_label = NULL;
+  rtx_code_label *jump_around_label = NULL;
   HOST_WIDE_INT align = 1;
   unsigned HOST_WIDE_INT count = 0;
   HOST_WIDE_INT expected_size = -1;
@@ -24425,7 +24592,7 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
        }
       else
        {
-         rtx hot_label = gen_label_rtx ();
+         rtx_code_label *hot_label = gen_label_rtx ();
          if (jump_around_label == NULL_RTX)
            jump_around_label = gen_label_rtx ();
          emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
@@ -24623,10 +24790,10 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx)
 {
   int align;
   rtx tmp;
-  rtx align_2_label = NULL_RTX;
-  rtx align_3_label = NULL_RTX;
-  rtx align_4_label = gen_label_rtx ();
-  rtx end_0_label = gen_label_rtx ();
+  rtx_code_label *align_2_label = NULL;
+  rtx_code_label *align_3_label = NULL;
+  rtx_code_label *align_4_label = gen_label_rtx ();
+  rtx_code_label *end_0_label = gen_label_rtx ();
   rtx mem;
   rtx tmpreg = gen_reg_rtx (SImode);
   rtx scratch = gen_reg_rtx (SImode);
@@ -24750,7 +24917,7 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx)
     }
   else
     {
-       rtx end_2_label = gen_label_rtx ();
+       rtx_code_label *end_2_label = gen_label_rtx ();
        /* Is zero in the first two bytes? */
 
        emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
@@ -24870,9 +25037,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
                  rtx callarg2,
                  rtx pop, bool sibcall)
 {
-  unsigned int const cregs_size
-    = ARRAY_SIZE (x86_64_ms_sysv_extra_clobbered_registers);
-  rtx vec[3 + cregs_size];
+  rtx vec[3];
   rtx use = NULL, call;
   unsigned int vec_len = 0;
 
@@ -24896,7 +25061,12 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
                  && DEFAULT_ABI != MS_ABI))
          && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
          && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
-       use_reg (&use, pic_offset_table_rtx);
+       {
+         use_reg (&use, gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM));
+         if (ix86_use_pseudo_pic_reg ())
+           emit_move_insn (gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM),
+                           pic_offset_table_rtx);
+       }
     }
 
   if (TARGET_64BIT && INTVAL (callarg2) >= 0)
@@ -24935,18 +25105,16 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
   if (TARGET_64BIT_MS_ABI
       && (!callarg2 || INTVAL (callarg2) != -2))
     {
-      unsigned i;
-
-      vec[vec_len++] = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx),
-                                      UNSPEC_MS_TO_SYSV_CALL);
+      int const cregs_size
+       = ARRAY_SIZE (x86_64_ms_sysv_extra_clobbered_registers);
+      int i;
 
       for (i = 0; i < cregs_size; i++)
        {
          int regno = x86_64_ms_sysv_extra_clobbered_registers[i];
          enum machine_mode mode = SSE_REGNO_P (regno) ? TImode : DImode;
 
-         vec[vec_len++]
-           = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno));
+         clobber_reg (&use, gen_rtx_REG (mode, regno));
        }
     }
 
@@ -24962,7 +25130,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
 /* Output the assembly for a call instruction.  */
 
 const char *
-ix86_output_call_insn (rtx insn, rtx call_op)
+ix86_output_call_insn (rtx_insn *insn, rtx call_op)
 {
   bool direct_p = constant_call_address_operand (call_op, VOIDmode);
   bool seh_nop_p = false;
@@ -24987,7 +25155,7 @@ ix86_output_call_insn (rtx insn, rtx call_op)
      circumstances.  Determine if we have one of those.  */
   if (TARGET_SEH)
     {
-      rtx i;
+      rtx_insn *i;
 
       for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
        {
@@ -25066,7 +25234,7 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
 
   s->next = ix86_stack_locals;
   ix86_stack_locals = s;
-  return validize_mem (s->rtl);
+  return validize_mem (copy_rtx (s->rtl));
 }
 
 static void
@@ -25218,7 +25386,7 @@ memory_address_length (rtx addr, bool lea)
 /* Compute default value for "length_immediate" attribute.  When SHORTFORM
    is set, expect that insn have 8bit immediate alternative.  */
 int
-ix86_attr_length_immediate_default (rtx insn, bool shortform)
+ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
 {
   int len = 0;
   int i;
@@ -25277,7 +25445,7 @@ ix86_attr_length_immediate_default (rtx insn, bool shortform)
 
 /* Compute default value for "length_address" attribute.  */
 int
-ix86_attr_length_address_default (rtx insn)
+ix86_attr_length_address_default (rtx_insn *insn)
 {
   int i;
 
@@ -25299,7 +25467,7 @@ ix86_attr_length_address_default (rtx insn)
   for (i = recog_data.n_operands - 1; i >= 0; --i)
     if (MEM_P (recog_data.operand[i]))
       {
-        constrain_operands_cached (reload_completed);
+        constrain_operands_cached (insn, reload_completed);
         if (which_alternative != -1)
          {
            const char *constraints = recog_data.constraints[i];
@@ -25323,7 +25491,8 @@ ix86_attr_length_address_default (rtx insn)
    2 or 3 byte VEX prefix and 1 opcode byte.  */
 
 int
-ix86_attr_length_vex_default (rtx insn, bool has_0f_opcode, bool has_vex_w)
+ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
+                             bool has_vex_w)
 {
   int i;
 
@@ -25401,7 +25570,7 @@ ix86_issue_rate (void)
    by DEP_INSN and nothing set by DEP_INSN.  */
 
 static bool
-ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
+ix86_flags_dependent (rtx_insn *insn, rtx_insn *dep_insn, enum attr_type insn_type)
 {
   rtx set, set2;
 
@@ -25446,7 +25615,7 @@ ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
    SET_INSN.  */
 
 bool
-ix86_agi_dependent (rtx set_insn, rtx use_insn)
+ix86_agi_dependent (rtx_insn *set_insn, rtx_insn *use_insn)
 {
   int i;
   extract_insn_cached (use_insn);
@@ -25509,7 +25678,7 @@ exact_dependency_1 (rtx addr, rtx insn)
 /* Return true if there exists exact dependency for store & load, i.e.
    the same memory address is used in them.  */
 static bool
-exact_store_load_dependency (rtx store, rtx load)
+exact_store_load_dependency (rtx_insn *store, rtx_insn *load)
 {
   rtx set1, set2;
 
@@ -25527,7 +25696,7 @@ exact_store_load_dependency (rtx store, rtx load)
 }
 
 static int
-ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
+ix86_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
 {
   enum attr_type insn_type, dep_insn_type;
   enum attr_memory memory;
@@ -25805,27 +25974,28 @@ ix86_macro_fusion_p ()
    "Intel Architectures Optimization Reference Manual". */
 
 static bool
-ix86_macro_fusion_pair_p (rtx condgen, rtx condjmp)
+ix86_macro_fusion_pair_p (rtx_insn *condgen, rtx_insn *condjmp)
 {
   rtx src, dest;
-  rtx single_set = single_set (condgen);
   enum rtx_code ccode;
   rtx compare_set = NULL_RTX, test_if, cond;
   rtx alu_set = NULL_RTX, addr = NULL_RTX;
 
+  if (!any_condjump_p (condjmp))
+    return false;
+
   if (get_attr_type (condgen) != TYPE_TEST
       && get_attr_type (condgen) != TYPE_ICMP
       && get_attr_type (condgen) != TYPE_INCDEC
       && get_attr_type (condgen) != TYPE_ALU)
     return false;
 
-  if (single_set == NULL_RTX
+  compare_set = single_set (condgen);
+  if (compare_set == NULL_RTX
       && !TARGET_FUSE_ALU_AND_BRANCH)
     return false;
 
-  if (single_set != NULL_RTX)
-    compare_set = single_set;
-  else
+  if (compare_set == NULL_RTX)
     {
       int i;
       rtx pat = PATTERN (condgen);
@@ -25912,9 +26082,10 @@ ix86_macro_fusion_pair_p (rtx condgen, rtx condjmp)
        ready list.
    Return index of IMUL producer if it was found and -1 otherwise.  */
 static int
-do_reorder_for_imul (rtx *ready, int n_ready)
+do_reorder_for_imul (rtx_insn **ready, int n_ready)
 {
-  rtx insn, set, insn1, insn2;
+  rtx_insn *insn;
+  rtx set, insn1, insn2;
   sd_iterator_def sd_it;
   dep_t dep;
   int index = -1;
@@ -25989,10 +26160,10 @@ do_reorder_for_imul (rtx *ready, int n_ready)
    scheduled earlier. Applied for Silvermont only.
    Return true if top 2 insns must be interchanged.  */
 static bool
-swap_top_of_ready_list (rtx *ready, int n_ready)
+swap_top_of_ready_list (rtx_insn **ready, int n_ready)
 {
-  rtx top = ready[n_ready - 1];
-  rtx next = ready[n_ready - 2];
+  rtx_insn *top = ready[n_ready - 1];
+  rtx_insn *next = ready[n_ready - 2];
   rtx set;
   sd_iterator_def sd_it;
   dep_t dep;
@@ -26060,13 +26231,13 @@ swap_top_of_ready_list (rtx *ready, int n_ready)
 /* Perform possible reodering of ready list for Atom/Silvermont only.
    Return issue rate.  */
 static int
-ix86_sched_reorder (FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
-                  int clock_var)
+ix86_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
+                   int *pn_ready, int clock_var)
 {
   int issue_rate = -1;
   int n_ready = *pn_ready;
   int i;
-  rtx insn;
+  rtx_insn *insn;
   int index = -1;
 
   /* Set up issue rate.  */
@@ -26146,12 +26317,12 @@ insn_is_function_arg (rtx insn, bool* is_spilled)
 /* Add output dependencies for chain of function adjacent arguments if only
    there is a move to likely spilled HW register.  Return first argument
    if at least one dependence was added or NULL otherwise.  */
-static rtx
-add_parameter_dependencies (rtx call, rtx head)
+static rtx_insn *
+add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
 {
-  rtx insn;
-  rtx last = call;
-  rtx first_arg = NULL;
+  rtx_insn *insn;
+  rtx_insn *last = call;
+  rtx_insn *first_arg = NULL;
   bool is_spilled = false;
 
   head = PREV_INSN (head);
@@ -26201,7 +26372,7 @@ add_parameter_dependencies (rtx call, rtx head)
 /* Add output or anti dependency from insn to first_arg to restrict its code
    motion.  */
 static void
-avoid_func_arg_motion (rtx first_arg, rtx insn)
+avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
 {
   rtx set;
   rtx tmp;
@@ -26223,9 +26394,9 @@ avoid_func_arg_motion (rtx first_arg, rtx insn)
 /* Avoid cross block motion of function argument through adding dependency
    from the first non-jump instruction in bb.  */
 static void
-add_dependee_for_func_arg (rtx arg, basic_block bb)
+add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
 {
-  rtx insn = BB_END (bb);
+  rtx_insn *insn = BB_END (bb);
 
   while (insn)
     {
@@ -26247,10 +26418,10 @@ add_dependee_for_func_arg (rtx arg, basic_block bb)
 /* Hook for pre-reload schedule - avoid motion of function arguments
    passed in likely spilled HW registers.  */
 static void
-ix86_dependencies_evaluation_hook (rtx head, rtx tail)
+ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
 {
-  rtx insn;
-  rtx first_arg = NULL;
+  rtx_insn *insn;
+  rtx_insn *first_arg = NULL;
   if (reload_completed)
     return;
   while (head != tail && DEBUG_INSN_P (head))
@@ -26300,7 +26471,7 @@ ix86_dependencies_evaluation_hook (rtx head, rtx tail)
    moves from function argument registers at the top of the function entry
    and moves from function return value registers after call.  */
 static int
-ix86_adjust_priority (rtx insn, int priority)
+ix86_adjust_priority (rtx_insn *insn, int priority)
 {
   rtx set;
 
@@ -26376,18 +26547,18 @@ core2i7_dfa_post_advance_cycle (void)
   data->ifetch_block_n_insns = 0;
 }
 
-static int min_insn_size (rtx);
+static int min_insn_size (rtx_insn *);
 
 /* Filter out insns from ready_try that the core will not be able to issue
    on current cycle due to decoder.  */
 static void
 core2i7_first_cycle_multipass_filter_ready_try
 (const_ix86_first_cycle_multipass_data_t data,
- char *ready_try, int n_ready, bool first_cycle_insn_p)
signed char *ready_try, int n_ready, bool first_cycle_insn_p)
 {
   while (n_ready--)
     {
-      rtx insn;
+      rtx_insn *insn;
       int insn_size;
 
       if (ready_try[n_ready])
@@ -26415,7 +26586,8 @@ core2i7_first_cycle_multipass_filter_ready_try
 
 /* Prepare for a new round of multipass lookahead scheduling.  */
 static void
-core2i7_first_cycle_multipass_begin (void *_data, char *ready_try, int n_ready,
+core2i7_first_cycle_multipass_begin (void *_data,
+                                    signed char *ready_try, int n_ready,
                                     bool first_cycle_insn_p)
 {
   ix86_first_cycle_multipass_data_t data
@@ -26436,8 +26608,9 @@ core2i7_first_cycle_multipass_begin (void *_data, char *ready_try, int n_ready,
 /* INSN is being issued in current solution.  Account for its impact on
    the decoder model.  */
 static void
-core2i7_first_cycle_multipass_issue (void *_data, char *ready_try, int n_ready,
-                                    rtx insn, const void *_prev_data)
+core2i7_first_cycle_multipass_issue (void *_data,
+                                    signed char *ready_try, int n_ready,
+                                    rtx_insn *insn, const void *_prev_data)
 {
   ix86_first_cycle_multipass_data_t data
     = (ix86_first_cycle_multipass_data_t) _data;
@@ -26474,7 +26647,7 @@ core2i7_first_cycle_multipass_issue (void *_data, char *ready_try, int n_ready,
 /* Revert the effect on ready_try.  */
 static void
 core2i7_first_cycle_multipass_backtrack (const void *_data,
-                                        char *ready_try,
+                                        signed char *ready_try,
                                         int n_ready ATTRIBUTE_UNUSED)
 {
   const_ix86_first_cycle_multipass_data_t data
@@ -26522,9 +26695,7 @@ core2i7_first_cycle_multipass_fini (void *_data)
 
 /* Prepare for scheduling pass.  */
 static void
-ix86_sched_init_global (FILE *dump ATTRIBUTE_UNUSED,
-                       int verbose ATTRIBUTE_UNUSED,
-                       int max_uid ATTRIBUTE_UNUSED)
+ix86_sched_init_global (FILE *, int, int)
 {
   /* Install scheduling hooks for current CPU.  Some of these hooks are used
      in time-critical parts of the scheduler, so we only set them up when
@@ -28099,6 +28270,12 @@ enum ix86_builtins
   IX86_BUILTIN_GATHERDIV8SI,
 
   /* AVX512F */
+  IX86_BUILTIN_SI512_SI256,
+  IX86_BUILTIN_PD512_PD256,
+  IX86_BUILTIN_PS512_PS256,
+  IX86_BUILTIN_SI512_SI,
+  IX86_BUILTIN_PD512_PD,
+  IX86_BUILTIN_PS512_PS,
   IX86_BUILTIN_ADDPD512,
   IX86_BUILTIN_ADDPS512,
   IX86_BUILTIN_ADDSD_ROUND,
@@ -28750,6 +28927,10 @@ enum ix86_builtins
   IX86_BUILTIN_ADDCARRYX32,
   IX86_BUILTIN_ADDCARRYX64,
 
+  /* SBB instructions.  */
+  IX86_BUILTIN_SBB32,
+  IX86_BUILTIN_SBB64,
+
   /* FSGSBASE instructions.  */
   IX86_BUILTIN_RDFSBASE32,
   IX86_BUILTIN_RDFSBASE64,
@@ -28985,7 +29166,7 @@ static const struct builtin_description bdesc_special_args[] =
   /* 80387 (for use internally for atomic compound assignment).  */
   { 0, CODE_FOR_fnstenv, "__builtin_ia32_fnstenv", IX86_BUILTIN_FNSTENV, UNKNOWN, (int) VOID_FTYPE_PVOID },
   { 0, CODE_FOR_fldenv, "__builtin_ia32_fldenv", IX86_BUILTIN_FLDENV, UNKNOWN, (int) VOID_FTYPE_PCVOID },
-  { 0, CODE_FOR_fnstsw, "__builtin_ia32_fnstsw", IX86_BUILTIN_FNSTSW, UNKNOWN, (int) VOID_FTYPE_PUSHORT },
+  { 0, CODE_FOR_fnstsw, "__builtin_ia32_fnstsw", IX86_BUILTIN_FNSTSW, UNKNOWN, (int) USHORT_FTYPE_VOID },
   { 0, CODE_FOR_fnclex, "__builtin_ia32_fnclex", IX86_BUILTIN_FNCLEX, UNKNOWN, (int) VOID_FTYPE_VOID },
 
   /* MMX */
@@ -29957,8 +30138,8 @@ static const struct builtin_description bdesc_args[] =
   { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permv4df, "__builtin_ia32_permdf256", IX86_BUILTIN_VPERMDF256, UNKNOWN, (int) V4DF_FTYPE_V4DF_INT },
   { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permv4di, "__builtin_ia32_permdi256", IX86_BUILTIN_VPERMDI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT },
   { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permv2ti, "__builtin_ia32_permti256", IX86_BUILTIN_VPERMTI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT },
-  { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_extracti128, "__builtin_ia32_extract128i256", IX86_BUILTIN_VEXTRACT128I256, UNKNOWN, (int) V2DI_FTYPE_V4DI_INT },
-  { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_inserti128, "__builtin_ia32_insert128i256", IX86_BUILTIN_VINSERT128I256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI_INT },
+  { OPTION_MASK_ISA_AVX2, CODE_FOR_avx_vextractf128v4di, "__builtin_ia32_extract128i256", IX86_BUILTIN_VEXTRACT128I256, UNKNOWN, (int) V2DI_FTYPE_V4DI_INT },
+  { OPTION_MASK_ISA_AVX2, CODE_FOR_avx_vinsertf128v4di, "__builtin_ia32_insert128i256", IX86_BUILTIN_VINSERT128I256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI_INT },
   { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv4di, "__builtin_ia32_psllv4di", IX86_BUILTIN_PSLLVV4DI, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
   { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv2di, "__builtin_ia32_psllv2di", IX86_BUILTIN_PSLLVV2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
   { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv8si, "__builtin_ia32_psllv8si", IX86_BUILTIN_PSLLVV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
@@ -29996,6 +30177,12 @@ static const struct builtin_description bdesc_args[] =
   { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pext_di3, "__builtin_ia32_pext_di", IX86_BUILTIN_PEXT64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
 
   /* AVX512F */
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_si512_256si, "__builtin_ia32_si512_256si", IX86_BUILTIN_SI512_SI256, UNKNOWN, (int) V16SI_FTYPE_V8SI },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_ps512_256ps, "__builtin_ia32_ps512_256ps", IX86_BUILTIN_PS512_PS256, UNKNOWN, (int) V16SF_FTYPE_V8SF },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_pd512_256pd, "__builtin_ia32_pd512_256pd", IX86_BUILTIN_PD512_PD256, UNKNOWN, (int) V8DF_FTYPE_V4DF },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_si512_si, "__builtin_ia32_si512_si", IX86_BUILTIN_SI512_SI, UNKNOWN, (int) V16SI_FTYPE_V4SI },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_ps512_ps, "__builtin_ia32_ps512_ps", IX86_BUILTIN_PS512_PS, UNKNOWN, (int) V16SF_FTYPE_V4SF },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_pd512_pd, "__builtin_ia32_pd512_pd", IX86_BUILTIN_PD512_PD, UNKNOWN, (int) V8DF_FTYPE_V2DF },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_alignv16si_mask, "__builtin_ia32_alignd512_mask", IX86_BUILTIN_ALIGND512, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_INT_V16SI_HI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_alignv8di_mask, "__builtin_ia32_alignq512_mask", IX86_BUILTIN_ALIGNQ512, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_INT_V8DI_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_blendmv16si, "__builtin_ia32_blendmd_512_mask", IX86_BUILTIN_BLENDMD512, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_HI },
@@ -30014,7 +30201,7 @@ static const struct builtin_description bdesc_args[] =
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_compressv16sf_mask, "__builtin_ia32_compresssf512_mask", IX86_BUILTIN_COMPRESSPS512, UNKNOWN, (int) V16SF_FTYPE_V16SF_V16SF_HI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_floatv8siv8df2_mask, "__builtin_ia32_cvtdq2pd512_mask", IX86_BUILTIN_CVTDQ2PD512, UNKNOWN, (int) V8DF_FTYPE_V8SI_V8DF_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_vcvtps2ph512_mask,  "__builtin_ia32_vcvtps2ph512_mask", IX86_BUILTIN_CVTPS2PH512, UNKNOWN, (int) V16HI_FTYPE_V16SF_INT_V16HI_HI },
-  { OPTION_MASK_ISA_AVX512F, CODE_FOR_ufloatv8siv8df_mask, "__builtin_ia32_cvtudq2pd512_mask", IX86_BUILTIN_CVTUDQ2PD512, UNKNOWN, (int) V8DF_FTYPE_V8SI_V8DF_QI },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_ufloatv8siv8df2_mask, "__builtin_ia32_cvtudq2pd512_mask", IX86_BUILTIN_CVTUDQ2PD512, UNKNOWN, (int) V8DF_FTYPE_V8SI_V8DF_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_cvtusi2sd32, "__builtin_ia32_cvtusi2sd32", IX86_BUILTIN_CVTUSI2SD32, UNKNOWN, (int) V2DF_FTYPE_V2DF_UINT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_expandv8df_mask, "__builtin_ia32_expanddf512_mask", IX86_BUILTIN_EXPANDPD512, UNKNOWN, (int) V8DF_FTYPE_V8DF_V8DF_QI },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_expandv8df_maskz, "__builtin_ia32_expanddf512_maskz", IX86_BUILTIN_EXPANDPD512Z, UNKNOWN, (int) V8DF_FTYPE_V8DF_V8DF_QI },
@@ -30236,7 +30423,7 @@ static const struct builtin_description bdesc_round_args[] =
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_floatv16siv16sf2_mask_round, "__builtin_ia32_cvtdq2ps512_mask", IX86_BUILTIN_CVTDQ2PS512, UNKNOWN, (int) V16SF_FTYPE_V16SI_V16SF_HI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_cvtpd2dq512_mask_round, "__builtin_ia32_cvtpd2dq512_mask", IX86_BUILTIN_CVTPD2DQ512, UNKNOWN, (int) V8SI_FTYPE_V8DF_V8SI_QI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_cvtpd2ps512_mask_round,  "__builtin_ia32_cvtpd2ps512_mask", IX86_BUILTIN_CVTPD2PS512, UNKNOWN, (int) V8SF_FTYPE_V8DF_V8SF_QI_INT },
-  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_ufix_notruncv8dfv8si_mask_round, "__builtin_ia32_cvtpd2udq512_mask", IX86_BUILTIN_CVTPD2UDQ512, UNKNOWN, (int) V8SI_FTYPE_V8DF_V8SI_QI_INT },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_ufix_notruncv8dfv8si2_mask_round, "__builtin_ia32_cvtpd2udq512_mask", IX86_BUILTIN_CVTPD2UDQ512, UNKNOWN, (int) V8SI_FTYPE_V8DF_V8SI_QI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_vcvtph2ps512_mask_round,  "__builtin_ia32_vcvtph2ps512_mask", IX86_BUILTIN_CVTPH2PS512, UNKNOWN, (int) V16SF_FTYPE_V16HI_V16SF_HI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_fix_notruncv16sfv16si_mask_round, "__builtin_ia32_cvtps2dq512_mask", IX86_BUILTIN_CVTPS2DQ512, UNKNOWN, (int) V16SI_FTYPE_V16SF_V16SI_HI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_cvtps2pd512_mask_round, "__builtin_ia32_cvtps2pd512_mask", IX86_BUILTIN_CVTPS2PD512, UNKNOWN, (int) V8DF_FTYPE_V8SF_V8DF_QI_INT },
@@ -30272,8 +30459,8 @@ static const struct builtin_description bdesc_round_args[] =
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_sgetexpv4sf_round, "__builtin_ia32_getexpss128_round", IX86_BUILTIN_GETEXPSS128, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_getmantv8df_mask_round, "__builtin_ia32_getmantpd512_mask", IX86_BUILTIN_GETMANTPD512, UNKNOWN, (int) V8DF_FTYPE_V8DF_INT_V8DF_QI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_getmantv16sf_mask_round, "__builtin_ia32_getmantps512_mask", IX86_BUILTIN_GETMANTPS512, UNKNOWN, (int) V16SF_FTYPE_V16SF_INT_V16SF_HI_INT },
-  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_getmantv2df_round, "__builtin_ia32_getmantsd_round", IX86_BUILTIN_GETMANTSD128, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT_INT },
-  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_getmantv4sf_round, "__builtin_ia32_getmantss_round", IX86_BUILTIN_GETMANTSS128, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT_INT },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_vgetmantv2df_round, "__builtin_ia32_getmantsd_round", IX86_BUILTIN_GETMANTSD128, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT_INT },
+  { OPTION_MASK_ISA_AVX512F, CODE_FOR_avx512f_vgetmantv4sf_round, "__builtin_ia32_getmantss_round", IX86_BUILTIN_GETMANTSS128, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_smaxv8df3_mask_round, "__builtin_ia32_maxpd512_mask", IX86_BUILTIN_MAXPD512, UNKNOWN, (int) V8DF_FTYPE_V8DF_V8DF_V8DF_QI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_smaxv16sf3_mask_round, "__builtin_ia32_maxps512_mask", IX86_BUILTIN_MAXPS512, UNKNOWN, (int) V16SF_FTYPE_V16SF_V16SF_V16SF_HI_INT },
   { OPTION_MASK_ISA_AVX512F, CODE_FOR_sse2_vmsmaxv2df3_round, "__builtin_ia32_maxsd_round", IX86_BUILTIN_MAXSD_ROUND, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
@@ -31179,6 +31366,14 @@ ix86_init_mmx_sse_builtins (void)
               UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
               IX86_BUILTIN_ADDCARRYX64);
 
+  /* SBB */
+  def_builtin (0, "__builtin_ia32_sbb_u32",
+              UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_SBB32);
+  def_builtin (OPTION_MASK_ISA_64BIT,
+              "__builtin_ia32_sbb_u64",
+              UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
+              IX86_BUILTIN_SBB64);
+
   /* Read/write FLAGS.  */
   def_builtin (~OPTION_MASK_ISA_64BIT, "__builtin_ia32_readeflags_u32",
                UNSIGNED_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
@@ -32033,10 +32228,10 @@ ix86_get_function_versions_dispatcher (void *decl)
  
   gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn));
 
-  node = cgraph_get_node (fn);
+  node = cgraph_node::get (fn);
   gcc_assert (node != NULL);
 
-  node_v = get_cgraph_node_version (node);
+  node_v = node->function_version ();
   gcc_assert (node_v != NULL);
  
   if (node_v->dispatcher_resolver != NULL)
@@ -32083,11 +32278,11 @@ ix86_get_function_versions_dispatcher (void *decl)
       /* Right now, the dispatching is done via ifunc.  */
       dispatch_decl = make_dispatcher_decl (default_node->decl);
 
-      dispatcher_node = cgraph_get_create_node (dispatch_decl);
+      dispatcher_node = cgraph_node::get_create (dispatch_decl);
       gcc_assert (dispatcher_node != NULL);
       dispatcher_node->dispatcher_function = 1;
       dispatcher_version_info
-       = insert_new_cgraph_node_version (dispatcher_node);
+       = dispatcher_node->insert_new_function_version ();
       dispatcher_version_info->next = default_version_info;
       dispatcher_node->definition = 1;
 
@@ -32196,8 +32391,8 @@ make_resolver_func (const tree default_decl,
   push_cfun (DECL_STRUCT_FUNCTION (decl));
   *empty_bb = init_lowered_empty_function (decl, false);
 
-  cgraph_add_new_function (decl, true);
-  cgraph_call_function_insertion_hooks (cgraph_get_create_node (decl));
+  cgraph_node::add_new_function (decl, true);
+  symtab->call_cgraph_insertion_hooks (cgraph_node::get_create (decl));
 
   pop_cfun ();
 
@@ -32208,7 +32403,7 @@ make_resolver_func (const tree default_decl,
 
   /* Create the alias for dispatch to resolver here.  */
   /*cgraph_create_function_alias (dispatch_decl, decl);*/
-  cgraph_same_body_alias (NULL, dispatch_decl, decl);
+  cgraph_node::create_same_body_alias (dispatch_decl, decl);
   XDELETEVEC (resolver_name);
   return decl;
 }
@@ -32232,7 +32427,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
 
   node = (cgraph_node *)node_p;
 
-  node_version_info = get_cgraph_node_version (node);
+  node_version_info = node->function_version ();
   gcc_assert (node->dispatcher_function
              && node_version_info != NULL);
 
@@ -32270,7 +32465,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
     }
 
   dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb);
-  rebuild_cgraph_edges (); 
+  cgraph_edge::rebuild_edges ();
   pop_cfun ();
   return resolver_decl;
 }
@@ -32459,7 +32654,7 @@ fold_builtin_cpu (tree fndecl, tree *args)
                                        "__cpu_model");
 
 
-  varpool_add_new_variable (__cpu_model_var);
+  varpool_node::add (__cpu_model_var);
 
   gcc_assert ((args != NULL) && (*args != NULL));
 
@@ -32754,7 +32949,7 @@ ix86_init_builtins (void)
 /* Return the ix86 builtin for CODE.  */
 
 static tree
-ix86_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+ix86_builtin_decl (unsigned code, bool)
 {
   if (code >= IX86_BUILTIN_MAX)
     return error_mark_node;
@@ -33633,7 +33828,10 @@ ix86_expand_args_builtin (const struct builtin_description *d,
     case V16SI_FTYPE_V16SI:
     case V16SI_FTYPE_INT:
     case V16SF_FTYPE_FLOAT:
+    case V16SF_FTYPE_V8SF:
+    case V16SI_FTYPE_V8SI:
     case V16SF_FTYPE_V4SF:
+    case V16SI_FTYPE_V4SI:
     case V16SF_FTYPE_V16SF:
     case V8HI_FTYPE_V8DI:
     case V8UHI_FTYPE_V8UHI:
@@ -33646,6 +33844,7 @@ ix86_expand_args_builtin (const struct builtin_description *d,
     case V8DI_FTYPE_V8DI:
     case V8DF_FTYPE_DOUBLE:
     case V8DF_FTYPE_V4DF:
+    case V8DF_FTYPE_V2DF:
     case V8DF_FTYPE_V8DF:
     case V8DF_FTYPE_V8SI:
       nargs = 1;
@@ -34031,8 +34230,8 @@ ix86_expand_args_builtin (const struct builtin_description *d,
          if (!match)
            switch (icode)
              {
-             case CODE_FOR_avx2_inserti128:
-             case CODE_FOR_avx2_extracti128:
+             case CODE_FOR_avx_vinsertf128v4di:
+             case CODE_FOR_avx_vextractf128v4di:
                error ("the last argument must be an 1-bit immediate");
                return const0_rtx;
 
@@ -34040,6 +34239,14 @@ ix86_expand_args_builtin (const struct builtin_description *d,
              case CODE_FOR_avx512f_cmpv16si3_mask:
              case CODE_FOR_avx512f_ucmpv8di3_mask:
              case CODE_FOR_avx512f_ucmpv16si3_mask:
+             case CODE_FOR_avx512vl_cmpv4di3_mask:
+             case CODE_FOR_avx512vl_cmpv8si3_mask:
+             case CODE_FOR_avx512vl_ucmpv4di3_mask:
+             case CODE_FOR_avx512vl_ucmpv8si3_mask:
+             case CODE_FOR_avx512vl_cmpv2di3_mask:
+             case CODE_FOR_avx512vl_cmpv4si3_mask:
+             case CODE_FOR_avx512vl_ucmpv2di3_mask:
+             case CODE_FOR_avx512vl_ucmpv4si3_mask:
                error ("the last argument must be a 3-bit immediate");
                return const0_rtx;
 
@@ -34061,6 +34268,16 @@ ix86_expand_args_builtin (const struct builtin_description *d,
              case CODE_FOR_avx_vpermilv4df:
              case CODE_FOR_avx512f_getmantv8df_mask:
              case CODE_FOR_avx512f_getmantv16sf_mask:
+             case CODE_FOR_avx512vl_getmantv8sf_mask:
+             case CODE_FOR_avx512vl_getmantv4df_mask:
+             case CODE_FOR_avx512vl_getmantv4sf_mask:
+             case CODE_FOR_avx512vl_getmantv2df_mask:
+             case CODE_FOR_avx512dq_rangepv8df_mask_round:
+             case CODE_FOR_avx512dq_rangepv16sf_mask_round:
+             case CODE_FOR_avx512dq_rangepv4df_mask:
+             case CODE_FOR_avx512dq_rangepv8sf_mask:
+             case CODE_FOR_avx512dq_rangepv2df_mask:
+             case CODE_FOR_avx512dq_rangepv4sf_mask:
                error ("the last argument must be a 4-bit immediate");
                return const0_rtx;
 
@@ -34075,6 +34292,12 @@ ix86_expand_args_builtin (const struct builtin_description *d,
              case CODE_FOR_avx512f_vinserti32x4_mask:
              case CODE_FOR_avx512f_vextractf32x4_mask:
              case CODE_FOR_avx512f_vextracti32x4_mask:
+             case CODE_FOR_sse2_shufpd:
+             case CODE_FOR_sse2_shufpd_mask:
+             case CODE_FOR_avx512dq_shuf_f64x2_mask:
+             case CODE_FOR_avx512dq_shuf_i64x2_mask:
+             case CODE_FOR_avx512vl_shuf_i32x4_mask:
+             case CODE_FOR_avx512vl_shuf_f32x4_mask:
                error ("the last argument must be a 2-bit immediate");
                return const0_rtx;
 
@@ -34088,6 +34311,12 @@ ix86_expand_args_builtin (const struct builtin_description *d,
              case CODE_FOR_avx512f_vinserti64x4_mask:
              case CODE_FOR_avx512f_vextractf64x4_mask:
              case CODE_FOR_avx512f_vextracti64x4_mask:
+             case CODE_FOR_avx512dq_vinsertf32x8_mask:
+             case CODE_FOR_avx512dq_vinserti32x8_mask:
+             case CODE_FOR_avx512vl_vinsertv4df:
+             case CODE_FOR_avx512vl_vinsertv4di:
+             case CODE_FOR_avx512vl_vinsertv8sf:
+             case CODE_FOR_avx512vl_vinsertv8si:
                error ("the last argument must be a 1-bit immediate");
                return const0_rtx;
 
@@ -34467,8 +34696,8 @@ ix86_expand_round_builtin (const struct builtin_description *d,
                {
                case CODE_FOR_avx512f_getmantv8df_mask_round:
                case CODE_FOR_avx512f_getmantv16sf_mask_round:
-               case CODE_FOR_avx512f_getmantv2df_round:
-               case CODE_FOR_avx512f_getmantv4sf_round:
+               case CODE_FOR_avx512f_vgetmantv2df_round:
+               case CODE_FOR_avx512f_vgetmantv4sf_round:
                  error ("the immediate argument must be a 4-bit immediate");
                  return const0_rtx;
                case CODE_FOR_avx512f_cmpv8df3_mask_round:
@@ -34589,6 +34818,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
       break;
 
     case INT_FTYPE_VOID:
+    case USHORT_FTYPE_VOID:
     case UINT64_FTYPE_VOID:
     case UNSIGNED_FTYPE_VOID:
       nargs = 0;
@@ -34699,6 +34929,14 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
        case CODE_FOR_avx512f_storev16si_mask:
        case CODE_FOR_avx512f_storev8df_mask:
        case CODE_FOR_avx512f_storev8di_mask:
+       case CODE_FOR_avx512vl_storev8sf_mask:
+       case CODE_FOR_avx512vl_storev8si_mask:
+       case CODE_FOR_avx512vl_storev4df_mask:
+       case CODE_FOR_avx512vl_storev4di_mask:
+       case CODE_FOR_avx512vl_storev4sf_mask:
+       case CODE_FOR_avx512vl_storev4si_mask:
+       case CODE_FOR_avx512vl_storev2df_mask:
+       case CODE_FOR_avx512vl_storev2di_mask:
          aligned_mem = true;
          break;
        default:
@@ -34742,6 +34980,20 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
        case CODE_FOR_avx512f_loadv16si_mask:
        case CODE_FOR_avx512f_loadv8df_mask:
        case CODE_FOR_avx512f_loadv8di_mask:
+       case CODE_FOR_avx512vl_loadv8sf_mask:
+       case CODE_FOR_avx512vl_loadv8si_mask:
+       case CODE_FOR_avx512vl_loadv4df_mask:
+       case CODE_FOR_avx512vl_loadv4di_mask:
+       case CODE_FOR_avx512vl_loadv4sf_mask:
+       case CODE_FOR_avx512vl_loadv4si_mask:
+       case CODE_FOR_avx512vl_loadv2df_mask:
+       case CODE_FOR_avx512vl_loadv2di_mask:
+       case CODE_FOR_avx512bw_loadv64qi_mask:
+       case CODE_FOR_avx512vl_loadv32qi_mask:
+       case CODE_FOR_avx512vl_loadv16qi_mask:
+       case CODE_FOR_avx512bw_loadv32hi_mask:
+       case CODE_FOR_avx512vl_loadv16hi_mask:
+       case CODE_FOR_avx512vl_loadv8hi_mask:
          aligned_mem = true;
          break;
        default:
@@ -35274,7 +35526,6 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
     case IX86_BUILTIN_FXRSTOR64:
     case IX86_BUILTIN_FNSTENV:
     case IX86_BUILTIN_FLDENV:
-    case IX86_BUILTIN_FNSTSW:
       mode0 = BLKmode;
       switch (fcode)
        {
@@ -35296,10 +35547,6 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
        case IX86_BUILTIN_FLDENV:
          icode = CODE_FOR_fldenv;
          break;
-       case IX86_BUILTIN_FNSTSW:
-         icode = CODE_FOR_fnstsw;
-         mode0 = HImode;
-         break;
        default:
          gcc_unreachable ();
        }
@@ -35561,6 +35808,16 @@ rdseed_step:
       emit_insn (gen_zero_extendqisi2 (target, op2));
       return target;
 
+    case IX86_BUILTIN_SBB32:
+      icode = CODE_FOR_subsi3_carry;
+      mode0 = SImode;
+      goto addcarryx;
+
+    case IX86_BUILTIN_SBB64:
+      icode = CODE_FOR_subdi3_carry;
+      mode0 = DImode;
+      goto addcarryx;
+
     case IX86_BUILTIN_ADDCARRYX32:
       icode = TARGET_ADX ? CODE_FOR_adcxsi3 : CODE_FOR_addsi3_carry;
       mode0 = SImode;
@@ -36910,8 +37167,7 @@ ix86_vectorize_builtin_gather (const_tree mem_vectype,
    reciprocal of the function, or NULL_TREE if not available.  */
 
 static tree
-ix86_builtin_reciprocal (unsigned int fn, bool md_fn,
-                        bool sqrt ATTRIBUTE_UNUSED)
+ix86_builtin_reciprocal (unsigned int fn, bool md_fn, bool)
 {
   if (! (TARGET_SSE_MATH && !optimize_insn_for_size_p ()
         && flag_finite_math_only && !flag_trapping_math
@@ -37376,6 +37632,11 @@ inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
   if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
     return true;
 
+  /* Between mask and general, we have moves no larger than word size.  */
+  if ((MAYBE_MASK_CLASS_P (class1) != MAYBE_MASK_CLASS_P (class2))
+      && (GET_MODE_SIZE (mode) > UNITS_PER_WORD))
+  return true;
+
   /* ??? This is a lie.  We do have moves between mmx/general, and for
      mmx/sse2.  But by saying we need secondary memory we discourage the
      register allocator from using the mmx registers unless needed.  */
@@ -37458,13 +37719,6 @@ ix86_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
         the vec_dupv4hi pattern.  */
       if (GET_MODE_SIZE (from) < 4)
        return true;
-
-      /* Vector registers do not support subreg with nonzero offsets, which
-        are otherwise valid for integer registers.  Since we can't see
-        whether we have a nonzero offset from here, prohibit all
-         nonparadoxical subregs changing size.  */
-      if (GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
-       return true;
     }
 
   return false;
@@ -37681,7 +37935,8 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
   if (STACK_REGNO_P (regno))
     return VALID_FP_MODE_P (mode);
   if (MASK_REGNO_P (regno))
-    return VALID_MASK_REG_MODE (mode);
+    return (VALID_MASK_REG_MODE (mode)
+           || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
   if (SSE_REGNO_P (regno))
     {
       /* We implement the move patterns for all vector modes into and
@@ -37698,6 +37953,15 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
              || VALID_AVX512F_SCALAR_MODE (mode)))
        return true;
 
+      /* TODO check for QI/HI scalars.  */
+      /* AVX512VL allows sse regs16+ for 128/256 bit modes.  */
+      if (TARGET_AVX512VL
+         && (mode == OImode
+             || mode == TImode
+             || VALID_AVX256_REG_MODE (mode)
+             || VALID_AVX512VL_128_REG_MODE (mode)))
+       return true;
+
       /* xmm16-xmm31 are only available for AVX-512.  */
       if (EXT_REX_SSE_REGNO_P (regno))
        return false;
@@ -37901,10 +38165,10 @@ ix86_rtx_costs (rtx x, int code_i, int outer_code_i, int opno, int *total,
       else if (TARGET_64BIT && !x86_64_zext_immediate_operand (x, VOIDmode))
        *total = 2;
       else if (flag_pic && SYMBOLIC_CONST (x)
-              && (!TARGET_64BIT
-                  || (!GET_CODE (x) != LABEL_REF
-                      && (GET_CODE (x) != SYMBOL_REF
-                          || !SYMBOL_REF_LOCAL_P (x)))))
+              && !(TARGET_64BIT
+                   && (GET_CODE (x) == LABEL_REF
+                       || (GET_CODE (x) == SYMBOL_REF
+                           && SYMBOL_REF_LOCAL_P (x)))))
        *total = 1;
       else
        *total = 0;
@@ -38523,7 +38787,7 @@ x86_order_regs_for_local_alloc (void)
 static tree
 ix86_handle_callee_pop_aggregate_return (tree *node, tree name,
                                              tree args,
-                                             int flags ATTRIBUTE_UNUSED,
+                                             int,
                                              bool *no_add_attrs)
 {
   if (TREE_CODE (*node) != FUNCTION_TYPE
@@ -38573,9 +38837,8 @@ ix86_handle_callee_pop_aggregate_return (tree *node, tree name,
 /* Handle a "ms_abi" or "sysv" attribute; arguments as in
    struct attribute_spec.handler.  */
 static tree
-ix86_handle_abi_attribute (tree *node, tree name,
-                             tree args ATTRIBUTE_UNUSED,
-                             int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+ix86_handle_abi_attribute (tree *node, tree name, tree, int,
+                          bool *no_add_attrs)
 {
   if (TREE_CODE (*node) != FUNCTION_TYPE
       && TREE_CODE (*node) != METHOD_TYPE
@@ -38614,9 +38877,8 @@ ix86_handle_abi_attribute (tree *node, tree name,
 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
    struct attribute_spec.handler.  */
 static tree
-ix86_handle_struct_attribute (tree *node, tree name,
-                             tree args ATTRIBUTE_UNUSED,
-                             int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+ix86_handle_struct_attribute (tree *node, tree name, tree, int,
+                             bool *no_add_attrs)
 {
   tree *type = NULL;
   if (DECL_P (*node))
@@ -38648,9 +38910,8 @@ ix86_handle_struct_attribute (tree *node, tree name,
 }
 
 static tree
-ix86_handle_fndecl_attribute (tree *node, tree name,
-                              tree args ATTRIBUTE_UNUSED,
-                              int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,
+                             bool *no_add_attrs)
 {
   if (TREE_CODE (*node) != FUNCTION_DECL)
     {
@@ -38728,9 +38989,8 @@ x86_this_parameter (tree function)
 /* Determine whether x86_output_mi_thunk can succeed.  */
 
 static bool
-x86_can_output_mi_thunk (const_tree thunk ATTRIBUTE_UNUSED,
-                        HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
-                        HOST_WIDE_INT vcall_offset, const_tree function)
+x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
+                        const_tree function)
 {
   /* 64-bit can handle anything.  */
   if (TARGET_64BIT)
@@ -38759,13 +39019,13 @@ x86_can_output_mi_thunk (const_tree thunk ATTRIBUTE_UNUSED,
    *(*this + vcall_offset) should be added to THIS.  */
 
 static void
-x86_output_mi_thunk (FILE *file,
-                    tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
+x86_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
                     HOST_WIDE_INT vcall_offset, tree function)
 {
   rtx this_param = x86_this_parameter (function);
   rtx this_reg, tmp, fnaddr;
   unsigned int tmp_regno;
+  rtx_insn *insn;
 
   if (TARGET_64BIT)
     tmp_regno = R10_REG;
@@ -38891,7 +39151,18 @@ x86_output_mi_thunk (FILE *file,
      For our purposes here, we can get away with (ab)using a jump pattern,
      because we're going to do no optimization.  */
   if (MEM_P (fnaddr))
-    emit_jump_insn (gen_indirect_jump (fnaddr));
+    {
+      if (sibcall_insn_operand (fnaddr, word_mode))
+       {
+         fnaddr = XEXP (DECL_RTL (function), 0);
+         tmp = gen_rtx_MEM (QImode, fnaddr);
+         tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
+         tmp = emit_call_insn (tmp);
+         SIBLING_CALL_P (tmp) = 1;
+       }
+      else
+       emit_jump_insn (gen_indirect_jump (fnaddr));
+    }
   else
     {
       if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
@@ -38916,10 +39187,10 @@ x86_output_mi_thunk (FILE *file,
 
   /* Emit just enough of rest_of_compilation to get the insns emitted.
      Note that use_thunk calls assemble_start_function et al.  */
-  tmp = get_insns ();
-  shorten_branches (tmp);
-  final_start_function (tmp, file, 1);
-  final (tmp, file, 1);
+  insn = get_insns ();
+  shorten_branches (insn);
+  final_start_function (insn, file, 1);
+  final (insn, file, 1);
   final_end_function ();
 }
 
@@ -38956,6 +39227,17 @@ x86_field_alignment (tree field, int computed)
   return computed;
 }
 
+/* Print call to TARGET to FILE.  */
+
+static void
+x86_print_call_or_nop (FILE *file, const char *target)
+{
+  if (flag_nop_mcount)
+    fprintf (file, "1:\tnopl 0x00(%%eax,%%eax,1)\n"); /* 5 byte nop.  */
+  else
+    fprintf (file, "1:\tcall\t%s\n", target);
+}
+
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 void
@@ -38963,7 +39245,6 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
 {
   const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE
                                         : MCOUNT_NAME);
-
   if (TARGET_64BIT)
     {
 #ifndef NO_PROFILE_COUNTERS
@@ -38971,9 +39252,9 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
 #endif
 
       if (!TARGET_PECOFF && flag_pic)
-       fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", mcount_name);
+       fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n", mcount_name);
       else
-       fprintf (file, "\tcall\t%s\n", mcount_name);
+       x86_print_call_or_nop (file, mcount_name);
     }
   else if (flag_pic)
     {
@@ -38981,7 +39262,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
       fprintf (file, "\tleal\t%sP%d@GOTOFF(%%ebx),%%" PROFILE_COUNT_REGISTER "\n",
               LPREFIX, labelno);
 #endif
-      fprintf (file, "\tcall\t*%s@GOT(%%ebx)\n", mcount_name);
+      fprintf (file, "1:\tcall\t*%s@GOT(%%ebx)\n", mcount_name);
     }
   else
     {
@@ -38989,7 +39270,14 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
       fprintf (file, "\tmovl\t$%sP%d,%%" PROFILE_COUNT_REGISTER "\n",
               LPREFIX, labelno);
 #endif
-      fprintf (file, "\tcall\t%s\n", mcount_name);
+      x86_print_call_or_nop (file, mcount_name);
+    }
+
+  if (flag_record_mcount)
+    {
+      fprintf (file, "\t.section __mcount_loc, \"a\",@progbits\n");
+      fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
+      fprintf (file, "\t.previous\n");
     }
 }
 
@@ -38999,7 +39287,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
    99% of cases.  */
 
 static int
-min_insn_size (rtx insn)
+min_insn_size (rtx_insn *insn)
 {
   int l = 0, len;
 
@@ -39060,7 +39348,7 @@ min_insn_size (rtx insn)
 static void
 ix86_avoid_jump_mispredicts (void)
 {
-  rtx insn, start = get_insns ();
+  rtx_insn *insn, *start = get_insns ();
   int nbytes = 0, njumps = 0;
   int isjump = 0;
 
@@ -39166,8 +39454,8 @@ ix86_pad_returns (void)
   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
     {
       basic_block bb = e->src;
-      rtx ret = BB_END (bb);
-      rtx prev;
+      rtx_insn *ret = BB_END (bb);
+      rtx_insn *prev;
       bool replace = false;
 
       if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
@@ -39215,7 +39503,7 @@ ix86_pad_returns (void)
 static int
 ix86_count_insn_bb (basic_block bb)
 {
-  rtx insn;
+  rtx_insn *insn;
   int insn_count = 0;
 
   /* Count number of instructions in this block.  Return 4 if the number
@@ -39296,7 +39584,7 @@ ix86_pad_short_function (void)
 
   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
     {
-      rtx ret = BB_END (e->src);
+      rtx_insn *ret = BB_END (e->src);
       if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
        {
          int insn_count = ix86_count_insn (e->src);
@@ -39304,7 +39592,7 @@ ix86_pad_short_function (void)
          /* Pad short function.  */
          if (insn_count < 4)
            {
-             rtx insn = ret;
+             rtx_insn *insn = ret;
 
              /* Find epilogue.  */
              while (insn
@@ -39336,7 +39624,7 @@ ix86_seh_fixup_eh_fallthru (void)
 
   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
     {
-      rtx insn, next;
+      rtx_insn *insn, *next;
 
       /* Find the beginning of the epilogue.  */
       for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
@@ -39391,7 +39679,7 @@ ix86_reorg (void)
 /* Return nonzero when QImode register that must be represented via REX prefix
    is used.  */
 bool
-x86_extended_QIreg_mentioned_p (rtx insn)
+x86_extended_QIreg_mentioned_p (rtx_insn *insn)
 {
   int i;
   extract_insn_cached (insn);
@@ -39405,7 +39693,7 @@ x86_extended_QIreg_mentioned_p (rtx insn)
 /* Return nonzero when P points to register encoded via REX prefix.
    Called via for_each_rtx.  */
 static int
-extended_reg_mentioned_1 (rtx *p, void *data ATTRIBUTE_UNUSED)
+extended_reg_mentioned_1 (rtx *p, void *)
 {
    unsigned int regno;
    if (!REG_P (*p))
@@ -39475,7 +39763,8 @@ x86_maybe_negate_const_int (rtx *loc, enum machine_mode mode)
 void
 x86_emit_floatuns (rtx operands[2])
 {
-  rtx neglab, donelab, i0, i1, f0, in, out;
+  rtx_code_label *neglab, *donelab;
+  rtx i0, i1, f0, in, out;
   enum machine_mode mode, inmode;
 
   inmode = GET_MODE (operands[1]);
@@ -39510,23 +39799,10 @@ x86_emit_floatuns (rtx operands[2])
   emit_label (donelab);
 }
 \f
-/* AVX512F does support 64-byte integer vector operations,
-   thus the longest vector we are faced with is V64QImode.  */
-#define MAX_VECT_LEN   64
-
-struct expand_vec_perm_d
-{
-  rtx target, op0, op1;
-  unsigned char perm[MAX_VECT_LEN];
-  enum machine_mode vmode;
-  unsigned char nelt;
-  bool one_operand_p;
-  bool testing_p;
-};
-
 static bool canonicalize_perm (struct expand_vec_perm_d *d);
 static bool expand_vec_perm_1 (struct expand_vec_perm_d *d);
 static bool expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d);
+static bool expand_vec_perm_palignr (struct expand_vec_perm_d *d, bool);
 
 /* Get a vector mode of the same size as the original but with elements
    twice as wide.  This is only guaranteed to apply to integral vectors.  */
@@ -39548,14 +39824,15 @@ static bool
 ix86_vector_duplicate_value (enum machine_mode mode, rtx target, rtx val)
 {
   bool ok;
-  rtx insn, dup;
+  rtx_insn *insn;
+  rtx dup;
 
   /* First attempt to recognize VAL as-is.  */
   dup = gen_rtx_VEC_DUPLICATE (mode, val);
   insn = emit_insn (gen_rtx_SET (VOIDmode, target, dup));
   if (recog_memoized (insn) < 0)
     {
-      rtx seq;
+      rtx_insn *seq;
       /* If that fails, force VAL into a register.  */
 
       start_sequence ();
@@ -39623,6 +39900,9 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
       goto widen;
 
     case V8HImode:
+      if (TARGET_AVX2)
+       return ix86_vector_duplicate_value (mode, target, val);
+
       if (TARGET_SSE2)
        {
          struct expand_vec_perm_d dperm;
@@ -39653,6 +39933,9 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
       goto widen;
 
     case V16QImode:
+      if (TARGET_AVX2)
+       return ix86_vector_duplicate_value (mode, target, val);
+
       if (TARGET_SSE2)
        goto permute;
       goto widen;
@@ -39682,16 +39965,36 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
 
     case V16HImode:
     case V32QImode:
-      {
-       enum machine_mode hvmode = (mode == V16HImode ? V8HImode : V16QImode);
-       rtx x = gen_reg_rtx (hvmode);
+      if (TARGET_AVX2)
+       return ix86_vector_duplicate_value (mode, target, val);
+      else
+       {
+         enum machine_mode hvmode = (mode == V16HImode ? V8HImode : V16QImode);
+         rtx x = gen_reg_rtx (hvmode);
 
-       ok = ix86_expand_vector_init_duplicate (false, hvmode, x, val);
-       gcc_assert (ok);
+         ok = ix86_expand_vector_init_duplicate (false, hvmode, x, val);
+         gcc_assert (ok);
 
-       x = gen_rtx_VEC_CONCAT (mode, x, x);
-       emit_insn (gen_rtx_SET (VOIDmode, target, x));
-      }
+         x = gen_rtx_VEC_CONCAT (mode, x, x);
+         emit_insn (gen_rtx_SET (VOIDmode, target, x));
+       }
+      return true;
+
+    case V64QImode:
+    case V32HImode:
+      if (TARGET_AVX512BW)
+       return ix86_vector_duplicate_value (mode, target, val);
+      else
+       {
+         enum machine_mode hvmode = (mode == V32HImode ? V16HImode : V32QImode);
+         rtx x = gen_reg_rtx (hvmode);
+
+         ok = ix86_expand_vector_init_duplicate (false, hvmode, x, val);
+         gcc_assert (ok);
+
+         x = gen_rtx_VEC_CONCAT (mode, x, x);
+         emit_insn (gen_rtx_SET (VOIDmode, target, x));
+       }
       return true;
 
     default:
@@ -40253,8 +40556,9 @@ static void
 ix86_expand_vector_init_general (bool mmx_ok, enum machine_mode mode,
                                 rtx target, rtx vals)
 {
-  rtx ops[64], op0, op1;
+  rtx ops[64], op0, op1, op2, op3, op4, op5;
   enum machine_mode half_mode = VOIDmode;
+  enum machine_mode quarter_mode = VOIDmode;
   int n, i;
 
   switch (mode)
@@ -40305,6 +40609,42 @@ half:
                              gen_rtx_VEC_CONCAT (mode, op0, op1)));
       return;
 
+    case V64QImode:
+      quarter_mode = V16QImode;
+      half_mode = V32QImode;
+      goto quarter;
+
+    case V32HImode:
+      quarter_mode = V8HImode;
+      half_mode = V16HImode;
+      goto quarter;
+
+quarter:
+      n = GET_MODE_NUNITS (mode);
+      for (i = 0; i < n; i++)
+       ops[i] = XVECEXP (vals, 0, i);
+      op0 = gen_reg_rtx (quarter_mode);
+      op1 = gen_reg_rtx (quarter_mode);
+      op2 = gen_reg_rtx (quarter_mode);
+      op3 = gen_reg_rtx (quarter_mode);
+      op4 = gen_reg_rtx (half_mode);
+      op5 = gen_reg_rtx (half_mode);
+      ix86_expand_vector_init_interleave (quarter_mode, op0, ops,
+                                         n >> 3);
+      ix86_expand_vector_init_interleave (quarter_mode, op1,
+                                         &ops [n >> 2], n >> 3);
+      ix86_expand_vector_init_interleave (quarter_mode, op2,
+                                         &ops [n >> 1], n >> 3);
+      ix86_expand_vector_init_interleave (quarter_mode, op3,
+                                         &ops [(n >> 1) | (n >> 2)], n >> 3);
+      emit_insn (gen_rtx_SET (VOIDmode, op4,
+                             gen_rtx_VEC_CONCAT (half_mode, op0, op1)));
+      emit_insn (gen_rtx_SET (VOIDmode, op5,
+                             gen_rtx_VEC_CONCAT (half_mode, op2, op3)));
+      emit_insn (gen_rtx_SET (VOIDmode, target,
+                             gen_rtx_VEC_CONCAT (mode, op4, op5)));
+      return;
+
     case V16QImode:
       if (!TARGET_SSE4_1)
        break;
@@ -40687,6 +41027,79 @@ half:
       emit_insn (gen_insert[j][i] (target, target, tmp));
       return;
 
+    case V8DFmode:
+      if (TARGET_AVX512F)
+       {
+         tmp = gen_reg_rtx (mode);
+         emit_insn (gen_rtx_SET (VOIDmode, tmp,
+                                 gen_rtx_VEC_DUPLICATE (mode, val)));
+         emit_insn (gen_avx512f_blendmv8df (target, tmp, target,
+                                            force_reg (QImode, GEN_INT (1 << elt))));
+         return;
+       }
+      else
+       break;
+    case V8DImode:
+      if (TARGET_AVX512F)
+       {
+         tmp = gen_reg_rtx (mode);
+         emit_insn (gen_rtx_SET (VOIDmode, tmp,
+                                 gen_rtx_VEC_DUPLICATE (mode, val)));
+         emit_insn (gen_avx512f_blendmv8di (target, tmp, target,
+                                            force_reg (QImode, GEN_INT (1 << elt))));
+         return;
+       }
+      else
+       break;
+    case V16SFmode:
+      if (TARGET_AVX512F)
+       {
+         tmp = gen_reg_rtx (mode);
+         emit_insn (gen_rtx_SET (VOIDmode, tmp,
+                                 gen_rtx_VEC_DUPLICATE (mode, val)));
+         emit_insn (gen_avx512f_blendmv16sf (target, tmp, target,
+                                             force_reg (HImode, GEN_INT (1 << elt))));
+         return;
+       }
+      else
+       break;
+    case V16SImode:
+      if (TARGET_AVX512F)
+       {
+         tmp = gen_reg_rtx (mode);
+         emit_insn (gen_rtx_SET (VOIDmode, tmp,
+                                 gen_rtx_VEC_DUPLICATE (mode, val)));
+         emit_insn (gen_avx512f_blendmv16si (target, tmp, target,
+                                             force_reg (HImode, GEN_INT (1 << elt))));
+         return;
+       }
+      else
+       break;
+    case V32HImode:
+      if (TARGET_AVX512F && TARGET_AVX512BW)
+       {
+         tmp = gen_reg_rtx (mode);
+         emit_insn (gen_rtx_SET (VOIDmode, tmp,
+                                 gen_rtx_VEC_DUPLICATE (mode, val)));
+         emit_insn (gen_avx512bw_blendmv32hi (target, tmp, target,
+                                              force_reg (SImode, GEN_INT (1 << elt))));
+         return;
+       }
+      else
+       break;
+    case V64QImode:
+      if (TARGET_AVX512F && TARGET_AVX512BW)
+       {
+         tmp = gen_reg_rtx (mode);
+         emit_insn (gen_rtx_SET (VOIDmode, tmp,
+                                 gen_rtx_VEC_DUPLICATE (mode, val)));
+         emit_insn (gen_avx512bw_blendmv64qi (target, tmp, target,
+                                              force_reg (DImode, GEN_INT (1 << elt))));
+         return;
+       }
+      else
+       break;
+
     default:
       break;
     }
@@ -40894,6 +41307,32 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt)
        }
       break;
 
+    case V32HImode:
+      if (TARGET_AVX512BW)
+       {
+         tmp = gen_reg_rtx (V16HImode);
+         if (elt < 16)
+           emit_insn (gen_vec_extract_lo_v32hi (tmp, vec));
+         else
+           emit_insn (gen_vec_extract_hi_v32hi (tmp, vec));
+         ix86_expand_vector_extract (false, target, tmp, elt & 15);
+         return;
+       }
+      break;
+
+    case V64QImode:
+      if (TARGET_AVX512BW)
+       {
+         tmp = gen_reg_rtx (V32QImode);
+         if (elt < 32)
+           emit_insn (gen_vec_extract_lo_v64qi (tmp, vec));
+         else
+           emit_insn (gen_vec_extract_hi_v64qi (tmp, vec));
+         ix86_expand_vector_extract (false, target, tmp, elt & 31);
+         return;
+       }
+      break;
+
     case V16SFmode:
       tmp = gen_reg_rtx (V8SFmode);
       if (elt < 8)
@@ -41022,6 +41461,8 @@ emit_reduc_half (rtx dest, rtx src, int i)
                                    GEN_INT (i / 2));
        }
       break;
+    case V64QImode:
+    case V32HImode:
     case V16SImode:
     case V16SFmode:
     case V8DImode:
@@ -41133,6 +41574,31 @@ ix86_vector_mode_supported_p (enum machine_mode mode)
   return false;
 }
 
+/* Implement target hook libgcc_floating_mode_supported_p.  */
+static bool
+ix86_libgcc_floating_mode_supported_p (enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case SFmode:
+    case DFmode:
+    case XFmode:
+      return true;
+
+    case TFmode:
+#ifdef IX86_NO_LIBGCC_TFMODE
+      return false;
+#elif defined IX86_MAYBE_NO_LIBGCC_TFMODE
+      return TARGET_LONG_DOUBLE_128;
+#else
+      return true;
+#endif
+
+    default:
+      return false;
+    }
+}
+
 /* Target hook for c_mode_for_suffix.  */
 static enum machine_mode
 ix86_c_mode_for_suffix (char suffix)
@@ -41151,9 +41617,7 @@ ix86_c_mode_for_suffix (char suffix)
    with the old cc0-based compiler.  */
 
 static tree
-ix86_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED,
-                     tree inputs ATTRIBUTE_UNUSED,
-                     tree clobbers)
+ix86_md_asm_clobbers (tree, tree, tree clobbers)
 {
   clobbers = tree_cons (NULL_TREE, build_string (5, "flags"),
                        clobbers);
@@ -41262,8 +41726,8 @@ ix86_emit_fp_unordered_jump (rtx label)
 
 void ix86_emit_i387_log1p (rtx op0, rtx op1)
 {
-  rtx label1 = gen_label_rtx ();
-  rtx label2 = gen_label_rtx ();
+  rtx_code_label *label1 = gen_label_rtx ();
+  rtx_code_label *label2 = gen_label_rtx ();
 
   rtx tmp = gen_reg_rtx (XFmode);
   rtx tmp2 = gen_reg_rtx (XFmode);
@@ -41297,7 +41761,7 @@ void ix86_emit_i387_round (rtx op0, rtx op1)
   rtx e1, e2, res, tmp, tmp1, half;
   rtx scratch = gen_reg_rtx (HImode);
   rtx flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
-  rtx jump_label = gen_label_rtx ();
+  rtx_code_label *jump_label = gen_label_rtx ();
   rtx insn;
   rtx (*gen_abs) (rtx, rtx);
   rtx (*gen_neg) (rtx, rtx);
@@ -41733,12 +42197,13 @@ ix86_expand_sse_fabs (rtx op0, rtx *smask)
    swapping the operands if SWAP_OPERANDS is true.  The expanded
    code is a forward jump to a newly created label in case the
    comparison is true.  The generated label rtx is returned.  */
-static rtx
+static rtx_code_label *
 ix86_expand_sse_compare_and_jump (enum rtx_code code, rtx op0, rtx op1,
                                   bool swap_operands)
 {
   enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
-  rtx label, tmp;
+  rtx_code_label *label;
+  rtx tmp;
 
   if (swap_operands)
     {
@@ -41842,7 +42307,8 @@ ix86_expand_lfloorceil (rtx op0, rtx op1, bool do_floor)
    */
   enum machine_mode fmode = GET_MODE (op1);
   enum machine_mode imode = GET_MODE (op0);
-  rtx ireg, freg, label, tmp;
+  rtx ireg, freg, tmp;
+  rtx_code_label *label;
 
   /* reg = (long)op1 */
   ireg = gen_reg_rtx (imode);
@@ -41878,7 +42344,8 @@ ix86_expand_rint (rtx operand0, rtx operand1)
         return copysign (xa, operand1);
    */
   enum machine_mode mode = GET_MODE (operand0);
-  rtx res, xa, label, TWO52, mask;
+  rtx res, xa, TWO52, mask;
+  rtx_code_label *label;
 
   res = gen_reg_rtx (mode);
   emit_move_insn (res, operand1);
@@ -41921,7 +42388,8 @@ ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
         return x2;
    */
   enum machine_mode mode = GET_MODE (operand0);
-  rtx xa, TWO52, tmp, label, one, res, mask;
+  rtx xa, TWO52, tmp, one, res, mask;
+  rtx_code_label *label;
 
   TWO52 = ix86_gen_TWO52 (mode);
 
@@ -41984,7 +42452,8 @@ ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
        return x2;
    */
   enum machine_mode mode = GET_MODE (operand0);
-  rtx xa, xi, TWO52, tmp, label, one, res, mask;
+  rtx xa, xi, TWO52, tmp, one, res, mask;
+  rtx_code_label *label;
 
   TWO52 = ix86_gen_TWO52 (mode);
 
@@ -42047,7 +42516,8 @@ ix86_expand_rounddf_32 (rtx operand0, rtx operand1)
         return x2;
    */
   enum machine_mode mode = GET_MODE (operand0);
-  rtx xa, xa2, dxa, TWO52, tmp, label, half, mhalf, one, res, mask;
+  rtx xa, xa2, dxa, TWO52, tmp, half, mhalf, one, res, mask;
+  rtx_code_label *label;
 
   TWO52 = ix86_gen_TWO52 (mode);
 
@@ -42112,7 +42582,8 @@ ix86_expand_trunc (rtx operand0, rtx operand1)
        return x2;
    */
   enum machine_mode mode = GET_MODE (operand0);
-  rtx xa, xi, TWO52, label, res, mask;
+  rtx xa, xi, TWO52, res, mask;
+  rtx_code_label *label;
 
   TWO52 = ix86_gen_TWO52 (mode);
 
@@ -42147,7 +42618,8 @@ void
 ix86_expand_truncdf_32 (rtx operand0, rtx operand1)
 {
   enum machine_mode mode = GET_MODE (operand0);
-  rtx xa, mask, TWO52, label, one, res, smask, tmp;
+  rtx xa, mask, TWO52, one, res, smask, tmp;
+  rtx_code_label *label;
 
   /* C code for SSE variant we expand below.
         double xa = fabs (x), x2;
@@ -42212,7 +42684,8 @@ ix86_expand_round (rtx operand0, rtx operand1)
         return copysign (xa, x);
    */
   enum machine_mode mode = GET_MODE (operand0);
-  rtx res, TWO52, xa, label, xi, half, mask;
+  rtx res, TWO52, xa, xi, half, mask;
+  rtx_code_label *label;
   const struct real_format *fmt;
   REAL_VALUE_TYPE pred_half, half_minus_pred_half;
 
@@ -42360,8 +42833,7 @@ static const struct attribute_spec ix86_attribute_table[] =
 /* Implement targetm.vectorize.builtin_vectorization_cost.  */
 static int
 ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
-                                 tree vectype,
-                                 int misalign ATTRIBUTE_UNUSED)
+                                 tree vectype, int)
 {
   unsigned elements;
 
@@ -42418,7 +42890,7 @@ ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
    insn, so that expand_vselect{,_vconcat} doesn't have to create a fresh
    insn every time.  */
 
-static GTY(()) rtx vselect_insn;
+static GTY(()) rtx_insn *vselect_insn;
 
 /* Initialize vselect_insn.  */
 
@@ -42511,7 +42983,10 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
 
   if (d->one_operand_p)
     return false;
-  if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32)
+  if (TARGET_AVX512F && GET_MODE_SIZE (vmode) == 64
+      && GET_MODE_SIZE (GET_MODE_INNER (vmode)) >= 4)
+    ;
+  else if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32)
     ;
   else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
     ;
@@ -42542,12 +43017,18 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
 
   switch (vmode)
     {
+    case V8DFmode:
+    case V16SFmode:
     case V4DFmode:
     case V8SFmode:
     case V2DFmode:
     case V4SFmode:
     case V8HImode:
     case V8SImode:
+    case V32HImode:
+    case V64QImode:
+    case V16SImode:
+    case V8DImode:
       for (i = 0; i < nelt; ++i)
        mask |= (d->perm[i] >= nelt) << i;
       break;
@@ -42770,9 +43251,9 @@ static bool
 expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
 {
   unsigned i, nelt, eltsz, mask;
-  unsigned char perm[32];
+  unsigned char perm[64];
   enum machine_mode vmode = V16QImode;
-  rtx rperm[32], vperm, target, op0, op1;
+  rtx rperm[64], vperm, target, op0, op1;
 
   nelt = d->nelt;
 
@@ -42794,8 +43275,8 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
              op0 = gen_lowpart (V4DImode, d->op0);
              op1 = gen_lowpart (V4DImode, d->op1);
              rperm[0]
-               = GEN_INT (((d->perm[0] & (nelt / 2)) ? 1 : 0)
-                          || ((d->perm[nelt / 2] & (nelt / 2)) ? 2 : 0));
+               = GEN_INT ((d->perm[0] / (nelt / 2))
+                          | ((d->perm[nelt / 2] / (nelt / 2)) * 16));
              emit_insn (gen_avx2_permv2ti (target, op0, op1, rperm[0]));
              if (target != d->target)
                emit_move_insn (d->target, gen_lowpart (d->vmode, target));
@@ -42861,6 +43342,19 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
                  return false;
            }
        }
+      else if (GET_MODE_SIZE (d->vmode) == 64)
+       {
+         if (!TARGET_AVX512BW)
+           return false;
+         if (vmode == V64QImode)
+           {
+             /* vpshufb only works intra lanes, it is not
+                possible to shuffle bytes in between the lanes.  */
+             for (i = 0; i < nelt; ++i)
+               if ((d->perm[i] ^ i) & (nelt / 4))
+                 return false;
+           }
+       }
       else
        return false;
     }
@@ -42878,6 +43372,8 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
        mask = 2 * nelt - 1;
       else if (vmode == V16QImode)
        mask = nelt - 1;
+      else if (vmode == V64QImode)
+       mask = nelt / 4 - 1;
       else
        mask = nelt / 2 - 1;
 
@@ -42903,6 +43399,8 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
        emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, vperm));
       else if (vmode == V32QImode)
        emit_insn (gen_avx2_pshufbv32qi3 (target, op0, vperm));
+      else if (vmode == V64QImode)
+       emit_insn (gen_avx512bw_pshufbv64qi3 (target, op0, vperm));
       else if (vmode == V8SFmode)
        emit_insn (gen_avx2_permvarv8sf (target, op0, vperm));
       else
@@ -42958,12 +43456,24 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
          rtx (*gen) (rtx, rtx) = NULL;
          switch (d->vmode)
            {
+           case V64QImode:
+             if (TARGET_AVX512BW)
+               gen = gen_avx512bw_vec_dupv64qi;
+             break;
            case V32QImode:
              gen = gen_avx2_pbroadcastv32qi_1;
              break;
+           case V32HImode:
+             if (TARGET_AVX512BW)
+               gen = gen_avx512bw_vec_dupv32hi;
+             break;
            case V16HImode:
              gen = gen_avx2_pbroadcastv16hi_1;
              break;
+           case V16SImode:
+             if (TARGET_AVX512F)
+               gen = gen_avx512f_vec_dupv16si;
+             break;
            case V8SImode:
              gen = gen_avx2_pbroadcastv8si_1;
              break;
@@ -42973,9 +43483,21 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
            case V8HImode:
              gen = gen_avx2_pbroadcastv8hi;
              break;
+           case V16SFmode:
+             if (TARGET_AVX512F)
+               gen = gen_avx512f_vec_dupv16sf;
+             break;
            case V8SFmode:
              gen = gen_avx2_vec_dupv8sf_1;
              break;
+           case V8DFmode:
+             if (TARGET_AVX512F)
+               gen = gen_avx512f_vec_dupv8df;
+             break;
+           case V8DImode:
+             if (TARGET_AVX512F)
+               gen = gen_avx512f_vec_dupv8di;
+             break;
            /* For other modes prefer other shuffles this function creates.  */
            default: break;
            }
@@ -43058,17 +43580,12 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
   if (expand_vec_perm_pshufb (d))
     return true;
 
+  /* Try the AVX2 vpalignr instruction.  */
+  if (expand_vec_perm_palignr (d, true))
+    return true;
+
   /* Try the AVX512F vpermi2 instructions.  */
-  rtx vec[64];
-  enum machine_mode mode = d->vmode;
-  if (mode == V8DFmode)
-    mode = V8DImode;
-  else if (mode == V16SFmode)
-    mode = V16SImode;
-  for (i = 0; i < nelt; ++i)
-    vec[i] = GEN_INT (d->perm[i]);
-  rtx mask = gen_rtx_CONST_VECTOR (mode, gen_rtvec_v (nelt, vec));
-  if (ix86_expand_vec_perm_vpermi2 (d->target, d->op0, mask, d->op1))
+  if (ix86_expand_vec_perm_vpermi2 (NULL_RTX, NULL_RTX, NULL_RTX, NULL_RTX, d))
     return true;
 
   return false;
@@ -43119,55 +43636,120 @@ expand_vec_perm_pshuflw_pshufhw (struct expand_vec_perm_d *d)
    the permutation using the SSSE3 palignr instruction.  This succeeds
    when all of the elements in PERM fit within one vector and we merely
    need to shift them down so that a single vector permutation has a
-   chance to succeed.  */
+   chance to succeed.  If SINGLE_INSN_ONLY_P, succeed if only
+   the vpalignr instruction itself can perform the requested permutation.  */
 
 static bool
-expand_vec_perm_palignr (struct expand_vec_perm_d *d)
+expand_vec_perm_palignr (struct expand_vec_perm_d *d, bool single_insn_only_p)
 {
   unsigned i, nelt = d->nelt;
-  unsigned min, max;
-  bool in_order, ok;
+  unsigned min, max, minswap, maxswap;
+  bool in_order, ok, swap = false;
   rtx shift, target;
   struct expand_vec_perm_d dcopy;
 
-  /* Even with AVX, palignr only operates on 128-bit vectors.  */
-  if (!TARGET_SSSE3 || GET_MODE_SIZE (d->vmode) != 16)
+  /* Even with AVX, palignr only operates on 128-bit vectors,
+     in AVX2 palignr operates on both 128-bit lanes.  */
+  if ((!TARGET_SSSE3 || GET_MODE_SIZE (d->vmode) != 16)
+      && (!TARGET_AVX2 || GET_MODE_SIZE (d->vmode) != 32))
     return false;
 
-  min = nelt, max = 0;
+  min = 2 * nelt;
+  max = 0;
+  minswap = 2 * nelt;
+  maxswap = 0;
   for (i = 0; i < nelt; ++i)
     {
       unsigned e = d->perm[i];
+      unsigned eswap = d->perm[i] ^ nelt;
+      if (GET_MODE_SIZE (d->vmode) == 32)
+       {
+         e = (e & ((nelt / 2) - 1)) | ((e & nelt) >> 1);
+         eswap = e ^ (nelt / 2);
+       }
       if (e < min)
        min = e;
       if (e > max)
        max = e;
+      if (eswap < minswap)
+       minswap = eswap;
+      if (eswap > maxswap)
+       maxswap = eswap;
+    }
+  if (min == 0
+      || max - min >= (GET_MODE_SIZE (d->vmode) == 32 ? nelt / 2 : nelt))
+    {
+      if (d->one_operand_p
+         || minswap == 0
+         || maxswap - minswap >= (GET_MODE_SIZE (d->vmode) == 32
+                                  ? nelt / 2 : nelt))
+       return false;
+      swap = true;
+      min = minswap;
+      max = maxswap;
     }
-  if (min == 0 || max - min >= nelt)
-    return false;
 
   /* Given that we have SSSE3, we know we'll be able to implement the
-     single operand permutation after the palignr with pshufb.  */
-  if (d->testing_p)
+     single operand permutation after the palignr with pshufb for
+     128-bit vectors.  If SINGLE_INSN_ONLY_P, in_order has to be computed
+     first.  */
+  if (d->testing_p && GET_MODE_SIZE (d->vmode) == 16 && !single_insn_only_p)
     return true;
 
   dcopy = *d;
-  shift = GEN_INT (min * GET_MODE_BITSIZE (GET_MODE_INNER (d->vmode)));
-  target = gen_reg_rtx (TImode);
-  emit_insn (gen_ssse3_palignrti (target, gen_lowpart (TImode, d->op1),
-                                 gen_lowpart (TImode, d->op0), shift));
-
-  dcopy.op0 = dcopy.op1 = gen_lowpart (d->vmode, target);
-  dcopy.one_operand_p = true;
+  if (swap)
+    {
+      dcopy.op0 = d->op1;
+      dcopy.op1 = d->op0;
+      for (i = 0; i < nelt; ++i)
+       dcopy.perm[i] ^= nelt;
+    }
 
   in_order = true;
   for (i = 0; i < nelt; ++i)
     {
-      unsigned e = dcopy.perm[i] - min;
+      unsigned e = dcopy.perm[i];
+      if (GET_MODE_SIZE (d->vmode) == 32
+         && e >= nelt
+         && (e & (nelt / 2 - 1)) < min)
+       e = e - min - (nelt / 2);
+      else
+       e = e - min;
       if (e != i)
        in_order = false;
       dcopy.perm[i] = e;
     }
+  dcopy.one_operand_p = true;
+
+  if (single_insn_only_p && !in_order)
+    return false;
+
+  /* For AVX2, test whether we can permute the result in one instruction.  */
+  if (d->testing_p)
+    {
+      if (in_order)
+       return true;
+      dcopy.op1 = dcopy.op0;
+      return expand_vec_perm_1 (&dcopy);
+    }
+
+  shift = GEN_INT (min * GET_MODE_BITSIZE (GET_MODE_INNER (d->vmode)));
+  if (GET_MODE_SIZE (d->vmode) == 16)
+    {
+      target = gen_reg_rtx (TImode);
+      emit_insn (gen_ssse3_palignrti (target, gen_lowpart (TImode, dcopy.op1),
+                                     gen_lowpart (TImode, dcopy.op0), shift));
+    }
+  else
+    {
+      target = gen_reg_rtx (V2TImode);
+      emit_insn (gen_avx2_palignrv2ti (target,
+                                      gen_lowpart (V2TImode, dcopy.op1),
+                                      gen_lowpart (V2TImode, dcopy.op0),
+                                      shift));
+    }
+
+  dcopy.op0 = dcopy.op1 = gen_lowpart (d->vmode, target);
 
   /* Test for the degenerate case where the alignment by itself
      produces the desired permutation.  */
@@ -43178,11 +43760,91 @@ expand_vec_perm_palignr (struct expand_vec_perm_d *d)
     }
 
   ok = expand_vec_perm_1 (&dcopy);
-  gcc_assert (ok);
+  gcc_assert (ok || GET_MODE_SIZE (d->vmode) == 32);
 
   return ok;
 }
 
+/* A subroutine of ix86_expand_vec_perm_const_1.  Try to simplify
+   the permutation using the SSE4_1 pblendv instruction.  Potentially
+   reduces permutation from 2 pshufb and or to 1 pshufb and pblendv.  */
+
+static bool
+expand_vec_perm_pblendv (struct expand_vec_perm_d *d)
+{
+  unsigned i, which, nelt = d->nelt;
+  struct expand_vec_perm_d dcopy, dcopy1;
+  enum machine_mode vmode = d->vmode;
+  bool ok;
+
+  /* Use the same checks as in expand_vec_perm_blend.  */
+  if (d->one_operand_p)
+    return false;
+  if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32)
+    ;
+  else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
+    ;
+  else if (TARGET_SSE4_1 && GET_MODE_SIZE (vmode) == 16)
+    ;
+  else
+    return false;
+
+  /* Figure out where permutation elements stay not in their
+     respective lanes.  */
+  for (i = 0, which = 0; i < nelt; ++i)
+    {
+      unsigned e = d->perm[i];
+      if (e != i)
+       which |= (e < nelt ? 1 : 2);
+    }
+  /* We can pblend the part where elements stay not in their
+     respective lanes only when these elements are all in one
+     half of a permutation.
+     {0 1 8 3 4 5 9 7} is ok as 8, 9 are at not at their respective
+     lanes, but both 8 and 9 >= 8
+     {0 1 8 3 4 5 2 7} is not ok as 2 and 8 are not at their
+     respective lanes and 8 >= 8, but 2 not.  */
+  if (which != 1 && which != 2)
+    return false;
+  if (d->testing_p && GET_MODE_SIZE (vmode) == 16)
+    return true;
+
+  /* First we apply one operand permutation to the part where
+     elements stay not in their respective lanes.  */
+  dcopy = *d;
+  if (which == 2)
+    dcopy.op0 = dcopy.op1 = d->op1;
+  else
+    dcopy.op0 = dcopy.op1 = d->op0;
+  dcopy.one_operand_p = true;
+
+  for (i = 0; i < nelt; ++i)
+    dcopy.perm[i] = d->perm[i] & (nelt - 1);
+
+  ok = expand_vec_perm_1 (&dcopy);
+  if (GET_MODE_SIZE (vmode) != 16 && !ok)
+    return false;
+  else
+    gcc_assert (ok);
+  if (d->testing_p)
+    return true;
+
+  /* Next we put permuted elements into their positions.  */
+  dcopy1 = *d;
+  if (which == 2)
+    dcopy1.op1 = dcopy.target;
+  else
+    dcopy1.op0 = dcopy.target;
+
+  for (i = 0; i < nelt; ++i)
+    dcopy1.perm[i] = ((d->perm[i] >= nelt) ? (nelt + i) : i);
+
+  ok = expand_vec_perm_blend (&dcopy1);
+  gcc_assert (ok);
+
+  return true;
+}
+
 static bool expand_vec_perm_interleave3 (struct expand_vec_perm_d *d);
 
 /* A subroutine of ix86_expand_vec_perm_builtin_1.  Try to simplify
@@ -43196,7 +43858,7 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
   unsigned i, nelt = d->nelt, nelt2 = nelt / 2;
   unsigned HOST_WIDE_INT contents;
   unsigned char remap[2 * MAX_VECT_LEN];
-  rtx seq;
+  rtx_insn *seq;
   bool ok, same_halves = false;
 
   if (GET_MODE_SIZE (d->vmode) == 16)
@@ -43635,15 +44297,16 @@ expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d)
            dfirst.perm[i] = (i & (nelt2 - 1))
                             + ((perm >> (2 * (i >= nelt2))) & 3) * nelt2;
 
+         canonicalize_perm (&dfirst);
          ok = expand_vec_perm_1 (&dfirst);
          gcc_assert (ok);
 
          /* And dsecond is some single insn shuffle, taking
             d->op0 and result of vperm2f128 (if perm < 16) or
             d->op1 and result of vperm2f128 (otherwise).  */
-         dsecond.op1 = dfirst.target;
          if (perm >= 16)
-           dsecond.op0 = dfirst.op1;
+           dsecond.op0 = dsecond.op1;
+         dsecond.op1 = dfirst.target;
 
          ok = expand_vec_perm_1 (&dsecond);
          gcc_assert (ok);
@@ -43651,7 +44314,8 @@ expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d)
          return true;
        }
 
-      /* For one operand, the only useful vperm2f128 permutation is 0x10.  */
+      /* For one operand, the only useful vperm2f128 permutation is 0x01
+        aka lanes swap.  */
       if (d->one_operand_p)
        return false;
     }
@@ -43745,7 +44409,7 @@ expand_vec_perm_vperm2f128_vblend (struct expand_vec_perm_d *d)
 {
   struct expand_vec_perm_d dfirst, dsecond;
   unsigned i, j, msk, nelt = d->nelt, nelt2 = nelt / 2;
-  rtx seq;
+  rtx_insn *seq;
   bool ok;
   rtx (*blend) (rtx, rtx, rtx, rtx) = NULL;
 
@@ -44540,7 +45204,7 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
   if (expand_vec_perm_pshuflw_pshufhw (d))
     return true;
 
-  if (expand_vec_perm_palignr (d))
+  if (expand_vec_perm_palignr (d, false))
     return true;
 
   if (expand_vec_perm_interleave2 (d))
@@ -44555,6 +45219,9 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
   if (expand_vec_perm_vperm2f128 (d))
     return true;
 
+  if (expand_vec_perm_pblendv (d))
+    return true;
+
   /* Try sequences of three instructions.  */
 
   if (expand_vec_perm_2vperm2f128_vshuf (d))
@@ -44706,21 +45373,56 @@ ix86_vectorize_vec_perm_const_ok (enum machine_mode vmode,
 
   /* Given sufficient ISA support we can just return true here
      for selected vector modes.  */
-  if (d.vmode == V16SImode || d.vmode == V16SFmode
-      || d.vmode == V8DFmode || d.vmode == V8DImode)
-    /* All implementable with a single vpermi2 insn.  */
-    return true;
-  if (GET_MODE_SIZE (d.vmode) == 16)
+  switch (d.vmode)
     {
+    case V16SFmode:
+    case V16SImode:
+    case V8DImode:
+    case V8DFmode:
+      if (TARGET_AVX512F)
+       /* All implementable with a single vpermi2 insn.  */
+       return true;
+      break;
+    case V32HImode:
+      if (TARGET_AVX512BW)
+       /* All implementable with a single vpermi2 insn.  */
+       return true;
+      break;
+    case V8SImode:
+    case V8SFmode:
+    case V4DFmode:
+    case V4DImode:
+      if (TARGET_AVX512VL)
+       /* All implementable with a single vpermi2 insn.  */
+       return true;
+      break;
+    case V16HImode:
+      if (TARGET_AVX2)
+       /* Implementable with 4 vpshufb insns, 2 vpermq and 3 vpor insns.  */
+       return true;
+      break;
+    case V32QImode:
+      if (TARGET_AVX2)
+       /* Implementable with 4 vpshufb insns, 2 vpermq and 3 vpor insns.  */
+       return true;
+      break;
+    case V4SImode:
+    case V4SFmode:
+    case V8HImode:
+    case V16QImode:
       /* All implementable with a single vpperm insn.  */
       if (TARGET_XOP)
        return true;
       /* All implementable with 2 pshufb + 1 ior.  */
       if (TARGET_SSSE3)
        return true;
+      break;
+    case V2DImode:
+    case V2DFmode:
       /* All implementable with shufpd or unpck[lh]pd.  */
-      if (d.nelt == 2)
-       return true;
+      return true;
+    default:
+      return false;
     }
 
   /* Extract the values from the vector CST into the permutation
@@ -44840,6 +45542,11 @@ ix86_expand_vecop_qihi (enum rtx_code code, rtx dest, rtx op1, rtx op2)
       gen_il = gen_avx2_interleave_lowv32qi;
       gen_ih = gen_avx2_interleave_highv32qi;
       break;
+    case V64QImode:
+      himode = V32HImode;
+      gen_il = gen_avx512bw_interleave_lowv64qi;
+      gen_ih = gen_avx512bw_interleave_highv64qi;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -44900,7 +45607,7 @@ ix86_expand_vecop_qihi (enum rtx_code code, rtx dest, rtx op1, rtx op2)
     {
       /* For SSE2, we used an full interleave, so the desired
         results are in the even elements.  */
-      for (i = 0; i < 32; ++i)
+      for (i = 0; i < 64; ++i)
        d.perm[i] = i * 2;
     }
   else
@@ -44908,7 +45615,7 @@ ix86_expand_vecop_qihi (enum rtx_code code, rtx dest, rtx op1, rtx op2)
       /* For AVX, the interleave used above was not cross-lane.  So the
         extraction is evens but with the second and third quarter swapped.
         Happily, that is even one insn shorter than even extraction.  */
-      for (i = 0; i < 32; ++i)
+      for (i = 0; i < 64; ++i)
        d.perm[i] = i * 2 + ((i & 24) == 8 ? 16 : (i & 24) == 16 ? -16 : 0);
     }
 
@@ -45106,6 +45813,9 @@ ix86_expand_mul_widen_hilo (rtx dest, rtx op1, rtx op2,
 
     case V16QImode:
     case V32QImode:
+    case V32HImode:
+    case V16SImode:
+    case V64QImode:
       t1 = gen_reg_rtx (wmode);
       t2 = gen_reg_rtx (wmode);
       ix86_expand_sse_unpack (t1, op1, uns_p, high_p);
@@ -45160,7 +45870,13 @@ ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2)
   enum machine_mode mode = GET_MODE (op0);
   rtx t1, t2, t3, t4, t5, t6;
 
-  if (TARGET_XOP && mode == V2DImode)
+  if (TARGET_AVX512DQ && mode == V8DImode)
+    emit_insn (gen_avx512dq_mulv8di3 (op0, op1, op2));
+  else if (TARGET_AVX512DQ && TARGET_AVX512VL && mode == V4DImode)
+    emit_insn (gen_avx512dq_mulv4di3 (op0, op1, op2));
+  else if (TARGET_AVX512DQ && TARGET_AVX512VL && mode == V2DImode)
+    emit_insn (gen_avx512dq_mulv2di3 (op0, op1, op2));
+  else if (TARGET_XOP && mode == V2DImode)
     {
       /* op1: A,B,C,D, op2: E,F,G,H */
       op1 = gen_lowpart (V4SImode, op1);
@@ -45187,8 +45903,13 @@ ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2)
       /* t4: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */
       emit_insn (gen_ashlv2di3 (t4, t3, GEN_INT (32)));
 
-      /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */
-      emit_insn (gen_xop_pmacsdql (op0, op1, op2, t4));
+      /* Multiply lower parts and add all */
+      t5 = gen_reg_rtx (V2DImode);
+      emit_insn (gen_vec_widen_umult_even_v4si (t5, 
+                                       gen_lowpart (V4SImode, op1),
+                                       gen_lowpart (V4SImode, op2)));
+      op0 = expand_binop (mode, add_optab, t5, t4, op0, 1, OPTAB_DIRECT);
+
     }
   else
     {
@@ -45640,7 +46361,7 @@ static dispatch_windows *dispatch_window_list1;
 /* Get dispatch group of insn.  */
 
 static enum dispatch_group
-get_mem_group (rtx insn)
+get_mem_group (rtx_insn *insn)
 {
   enum attr_memory memory;
 
@@ -45662,7 +46383,7 @@ get_mem_group (rtx insn)
 /* Return true if insn is a compare instruction.  */
 
 static bool
-is_cmp (rtx insn)
+is_cmp (rtx_insn *insn)
 {
   enum attr_type type;
 
@@ -45899,7 +46620,7 @@ has_immediate (rtx insn)
 /* Return single or double path for instructions.  */
 
 static enum insn_path
-get_insn_path (rtx insn)
+get_insn_path (rtx_insn *insn)
 {
   enum attr_amdfam10_decode path = get_attr_amdfam10_decode (insn);
 
@@ -45915,7 +46636,7 @@ get_insn_path (rtx insn)
 /* Return insn dispatch group.  */
 
 static enum dispatch_group
-get_insn_group (rtx insn)
+get_insn_group (rtx_insn *insn)
 {
   enum dispatch_group group = get_mem_group (insn);
   if (group)
@@ -45940,7 +46661,7 @@ get_insn_group (rtx insn)
    window WINDOW_LIST.  */
 
 static int
-count_num_restricted (rtx insn, dispatch_windows *window_list)
+count_num_restricted (rtx_insn *insn, dispatch_windows *window_list)
 {
   enum dispatch_group group = get_insn_group (insn);
   int imm_size;
@@ -45990,7 +46711,7 @@ count_num_restricted (rtx insn, dispatch_windows *window_list)
    last window scheduled.  */
 
 static bool
-fits_dispatch_window (rtx insn)
+fits_dispatch_window (rtx_insn *insn)
 {
   dispatch_windows *window_list = dispatch_window_list;
   dispatch_windows *window_list_next = dispatch_window_list->next;
@@ -46047,7 +46768,7 @@ fits_dispatch_window (rtx insn)
    dispatch window WINDOW_LIST.  */
 
 static void
-add_insn_window (rtx insn, dispatch_windows *window_list, int num_uops)
+add_insn_window (rtx_insn *insn, dispatch_windows *window_list, int num_uops)
 {
   int byte_len = min_insn_size (insn);
   int num_insn = window_list->num_insn;
@@ -46098,7 +46819,7 @@ add_insn_window (rtx insn, dispatch_windows *window_list, int num_uops)
    the window exceed allowable, it allocates a new window.  */
 
 static void
-add_to_dispatch_window (rtx insn)
+add_to_dispatch_window (rtx_insn *insn)
 {
   int byte_len;
   dispatch_windows *window_list;
@@ -46233,7 +46954,7 @@ debug_dispatch_window (int window_num)
 /* Print INSN dispatch information to FILE.  */
 
 DEBUG_FUNCTION static void
-debug_insn_dispatch_info_file (FILE *file, rtx insn)
+debug_insn_dispatch_info_file (FILE *file, rtx_insn *insn)
 {
   int byte_len;
   enum insn_path path;
@@ -46277,7 +46998,7 @@ debug_ready_dispatch (void)
 /* This routine is the driver of the dispatch scheduler.  */
 
 static void
-do_dispatch (rtx insn, int mode)
+do_dispatch (rtx_insn *insn, int mode)
 {
   if (mode == DISPATCH_INIT)
     init_dispatch_sched ();
@@ -46288,7 +47009,7 @@ do_dispatch (rtx insn, int mode)
 /* Return TRUE if Dispatch Scheduling is supported.  */
 
 static bool
-has_dispatch (rtx insn, int action)
+has_dispatch (rtx_insn *insn, int action)
 {
   if ((TARGET_BDVER1 || TARGET_BDVER2 || TARGET_BDVER3 || TARGET_BDVER4)
       && flag_dispatch_scheduler)
@@ -46327,11 +47048,20 @@ has_dispatch (rtx insn, int action)
    enabled for other processors.  */
 
 static int
-ix86_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED,
-                         enum machine_mode mode)
+ix86_reassociation_width (unsigned int, enum machine_mode mode)
 {
   int res = 1;
 
+  /* Vector part.  */
+  if (VECTOR_MODE_P (mode))
+    {
+      if (TARGET_VECTOR_PARALLEL_EXECUTION)
+       return 2;
+      else
+       return 1;
+    }
+
+  /* Scalar part.  */
   if (INTEGRAL_MODE_P (mode) && TARGET_REASSOC_INT_TO_PARALLEL)
     res = 2;
   else if (FLOAT_MODE_P (mode) && TARGET_REASSOC_FP_TO_PARALLEL)
@@ -46352,9 +47082,11 @@ ix86_preferred_simd_mode (enum machine_mode mode)
   switch (mode)
     {
     case QImode:
-      return (TARGET_AVX && !TARGET_PREFER_AVX128) ? V32QImode : V16QImode;
+      return TARGET_AVX512BW ? V64QImode :
+       (TARGET_AVX && !TARGET_PREFER_AVX128) ? V32QImode : V16QImode;
     case HImode:
-      return (TARGET_AVX && !TARGET_PREFER_AVX128) ? V16HImode : V8HImode;
+      return TARGET_AVX512BW ? V32HImode :
+       (TARGET_AVX && !TARGET_PREFER_AVX128) ? V16HImode : V8HImode;
     case SImode:
       return TARGET_AVX512F ? V16SImode :
        (TARGET_AVX && !TARGET_PREFER_AVX128) ? V8SImode : V4SImode;
@@ -46407,7 +47139,7 @@ ix86_spill_class (reg_class_t rclass, enum machine_mode mode)
 {
   if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL && ! TARGET_MMX
       && (mode == SImode || (TARGET_64BIT && mode == DImode))
-      && INTEGER_CLASS_P (rclass))
+      && rclass != NO_REGS && INTEGER_CLASS_P (rclass))
     return ALL_SSE_REGS;
   return NO_REGS;
 }
@@ -46415,7 +47147,7 @@ ix86_spill_class (reg_class_t rclass, enum machine_mode mode)
 /* Implement targetm.vectorize.init_cost.  */
 
 static void *
-ix86_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED)
+ix86_init_cost (struct loop *)
 {
   unsigned *cost = XNEWVEC (unsigned, 3);
   cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0;
@@ -46723,7 +47455,7 @@ static unsigned
 ix86_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
 {
   basic_block *bbs;
-  rtx insn;
+  rtx_insn *insn;
   unsigned i;
   unsigned mem_count = 0;
 
@@ -46736,7 +47468,8 @@ ix86_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
     {
       for (insn = BB_HEAD (bbs[i]); insn != BB_END (bbs[i]); insn = NEXT_INSN (insn))
         if (NONDEBUG_INSN_P (insn))
-            for_each_rtx (&insn, (rtx_function) ix86_loop_memcount, &mem_count);
+            for_each_rtx_in_insn (&insn, (rtx_function) ix86_loop_memcount,
+                                 &mem_count);
     }
   free (bbs);
 
@@ -46786,15 +47519,14 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
                      hold_fnclex);
       *clear = build_call_expr (fnclex, 0);
       tree sw_var = create_tmp_var (short_unsigned_type_node, NULL);
-      mark_addressable (sw_var);
-      tree su_ptr = build_pointer_type (short_unsigned_type_node);
-      tree sw_addr = build1 (ADDR_EXPR, su_ptr, sw_var);
-      tree fnstsw_call = build_call_expr (fnstsw, 1, sw_addr);
+      tree fnstsw_call = build_call_expr (fnstsw, 0);
+      tree sw_mod = build2 (MODIFY_EXPR, short_unsigned_type_node,
+                           sw_var, fnstsw_call);
       tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
       tree update_mod = build2 (MODIFY_EXPR, integer_type_node,
                                exceptions_var, exceptions_x87);
       *update = build2 (COMPOUND_EXPR, integer_type_node,
-                       fnstsw_call, update_mod);
+                       sw_mod, update_mod);
       tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
       *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
     }
@@ -47067,6 +47799,10 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
 #undef TARGET_FUNCTION_ARG
 #define TARGET_FUNCTION_ARG ix86_function_arg
+#undef TARGET_INIT_PIC_REG
+#define TARGET_INIT_PIC_REG ix86_init_pic_reg
+#undef TARGET_USE_PSEUDO_PIC_REG
+#define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
 #undef TARGET_FUNCTION_ARG_BOUNDARY
 #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
 #undef TARGET_PASS_BY_REFERENCE
@@ -47101,6 +47837,10 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #undef TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
 
+#undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
+#define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
+  ix86_libgcc_floating_mode_supported_p
+
 #undef TARGET_C_MODE_FOR_SUFFIX
 #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
 
@@ -47270,6 +48010,9 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #undef TARGET_MODE_PRIORITY
 #define TARGET_MODE_PRIORITY ix86_mode_priority
 
+#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
+#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 #include "gt-i386.h"