Bring in branch-8 bugfixes into GCC80. vendor/GCC80
authorzrj <rimvydas.jasinskas@gmail.com>
Tue, 16 Apr 2019 02:39:06 +0000 (05:39 +0300)
committerzrj <zrj@dragonflybsd.org>
Tue, 16 Apr 2019 03:02:39 +0000 (06:02 +0300)
Bugfixes as of April 15.
Huge thanks to gcc developers for keeping longterm branches and
backporting/testing all the bugfixes.

46 files changed:
contrib/gcc-8.0/LAST_UPDATED
contrib/gcc-8.0/gcc/BASE-VER
contrib/gcc-8.0/gcc/c-family/c-ada-spec.c
contrib/gcc-8.0/gcc/cgraph.c
contrib/gcc-8.0/gcc/cgraph.h
contrib/gcc-8.0/gcc/cgraphclones.c
contrib/gcc-8.0/gcc/config/i386/i386.c
contrib/gcc-8.0/gcc/config/i386/i386.md
contrib/gcc-8.0/gcc/config/i386/sse.md
contrib/gcc-8.0/gcc/cp/class.c
contrib/gcc-8.0/gcc/cp/decl2.c
contrib/gcc-8.0/gcc/cp/mangle.c
contrib/gcc-8.0/gcc/cp/parser.c
contrib/gcc-8.0/gcc/cp/pt.c
contrib/gcc-8.0/gcc/cp/semantics.c
contrib/gcc-8.0/gcc/cp/typeck.c
contrib/gcc-8.0/gcc/cp/typeck2.c
contrib/gcc-8.0/gcc/dwarf2out.c
contrib/gcc-8.0/gcc/fold-const.c
contrib/gcc-8.0/gcc/gimple-ssa-warn-restrict.c
contrib/gcc-8.0/gcc/input.c
contrib/gcc-8.0/gcc/ipa-cp.c
contrib/gcc-8.0/gcc/loop-unroll.c
contrib/gcc-8.0/gcc/lra-constraints.c
contrib/gcc-8.0/gcc/lto-wrapper.c
contrib/gcc-8.0/gcc/multiple_target.c
contrib/gcc-8.0/gcc/opts.c
contrib/gcc-8.0/gcc/params.def
contrib/gcc-8.0/gcc/passes.c
contrib/gcc-8.0/gcc/rtl.h
contrib/gcc-8.0/gcc/rtlanal.c
contrib/gcc-8.0/gcc/tree-cfgcleanup.c
contrib/gcc-8.0/gcc/tree-cfgcleanup.h
contrib/gcc-8.0/gcc/tree-inline.c
contrib/gcc-8.0/gcc/tree-scalar-evolution.c
contrib/gcc-8.0/gcc/tree-sra.c
contrib/gcc-8.0/gcc/tree-ssa-dom.c
contrib/gcc-8.0/gcc/tree-ssa-ifcombine.c
contrib/gcc-8.0/gcc/tree-ssa-loop-ch.c
contrib/gcc-8.0/gcc/tree-ssa-loop-ivcanon.c
contrib/gcc-8.0/gcc/tree-ssa-math-opts.c
contrib/gcc-8.0/gcc/tree-ssa-structalias.c
contrib/gcc-8.0/gcc/tree-vect-data-refs.c
contrib/gcc-8.0/include/longlong.h
contrib/gcc-8.0/libcpp/line-map.c
contrib/gcc-8.0/libstdc++-v3/include/bits/char_traits.h

index 8331296..503b895 100644 (file)
@@ -1 +1,2 @@
-Obtained from SVN: tags/gcc_8_3_0_release revision 269117
+Mon Apr 15 17:37:23 EEST 2019
+Mon Apr 15 14:37:23 UTC 2019 (revision c33279ba94a:bbd97bfa4ce:8937eeb1a08801a7f7fc67b6f3d08ca62cdb4853)
index 30fdb59..f5f558c 100644 (file)
@@ -2686,6 +2686,8 @@ print_destructor (pretty_printer *buffer, tree t, tree type)
   tree decl_name = DECL_NAME (TYPE_NAME (type));
 
   pp_string (buffer, "Delete_");
+  if (strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del", 8) == 0)
+    pp_string (buffer, "And_Free_");
   pp_ada_tree_identifier (buffer, decl_name, t, 0, false);
 }
 
@@ -2937,9 +2939,10 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
          if (DECL_ARTIFICIAL (t))
            return 0;
 
-         /* Only consider constructors/destructors for complete objects.  */
+         /* Only consider complete constructors and deleting destructors.  */
          if (strncmp (IDENTIFIER_POINTER (decl_name), "__ct_comp", 9) != 0
-             && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0)
+             && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0
+             && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_del", 8) != 0)
            return 0;
        }
 
index 9f3a292..74a8212 100644 (file)
@@ -3007,42 +3007,55 @@ cgraph_node::collect_callers (void)
   return redirect_callers;
 }
 
-/* Return TRUE if NODE2 a clone of NODE or is equivalent to it.  */
+
+/* Return TRUE if NODE2 a clone of NODE or is equivalent to it.  Return
+   optimistically true if this cannot be determined.  */
 
 static bool
 clone_of_p (cgraph_node *node, cgraph_node *node2)
 {
-  bool skipped_thunk = false;
   node = node->ultimate_alias_target ();
   node2 = node2->ultimate_alias_target ();
 
+  if (node2->clone_of == node
+      || node2->former_clone_of == node->decl)
+    return true;
+
+  if (!node->thunk.thunk_p && !node->former_thunk_p ())
+    {
+      while (node2 && node->decl != node2->decl)
+       node2 = node2->clone_of;
+      return node2 != NULL;
+    }
+
   /* There are no virtual clones of thunks so check former_clone_of or if we
      might have skipped thunks because this adjustments are no longer
      necessary.  */
-  while (node->thunk.thunk_p)
+  while (node->thunk.thunk_p || node->former_thunk_p ())
     {
-      if (node2->former_clone_of == node->decl)
-       return true;
       if (!node->thunk.this_adjusting)
        return false;
+      /* In case of instrumented expanded thunks, which can have multiple calls
+        in them, we do not know how to continue and just have to be
+        optimistic.  */
+      if (node->callees->next_callee)
+       return true;
       node = node->callees->callee->ultimate_alias_target ();
-      skipped_thunk = true;
-    }
 
-  if (skipped_thunk)
-    {
       if (!node2->clone.args_to_skip
          || !bitmap_bit_p (node2->clone.args_to_skip, 0))
        return false;
       if (node2->former_clone_of == node->decl)
        return true;
-      else if (!node2->clone_of)
-       return false;
+
+      cgraph_node *n2 = node2;
+      while (n2 && node->decl != n2->decl)
+       n2 = n2->clone_of;
+      if (n2)
+       return true;
     }
 
-  while (node != node2 && node2)
-    node2 = node2->clone_of;
-  return node2 != NULL;
+  return false;
 }
 
 /* Verify edge count and frequency.  */
index afb2745..9495863 100644 (file)
@@ -997,12 +997,17 @@ public:
      If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
      If non_NULL NEW_ENTRY determine new entry BB of the clone.
 
+     If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
+     add the attributes to DECL_ATTRIBUTES.  And call valid_attribute_p
+     that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
+     of the declaration.
+
      Return the new version's cgraph node.  */
   cgraph_node *create_version_clone_with_body
     (vec<cgraph_edge *> redirect_callers,
      vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip,
      bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block,
-     const char *clone_name);
+     const char *clone_name, tree target_attributes = NULL_TREE);
 
   /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
      corresponding to cgraph_node.  */
@@ -1258,6 +1263,9 @@ public:
      Note that at WPA stage, the function body may not be present in memory.  */
   inline bool has_gimple_body_p (void);
 
+  /* Return true if this node represents a former, i.e. an expanded, thunk.  */
+  inline bool former_thunk_p (void);
+
   /* Return true if function should be optimized for size.  */
   bool optimize_for_size_p (void);
 
@@ -2858,6 +2866,16 @@ cgraph_node::has_gimple_body_p (void)
   return definition && !thunk.thunk_p && !alias;
 }
 
+/* Return true if this node represents a former, i.e. an expanded, thunk.  */
+
+inline bool
+cgraph_node::former_thunk_p (void)
+{
+  return (!thunk.thunk_p
+         && (thunk.fixed_offset
+             || thunk.virtual_offset_p));
+}
+
 /* Walk all functions with body defined.  */
 #define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
    for ((node) = symtab->first_function_with_gimple_body (); (node); \
index 6e84a31..bdccde1 100644 (file)
@@ -938,6 +938,11 @@ cgraph_node::create_version_clone (tree new_decl,
    If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
    If non_NULL NEW_ENTRY determine new entry BB of the clone.
 
+   If TARGET_ATTRIBUTES is non-null, when creating a new declaration,
+   add the attributes to DECL_ATTRIBUTES.  And call valid_attribute_p
+   that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
+   of the declaration.
+
    Return the new version's cgraph node.  */
 
 cgraph_node *
@@ -945,7 +950,7 @@ cgraph_node::create_version_clone_with_body
   (vec<cgraph_edge *> redirect_callers,
    vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip,
    bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block,
-   const char *suffix)
+   const char *suffix, tree target_attributes)
 {
   tree old_decl = decl;
   cgraph_node *new_version_node = NULL;
@@ -968,6 +973,19 @@ cgraph_node::create_version_clone_with_body
   SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
   SET_DECL_RTL (new_decl, NULL);
 
+  if (target_attributes)
+    {
+      DECL_ATTRIBUTES (new_decl) = target_attributes;
+
+      location_t saved_loc = input_location;
+      tree v = TREE_VALUE (target_attributes);
+      input_location = DECL_SOURCE_LOCATION (new_decl);
+      bool r = targetm.target_option.valid_attribute_p (new_decl, NULL, v, 0);
+      input_location = saved_loc;
+      if (!r)
+       return NULL;
+    }
+
   /* When the old decl was a con-/destructor make sure the clone isn't.  */
   DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
   DECL_STATIC_DESTRUCTOR (new_decl) = 0;
index 7732f88..30a20af 100644 (file)
@@ -1024,16 +1024,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
 
     case ASHIFT:
     case LSHIFTRT:
-      if (!REG_P (XEXP (src, 1))
-         && (!SUBREG_P (XEXP (src, 1))
-             || SUBREG_BYTE (XEXP (src, 1)) != 0
-             || !REG_P (SUBREG_REG (XEXP (src, 1))))
-         && (!CONST_INT_P (XEXP (src, 1))
-             || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, 63)))
-       return false;
-
-      if (GET_MODE (XEXP (src, 1)) != QImode
-         && !CONST_INT_P (XEXP (src, 1)))
+      if (!CONST_INT_P (XEXP (src, 1))
+         || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, 63))
        return false;
       break;
 
@@ -1630,15 +1622,10 @@ dimode_scalar_chain::compute_convert_gain ()
        {
          if (CONST_INT_P (XEXP (src, 0)))
            gain -= vector_const_cost (XEXP (src, 0));
-         if (CONST_INT_P (XEXP (src, 1)))
-           {
-             gain += ix86_cost->shift_const;
-             if (INTVAL (XEXP (src, 1)) >= 32)
-               gain -= COSTS_N_INSNS (1);
-           }
-         else
-           /* Additional gain for omitting two CMOVs.  */
-           gain += ix86_cost->shift_var + COSTS_N_INSNS (2);
+
+         gain += ix86_cost->shift_const;
+         if (INTVAL (XEXP (src, 1)) >= 32)
+           gain -= COSTS_N_INSNS (1);
        }
       else if (GET_CODE (src) == PLUS
               || GET_CODE (src) == MINUS
@@ -1754,60 +1741,14 @@ dimode_scalar_chain::make_vector_copies (unsigned regno)
 {
   rtx reg = regno_reg_rtx[regno];
   rtx vreg = gen_reg_rtx (DImode);
-  bool count_reg = false;
   df_ref ref;
 
   for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref))
     if (!bitmap_bit_p (insns, DF_REF_INSN_UID (ref)))
       {
-       df_ref use;
-
-       /* Detect the count register of a shift instruction.  */
-       for (use = DF_REG_USE_CHAIN (regno); use; use = DF_REF_NEXT_REG (use))
-         if (bitmap_bit_p (insns, DF_REF_INSN_UID (use)))
-           {
-             rtx_insn *insn = DF_REF_INSN (use);
-             rtx def_set = single_set (insn);
-
-             gcc_assert (def_set);
-
-             rtx src = SET_SRC (def_set);
-
-             if ((GET_CODE (src) == ASHIFT
-                  || GET_CODE (src) == ASHIFTRT
-                  || GET_CODE (src) == LSHIFTRT)
-                 && !CONST_INT_P (XEXP (src, 1))
-                 && reg_or_subregno (XEXP (src, 1)) == regno)
-               count_reg = true;
-           }
-
        start_sequence ();
-       if (count_reg)
-         {
-           rtx qreg = gen_lowpart (QImode, reg);
-           rtx tmp = gen_reg_rtx (SImode);
-
-           if (TARGET_ZERO_EXTEND_WITH_AND
-               && optimize_function_for_speed_p (cfun))
-             {
-               emit_move_insn (tmp, const0_rtx);
-               emit_insn (gen_movstrictqi
-                          (gen_lowpart (QImode, tmp), qreg));
-             }
-           else
-             emit_insn (gen_rtx_SET
-                        (tmp, gen_rtx_ZERO_EXTEND (SImode, qreg)));
-
-           if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
-             {
-               rtx slot = assign_386_stack_local (SImode, SLOT_STV_TEMP);
-               emit_move_insn (slot, tmp);
-               tmp = copy_rtx (slot);
-             }
 
-           emit_insn (gen_zero_extendsidi2 (vreg, tmp));
-         }
-       else if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
+       if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
          {
            rtx tmp = assign_386_stack_local (DImode, SLOT_STV_TEMP);
            emit_move_insn (adjust_address (tmp, SImode, 0),
@@ -1855,22 +1796,8 @@ dimode_scalar_chain::make_vector_copies (unsigned regno)
     if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref)))
       {
        rtx_insn *insn = DF_REF_INSN (ref);
-       if (count_reg)
-         {
-           rtx def_set = single_set (insn);
-           gcc_assert (def_set);
-
-           rtx src = SET_SRC (def_set);
 
-           if ((GET_CODE (src) == ASHIFT
-                || GET_CODE (src) == ASHIFTRT
-                || GET_CODE (src) == LSHIFTRT)
-               && !CONST_INT_P (XEXP (src, 1))
-               && reg_or_subregno (XEXP (src, 1)) == regno)
-             XEXP (src, 1) = vreg;
-         }
-       else
-         replace_with_subreg_in_insn (insn, reg, vreg);
+       replace_with_subreg_in_insn (insn, reg, vreg);
 
        if (dump_file)
          fprintf (dump_file, "  Replaced r%d with r%d in insn %d\n",
@@ -1973,42 +1900,7 @@ dimode_scalar_chain::convert_reg (unsigned regno)
            rtx src = SET_SRC (def_set);
            rtx dst = SET_DEST (def_set);
 
-           if ((GET_CODE (src) == ASHIFT
-                || GET_CODE (src) == ASHIFTRT
-                || GET_CODE (src) == LSHIFTRT)
-               && !CONST_INT_P (XEXP (src, 1))
-               && reg_or_subregno (XEXP (src, 1)) == regno)
-             {
-               rtx tmp2 = gen_reg_rtx (V2DImode);
-
-               start_sequence ();
-
-               if (TARGET_SSE4_1)
-                 emit_insn (gen_sse4_1_zero_extendv2qiv2di2
-                            (tmp2, gen_rtx_SUBREG (V16QImode, reg, 0)));
-               else
-                 {
-                   rtx vec_cst
-                     = gen_rtx_CONST_VECTOR (V2DImode,
-                                             gen_rtvec (2, GEN_INT (0xff),
-                                                        const0_rtx));
-                   vec_cst
-                     = validize_mem (force_const_mem (V2DImode, vec_cst));
-
-                   emit_insn (gen_rtx_SET
-                              (tmp2,
-                               gen_rtx_AND (V2DImode,
-                                            gen_rtx_SUBREG (V2DImode, reg, 0),
-                                            vec_cst)));
-                 }
-               rtx_insn *seq = get_insns ();
-               end_sequence ();
-
-               emit_insn_before (seq, insn);
-
-               XEXP (src, 1) = gen_rtx_SUBREG (DImode, tmp2, 0);
-             }
-           else if (!MEM_P (dst) || !REG_P (src))
+           if (!MEM_P (dst) || !REG_P (src))
              replace_with_subreg_in_insn (insn, reg, reg);
 
            bitmap_clear_bit (conv, INSN_UID (insn));
@@ -4958,6 +4850,12 @@ ix86_option_override_internal (bool main_args_p,
                           opts->x_param_values,
                           opts_set->x_param_values);
 
+  /* PR86952: jump table usage with retpolines is slow.
+     The PR provides some numbers about the slowness.  */
+  if (ix86_indirect_branch != indirect_branch_keep
+      && !opts_set->x_flag_jump_tables)
+    opts->x_flag_jump_tables = 0;
+
   return true;
 }
 
@@ -18121,6 +18019,7 @@ print_reg (rtx x, int code, FILE *file)
    ; -- print a semicolon (after prefixes due to bug in older gas).
    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
    ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
+   M -- print addr32 prefix for TARGET_X32 with VSIB address.
    ! -- print MPX prefix for jxx/call/ret instructions if required.
  */
 
@@ -18668,6 +18567,26 @@ ix86_print_operand (FILE *file, rtx x, int code)
          putc (TARGET_AVX2 ? 'i' : 'f', file);
          return;
 
+       case 'M':
+         if (TARGET_X32)
+           {
+             /* NB: 32-bit indices in VSIB address are sign-extended
+                to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
+                sign-extended to 0xfffffffff7fa3010 which is invalid
+                address.  Add addr32 prefix if there is no base
+                register nor symbol.  */
+             bool ok;
+             struct ix86_address parts;
+             ok = ix86_decompose_address (x, &parts);
+             gcc_assert (ok && parts.index == NULL_RTX);
+             if (parts.base == NULL_RTX
+                 && (parts.disp == NULL_RTX
+                     || !symbolic_operand (parts.disp,
+                                           GET_MODE (parts.disp))))
+               fputs ("addr32 ", file);
+           }
+         return;
+
        case '^':
          if (TARGET_64BIT && Pmode != word_mode)
            fputs ("addr32 ", file);
@@ -39641,7 +39560,7 @@ ix86_vectorize_builtin_scatter (const_tree vectype,
 static bool
 use_rsqrt_p ()
 {
-  return (TARGET_SSE_MATH
+  return (TARGET_SSE && TARGET_SSE_MATH
          && flag_finite_math_only
          && !flag_trapping_math
          && flag_unsafe_math_optimizations);
@@ -50999,7 +50918,7 @@ ix86_float_exceptions_rounding_supported_p (void)
      there is no adddf3 pattern (since x87 floating point only has
      XFmode operations) so the default hook implementation gets this
      wrong.  */
-  return TARGET_80387 || TARGET_SSE_MATH;
+  return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
 }
 
 /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
@@ -51007,7 +50926,7 @@ ix86_float_exceptions_rounding_supported_p (void)
 static void
 ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 {
-  if (!TARGET_80387 && !TARGET_SSE_MATH)
+  if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
     return;
   tree exceptions_var = create_tmp_var_raw (integer_type_node);
   if (TARGET_80387)
@@ -51042,7 +50961,7 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
       tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
       *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
     }
-  if (TARGET_SSE_MATH)
+  if (TARGET_SSE && TARGET_SSE_MATH)
     {
       tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
       tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
@@ -51399,7 +51318,7 @@ ix86_excess_precision (enum excess_precision_type type)
          return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
        else if (!TARGET_MIX_SSE_I387)
          {
-           if (!TARGET_SSE_MATH)
+           if (!(TARGET_SSE && TARGET_SSE_MATH))
              return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
            else if (TARGET_SSE2)
              return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
index 7691160..417b6e6 100644 (file)
   [(parallel [(set (match_dup 0)
                   (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
              (clobber (reg:CC FLAGS_REG))])]
-  "operands[2] = gen_lowpart (SImode, operands[2]);")
+{
+  if (GET_CODE (operands[2]) == SYMBOL_REF
+      || GET_CODE (operands[2]) == LABEL_REF)
+    {
+      operands[2] = shallow_copy_rtx (operands[2]);
+      PUT_MODE (operands[2], SImode);
+    }
+  else
+    operands[2] = gen_lowpart (SImode, operands[2]);
+})
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
 (define_insn "*andsi_1_zext"
index d5cab80..b42292e 100644 (file)
   [(set (match_operand:VF1_128_256 0 "register_operand")
        (unspec:VF1_128_256
          [(match_operand:VF1_128_256 1 "vector_operand")] UNSPEC_RSQRT))]
-  "TARGET_SSE_MATH"
+  "TARGET_SSE && TARGET_SSE_MATH"
 {
   ix86_emit_swsqrtsf (operands[0], operands[1], <MODE>mode, true);
   DONE;
     case 3:
       /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
         gas changed what it requires incompatibly.  */
-      return "vgatherpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vgatherpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
-      return "vgatherpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vgatherpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
     case 3:
       /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
         gas changed what it requires incompatibly.  */
-      return "vgatherpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vgatherpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
-      return "vgatherpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vgatherpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
     case 7:
       /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
         gas changed what it requires incompatibly.  */
-      return "vscatterpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vscatterpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
     case 6:
-      return "vscatterpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vscatterpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
     case 7:
       /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
         gas changed what it requires incompatibly.  */
-      return "vscatterpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vscatterpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
     case 6:
-      return "vscatterpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
+      return "%M2vscatterpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
          UNSPEC_GATHER))
    (clobber (match_scratch:VEC_GATHER_MODE 1 "=&x"))]
   "TARGET_AVX2"
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %7, %0|%0, %7, %1}"
+  "%M3v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %7, %0|%0, %7, %1}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
          UNSPEC_GATHER))
    (clobber (match_scratch:VEC_GATHER_MODE 1 "=&x"))]
   "TARGET_AVX2"
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %6, %0|%0, %6, %1}"
+  "%M2v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %6, %0|%0, %6, %1}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
          UNSPEC_GATHER))
    (clobber (match_scratch:VEC_GATHER_MODE 1 "=&x"))]
   "TARGET_AVX2"
-  "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %7, %2|%2, %7, %5}"
+  "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %7, %2|%2, %7, %5}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
   "TARGET_AVX2"
 {
   if (<MODE>mode != <VEC_GATHER_SRCDI>mode)
-    return "v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %x0|%x0, %6, %4}";
-  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}";
+    return "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %x0|%x0, %6, %4}";
+  return "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}";
 }
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
                     (const_int 2) (const_int 3)])))
    (clobber (match_scratch:VI4F_256 1 "=&x"))]
   "TARGET_AVX2"
-  "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %7, %0|%0, %7, %5}"
+  "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %7, %0|%0, %7, %5}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
                     (const_int 2) (const_int 3)])))
    (clobber (match_scratch:VI4F_256 1 "=&x"))]
   "TARGET_AVX2"
-  "v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}"
+  "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
   "TARGET_AVX512F"
 ;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as
 ;; gas changed what it requires incompatibly.
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%6, %0%{%2%}|%0%{%2%}, %X6}"
+  "%M4v<sseintprefix>gatherd<ssemodesuffix>\t{%6, %0%{%2%}|%0%{%2%}, %X6}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
   "TARGET_AVX512F"
 ;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
 ;; gas changed what it requires incompatibly.
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}"
+  "%M3v<sseintprefix>gatherd<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
   "TARGET_AVX512F"
 ;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as
 ;; gas changed what it requires incompatibly.
-  "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %X6}"
+  "%M4v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %X6}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
   if (<MODE>mode != <VEC_GATHER_SRCDI>mode)
     {
       if (<MODE_SIZE> != 64)
-       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %x0%{%1%}|%x0%{%1%}, %X5}";
+       return "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %x0%{%1%}|%x0%{%1%}, %X5}";
       else
-       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %t0%{%1%}|%t0%{%1%}, %X5}";
+       return "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %t0%{%1%}|%t0%{%1%}, %X5}";
     }
-  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}";
+  return "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}";
 }
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
   "TARGET_AVX512F"
 ;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
 ;; gas changed what it requires incompatibly.
-  "v<sseintprefix>scatterd<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
+  "%M0v<sseintprefix>scatterd<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
   "TARGET_AVX512F"
 ;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
 ;; gas changed what it requires incompatibly.
-  "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
+  "%M0v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
index 834ba17..0b789b1 100644 (file)
@@ -5171,7 +5171,9 @@ classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p)
     for (ovl_iterator iter (get_class_binding_direct
                            (t, assign_op_identifier));
         iter; ++iter)
-      if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
+      if ((!user_p || !DECL_ARTIFICIAL (*iter))
+         && DECL_CONTEXT (*iter) == t
+         && move_fn_p (*iter))
        return true;
   
   return false;
index 6a67c4e..1043af4 100644 (file)
@@ -4905,7 +4905,10 @@ c_parse_final_cleanups (void)
        {
          if (var_finalized_p (decl) || DECL_REALLY_EXTERN (decl)
              /* Don't write it out if we haven't seen a definition.  */
-             || (DECL_IN_AGGR_P (decl) && !DECL_INLINE_VAR_P (decl)))
+             || (DECL_IN_AGGR_P (decl) && !DECL_INLINE_VAR_P (decl))
+             /* Or haven't instantiated it.  */
+             || (DECL_TEMPLATE_INSTANTIATION (decl)
+                 && !DECL_TEMPLATE_INSTANTIATED (decl)))
            continue;
          import_export_decl (decl);
          /* If this static data member is needed, provide it to the
index 2f65709..5146162 100644 (file)
@@ -3047,7 +3047,8 @@ write_expression (tree expr)
        {
          scope = TREE_OPERAND (expr, 0);
          member = TREE_OPERAND (expr, 1);
-         gcc_assert (!BASELINK_P (member));
+         if (BASELINK_P (member))
+           member = BASELINK_FUNCTIONS (member);
        }
       else
        {
index 18b09af..e479ed9 100644 (file)
@@ -19125,8 +19125,9 @@ cp_parser_asm_definition (cp_parser* parser)
   location_t volatile_loc = UNKNOWN_LOCATION;
   location_t inline_loc = UNKNOWN_LOCATION;
   location_t goto_loc = UNKNOWN_LOCATION;
+  location_t first_loc = UNKNOWN_LOCATION;
 
-  if (cp_parser_allow_gnu_extensions_p (parser) && parser->in_function_body)
+  if (cp_parser_allow_gnu_extensions_p (parser))
     for (;;)
       {
        cp_token *token = cp_lexer_peek_token (parser->lexer);
@@ -19152,6 +19153,8 @@ cp_parser_asm_definition (cp_parser* parser)
              }
            else
              inline_loc = loc;
+           if (!first_loc)
+             first_loc = loc;
            cp_lexer_consume_token (parser->lexer);
            continue;
 
@@ -19163,6 +19166,8 @@ cp_parser_asm_definition (cp_parser* parser)
              }
            else
              goto_loc = loc;
+           if (!first_loc)
+             first_loc = loc;
            cp_lexer_consume_token (parser->lexer);
            continue;
 
@@ -19182,6 +19187,12 @@ cp_parser_asm_definition (cp_parser* parser)
   bool inline_p = (inline_loc != UNKNOWN_LOCATION);
   bool goto_p = (goto_loc != UNKNOWN_LOCATION);
 
+  if (!parser->in_function_body && (inline_p || goto_p))
+    {
+      error_at (first_loc, "asm qualifier outside of function body");
+      inline_p = goto_p = false;
+    }
+
   /* Look for the opening `('.  */
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return;
index f1a8fee..d0001c4 100644 (file)
@@ -11732,8 +11732,6 @@ fold_expression (tree t, tree left, tree right, tsubst_flags_t complain)
     {
     case COMPOUND_EXPR:
       return build_x_compound_expr (input_location, left, right, complain);
-    case DOTSTAR_EXPR:
-      return build_m_component_ref (left, right, complain);
     default:
       return build_x_binary_op (input_location, code,
                                 left, TREE_CODE (left),
@@ -13023,6 +13021,11 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
        set_constraints (r, ci);
       }
 
+  if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
+    SET_DECL_FRIEND_CONTEXT (r,
+                            tsubst (DECL_FRIEND_CONTEXT (t),
+                                    args, complain, in_decl));
+
   /* Set up the DECL_TEMPLATE_INFO for R.  There's no need to do
      this in the special friend case mentioned above where
      GEN_TMPL is NULL.  */
@@ -13084,11 +13087,6 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
           && !grok_op_properties (r, /*complain=*/true))
     return error_mark_node;
 
-  if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
-    SET_DECL_FRIEND_CONTEXT (r,
-                            tsubst (DECL_FRIEND_CONTEXT (t),
-                                    args, complain, in_decl));
-
   /* Possibly limit visibility based on template args.  */
   DECL_VISIBILITY (r) = VISIBILITY_DEFAULT;
   if (DECL_VISIBILITY_SPECIFIED (t))
@@ -18797,6 +18795,12 @@ tsubst_copy_and_build (tree t,
           looked up by digest_init.  */
        process_index_p = !(type && MAYBE_CLASS_TYPE_P (type));
 
+       if (null_member_pointer_value_p (t))
+         {
+           gcc_assert (same_type_p (type, TREE_TYPE (t)));
+           RETURN (t);
+         }
+
        n = vec_safe_copy (CONSTRUCTOR_ELTS (t));
         newlen = vec_safe_length (n);
        FOR_EACH_VEC_SAFE_ELT (n, idx, ce)
@@ -25998,8 +26002,10 @@ make_auto (void)
 tree
 make_template_placeholder (tree tmpl)
 {
-  tree t = make_auto_1 (DECL_NAME (tmpl), true);
+  tree t = make_auto_1 (DECL_NAME (tmpl), false);
   CLASS_PLACEHOLDER_TEMPLATE (t) = tmpl;
+  /* Our canonical type depends on the placeholder.  */
+  TYPE_CANONICAL (t) = canonical_type_parameter (t);
   return t;
 }
 
@@ -26534,6 +26540,9 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
        error ("non-class template %qT used without template arguments", tmpl);
       return error_mark_node;
     }
+  if (init && TREE_TYPE (init) == ptype)
+    /* Using the template parm as its own argument.  */
+    return ptype;
 
   tree type = TREE_TYPE (tmpl);
 
@@ -26601,7 +26610,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
 
   tree outer_args = NULL_TREE;
   if (DECL_CLASS_SCOPE_P (tmpl)
-      && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (tmpl)))
+      && CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (tmpl)))
     {
       outer_args = CLASSTYPE_TI_ARGS (DECL_CONTEXT (tmpl));
       type = TREE_TYPE (most_general_template (tmpl));
index a5460fa..0d7d75a 100644 (file)
@@ -645,10 +645,13 @@ maybe_convert_cond (tree cond)
     return NULL_TREE;
 
   /* Wait until we instantiate templates before doing conversion.  */
-  if (processing_template_decl)
+  if (processing_template_decl
+      && (type_dependent_expression_p (cond)
+         /* For GCC 8 only convert non-dependent condition in a lambda.  */
+         || !current_lambda_expr ()))
     return cond;
 
-  if (warn_sequence_point)
+  if (warn_sequence_point && !processing_template_decl)
     verify_sequence_points (cond);
 
   /* Do the conversion.  */
index 9ffea19..afc1fd7 100644 (file)
@@ -5747,18 +5747,17 @@ cp_truthvalue_conversion (tree expr)
     return c_common_truthvalue_conversion (input_location, expr);
 }
 
-/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
+/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  This
+   is a low-level function; most callers should use maybe_convert_cond.  */
 
 tree
 condition_conversion (tree expr)
 {
   tree t;
-  /* Anything that might happen in a template should go through
-     maybe_convert_cond.  */
-  gcc_assert (!processing_template_decl);
   t = perform_implicit_conversion_flags (boolean_type_node, expr,
                                         tf_warning_or_error, LOOKUP_NORMAL);
-  t = fold_build_cleanup_point_expr (boolean_type_node, t);
+  if (!processing_template_decl)
+    t = fold_build_cleanup_point_expr (boolean_type_node, t);
   return t;
 }
 
index b91c98d..3428407 100644 (file)
@@ -1538,6 +1538,13 @@ process_init_constructor_record (tree type, tree init, int nested,
            }
        }
 
+      if (DECL_SIZE (field) && integer_zerop (DECL_SIZE (field))
+         && !TREE_SIDE_EFFECTS (next))
+       /* Don't add trivial initialization of an empty base/field to the
+          constructor, as they might not be ordered the way the back-end
+          expects.  */
+       continue;
+
       /* If this is a bitfield, now convert to the lowered type.  */
       if (type != TREE_TYPE (field))
        next = cp_convert_and_check (TREE_TYPE (field), next, complain);
index 0940959..36884c7 100644 (file)
@@ -2875,9 +2875,13 @@ const struct gcc_debug_hooks dwarf2_lineno_debug_hooks =
    separate comdat sections since the linker will then be able to
    remove duplicates.  But not all tools support .debug_types sections
    yet.  For Dwarf V5 or higher .debug_types doesn't exist any more,
-   it is DW_UT_type unit type in .debug_info section.  */
+   it is DW_UT_type unit type in .debug_info section.  For late LTO
+   debug there should be almost no types emitted so avoid enabling
+   -fdebug-types-section there.  */
 
-#define use_debug_types (dwarf_version >= 4 && flag_debug_types_section)
+#define use_debug_types (dwarf_version >= 4 \
+                        && flag_debug_types_section \
+                        && !in_lto_p)
 
 /* Various DIE's use offsets relative to the beginning of the
    .debug_info section to refer to each other.  */
@@ -3713,7 +3717,7 @@ static void output_die_abbrevs (unsigned long, dw_die_ref);
 static void output_die (dw_die_ref);
 static void output_compilation_unit_header (enum dwarf_unit_type);
 static void output_comp_unit (dw_die_ref, int, const unsigned char *);
-static void output_comdat_type_unit (comdat_type_node *);
+static void output_comdat_type_unit (comdat_type_node *, bool);
 static const char *dwarf2_name (tree, int);
 static void add_pubname (tree, dw_die_ref);
 static void add_enumerator_pubname (const char *, dw_die_ref);
@@ -9425,7 +9429,7 @@ size_of_die (dw_die_ref die)
                 we use DW_FORM_ref_addr.  In DWARF2, DW_FORM_ref_addr
                 is sized by target address length, whereas in DWARF3
                 it's always sized as an offset.  */
-             if (use_debug_types)
+             if (AT_ref (a)->comdat_type_p)
                size += DWARF_TYPE_SIGNATURE_SIZE;
              else if (dwarf_version == 2)
                size += DWARF2_ADDR_SIZE;
@@ -9869,7 +9873,12 @@ value_format (dw_attr_node *a)
       return DW_FORM_flag;
     case dw_val_class_die_ref:
       if (AT_ref_external (a))
-       return use_debug_types ? DW_FORM_ref_sig8 : DW_FORM_ref_addr;
+       {
+         if (AT_ref (a)->comdat_type_p)
+           return DW_FORM_ref_sig8;
+         else
+           return DW_FORM_ref_addr;
+       }
       else
        return DW_FORM_ref;
     case dw_val_class_fde_ref:
@@ -11217,7 +11226,8 @@ output_skeleton_debug_sections (dw_die_ref comp_unit,
 /* Output a comdat type unit DIE and its children.  */
 
 static void
-output_comdat_type_unit (comdat_type_node *node)
+output_comdat_type_unit (comdat_type_node *node,
+                        bool early_lto_debug ATTRIBUTE_UNUSED)
 {
   const char *secname;
   char *tmp;
@@ -11244,14 +11254,16 @@ output_comdat_type_unit (comdat_type_node *node)
   if (dwarf_version >= 5)
     {
       if (!dwarf_split_debug_info)
-       secname = ".debug_info";
+       secname = early_lto_debug ? DEBUG_LTO_INFO_SECTION : DEBUG_INFO_SECTION;
       else
-       secname = ".debug_info.dwo";
+       secname = (early_lto_debug
+                  ? DEBUG_LTO_DWO_INFO_SECTION : DEBUG_DWO_INFO_SECTION);
     }
   else if (!dwarf_split_debug_info)
-    secname = ".debug_types";
+    secname = early_lto_debug ? ".gnu.debuglto_.debug_types" : ".debug_types";
   else
-    secname = ".debug_types.dwo";
+    secname = (early_lto_debug
+              ? ".gnu.debuglto_.debug_types.dwo" : ".debug_types.dwo");
 
   tmp = XALLOCAVEC (char, 4 + DWARF_TYPE_SIGNATURE_SIZE * 2);
   sprintf (tmp, dwarf_version >= 5 ? "wi." : "wt.");
@@ -31398,7 +31410,7 @@ dwarf2out_finish (const char *)
                          ? dl_section_ref
                          : debug_skeleton_line_section_label));
 
-      output_comdat_type_unit (ctnode);
+      output_comdat_type_unit (ctnode, false);
       *slot = ctnode;
     }
 
@@ -32039,7 +32051,7 @@ dwarf2out_early_finish (const char *filename)
                          ? debug_line_section_label
                          : debug_skeleton_line_section_label));
 
-      output_comdat_type_unit (ctnode);
+      output_comdat_type_unit (ctnode, true);
       *slot = ctnode;
     }
 
index 36bcc65..af67feb 100644 (file)
@@ -5515,12 +5515,15 @@ fold_range_test (location_t loc, enum tree_code code, tree type,
   /* On machines where the branch cost is expensive, if this is a
      short-circuited branch and the underlying object on both sides
      is the same, make a non-short-circuit operation.  */
-  else if (LOGICAL_OP_NON_SHORT_CIRCUIT
-          && !flag_sanitize_coverage
-          && lhs != 0 && rhs != 0
-          && (code == TRUTH_ANDIF_EXPR
-              || code == TRUTH_ORIF_EXPR)
-          && operand_equal_p (lhs, rhs, 0))
+  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
+  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
+    logical_op_non_short_circuit
+      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
+  if (logical_op_non_short_circuit
+      && !flag_sanitize_coverage
+      && lhs != 0 && rhs != 0
+      && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
+      && operand_equal_p (lhs, rhs, 0))
     {
       /* If simple enough, just rewrite.  Otherwise, make a SAVE_EXPR
         unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
@@ -8165,7 +8168,11 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type,
   if ((tem = fold_truth_andor_1 (loc, code, type, arg0, arg1)) != 0)
     return tem;
 
-  if (LOGICAL_OP_NON_SHORT_CIRCUIT
+  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
+  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
+    logical_op_non_short_circuit
+      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
+  if (logical_op_non_short_circuit
       && !flag_sanitize_coverage
       && (code == TRUTH_AND_EXPR
           || code == TRUTH_ANDIF_EXPR
index 3d0664d..722bc6f 100644 (file)
@@ -314,13 +314,9 @@ builtin_memref::extend_offset_range (tree offset)
          offrange[0] += offset_int::from (min, SIGNED);
          offrange[1] += offset_int::from (max, SIGNED);
        }
-      else if (rng == VR_ANTI_RANGE)
-       {
-         offrange[0] += offset_int::from (max + 1, SIGNED);
-         offrange[1] += offset_int::from (min - 1, SIGNED);
-       }
       else
        {
+         /* Handle an anti-range the same as no range at all.  */
          gimple *stmt = SSA_NAME_DEF_STMT (offset);
          tree type;
          if (is_gimple_assign (stmt)
@@ -702,6 +698,10 @@ builtin_access::builtin_access (gcall *call, builtin_memref &dst,
   offset_int bounds[2] = { maxobjsize, maxobjsize };
   if (dstref->strbounded_p)
     {
+      unsigned nargs = gimple_call_num_args (call);
+      if (nargs <= sizeargno)
+       return;
+
       tree size = gimple_call_arg (call, sizeargno);
       tree range[2];
       if (get_size_range (size, range, true))
index b667576..26c2bf2 100644 (file)
@@ -3538,6 +3538,34 @@ for_each_line_table_case (void (*testcase) (const line_table_case &))
   ASSERT_EQ (num_cases_tested, 2 * 12);
 }
 
+/* Verify that when presented with a consecutive pair of locations with
+   a very large line offset, we don't attempt to consolidate them into
+   a single ordinary linemap where the line offsets within the line map
+   would lead to overflow (PR lto/88147).  */
+
+static void
+test_line_offset_overflow ()
+{
+  line_table_test ltt (line_table_case (5, 0));
+
+  linemap_add (line_table, LC_ENTER, false, "foo.c", 0);
+  linemap_line_start (line_table, 1, 100);
+  location_t loc_a = linemap_line_start (line_table, 2578, 255);
+  assert_loceq ("foo.c", 2578, 0, loc_a);
+
+  const line_map_ordinary *ordmap_a = LINEMAPS_LAST_ORDINARY_MAP (line_table);
+  ASSERT_EQ (ordmap_a->m_column_and_range_bits, 13);
+  ASSERT_EQ (ordmap_a->m_range_bits, 5);
+
+  location_t loc_b = linemap_line_start (line_table, 404198, 512);
+  assert_loceq ("foo.c", 404198, 0, loc_b);
+
+  /* We should have started a new linemap, rather than attempting to store
+     a very large line offset.  */
+  const line_map_ordinary *ordmap_b = LINEMAPS_LAST_ORDINARY_MAP (line_table);
+  ASSERT_NE (ordmap_a, ordmap_b);
+}
+
 /* Run all of the selftests within this file.  */
 
 void
@@ -3577,6 +3605,8 @@ input_c_tests ()
   for_each_line_table_case (test_lexer_char_constants);
 
   test_reading_source_line ();
+
+  test_line_offset_overflow ();
 }
 
 } // namespace selftest
index 5bd4df0..84d4907 100644 (file)
@@ -2852,11 +2852,18 @@ perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
   base_time -= time;
   if (base_time > 65535)
     base_time = 65535;
-  time_benefit = base_time.to_int ()
-    + devirtualization_time_bonus (node, known_csts, known_contexts,
-                                  known_aggs_ptrs)
-    + hint_time_bonus (hints)
-    + removable_params_cost + est_move_cost;
+
+  /* Extern inline functions have no cloning local time benefits because they
+     will be inlined anyway.  The only reason to clone them is if it enables
+     optimization in any of the functions they call.  */
+  if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
+    time_benefit = 0;
+  else
+    time_benefit = base_time.to_int ()
+      + devirtualization_time_bonus (node, known_csts, known_contexts,
+                                    known_aggs_ptrs)
+      + hint_time_bonus (hints)
+      + removable_params_cost + est_move_cost;
 
   gcc_checking_assert (size >=0);
   /* The inliner-heuristics based estimates may think that in certain
index 5a03932..0f50747 100644 (file)
@@ -399,7 +399,7 @@ decide_unroll_constant_iterations (struct loop *loop, int flags)
     {
       /* However we cannot unroll completely at the RTL level a loop with
         constant number of iterations; it should have been peeled instead.  */
-      if ((unsigned) loop->unroll - 1 > desc->niter - 2)
+      if (desc->niter == 0 || (unsigned) loop->unroll > desc->niter - 1)
        {
          if (dump_file)
            fprintf (dump_file, ";; Loop should have been peeled\n");
index 5405c4d..e3adf78 100644 (file)
@@ -6293,6 +6293,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
                        add_to_hard_reg_set (&s, PSEUDO_REGNO_MODE (dst_regno),
                                             reg_renumber[dst_regno]);
                      AND_COMPL_HARD_REG_SET (live_hard_regs, s);
+                     AND_COMPL_HARD_REG_SET (potential_reload_hard_regs, s);
                    }
                  /* We should invalidate potential inheritance or
                     splitting for the current insn usages to the next
index 7a3f93a..dada53d 100644 (file)
@@ -1669,7 +1669,9 @@ cont:
          struct pex_obj *pex;
          char jobs[32];
 
-         fprintf (mstream, "all:");
+         fprintf (mstream,
+                  ".PHONY: all\n"
+                  "all:");
          for (i = 0; i < nr; ++i)
            {
              int j = ltrans_priorities[i*2 + 1];
index a1fe09a..be15af3 100644 (file)
@@ -294,7 +294,8 @@ create_new_asm_name (char *old_asm_name, char *new_asm_name)
 /*  Creates target clone of NODE.  */
 
 static cgraph_node *
-create_target_clone (cgraph_node *node, bool definition, char *name)
+create_target_clone (cgraph_node *node, bool definition, char *name,
+                    tree attributes)
 {
   cgraph_node *new_node;
 
@@ -303,13 +304,16 @@ create_target_clone (cgraph_node *node, bool definition, char *name)
       new_node = node->create_version_clone_with_body (vNULL, NULL,
                                                       NULL, false,
                                                       NULL, NULL,
-                                                      name);
+                                                      name, attributes);
+      if (new_node == NULL)
+       return NULL;
       new_node->force_output = true;
     }
   else
     {
       tree new_decl = copy_node (node->decl);
       new_node = cgraph_node::get_create (new_decl);
+      DECL_ATTRIBUTES (new_decl) = attributes;
       /* Generate a new name for the new version.  */
       symtab->change_decl_assembler_name (new_node->decl,
                                          clone_function_name (node->decl,
@@ -399,22 +403,16 @@ expand_target_clones (struct cgraph_node *node, bool definition)
 
       create_new_asm_name (attr, suffix);
       /* Create new target clone.  */
-      cgraph_node *new_node = create_target_clone (node, definition, suffix);
-      new_node->local.local = false;
-      XDELETEVEC (suffix);
-
-      /* Set new attribute for the clone.  */
       tree attributes = make_attribute ("target", attr,
-                                       DECL_ATTRIBUTES (new_node->decl));
-      DECL_ATTRIBUTES (new_node->decl) = attributes;
-      location_t saved_loc = input_location;
-      input_location = DECL_SOURCE_LOCATION (node->decl);
-      if (!targetm.target_option.valid_attribute_p (new_node->decl, NULL,
-                                                   TREE_VALUE (attributes),
-                                                   0))
+                                       DECL_ATTRIBUTES (node->decl));
+
+      cgraph_node *new_node = create_target_clone (node, definition, suffix,
+                                                  attributes);
+      if (new_node == NULL)
        return false;
+      new_node->local.local = false;
+      XDELETEVEC (suffix);
 
-      input_location = saved_loc;
       decl2_v = new_node->function_version ();
       if (decl2_v != NULL)
         continue;
@@ -441,13 +439,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
                                    DECL_ATTRIBUTES (node->decl));
   DECL_ATTRIBUTES (node->decl) = attributes;
   node->local.local = false;
-  location_t saved_loc = input_location;
-  input_location = DECL_SOURCE_LOCATION (node->decl);
-  bool ret
-    = targetm.target_option.valid_attribute_p (node->decl, NULL,
-                                              TREE_VALUE (attributes), 0);
-  input_location = saved_loc;
-  return ret;
+  return true;
 }
 
 static unsigned int
index 442f250..2803088 100644 (file)
@@ -922,6 +922,14 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
                      "linker plugin");
          opts->x_flag_fat_lto_objects = 1;
        }
+
+      /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
+      if (opts->x_dwarf_split_debug_info)
+       {
+         inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
+                 " disabling");
+         opts->x_dwarf_split_debug_info = 0;
+       }
     }
 
   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
index dad47ec..e3ad05f 100644 (file)
@@ -1331,6 +1331,11 @@ DEFPARAM(PARAM_AVOID_FMA_MAX_BITS,
         "Maximum number of bits for which we avoid creating FMAs.",
         0, 0, 512)
 
+DEFPARAM(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,
+        "logical-op-non-short-circuit",
+        "True if a non-short-circuit operation is optimal.",
+        -1, -1, 1)
+
 /*
 
 Local variables:
index 65ad690..a6c1185 100644 (file)
@@ -1944,7 +1944,7 @@ execute_function_todo (function *fn, void *data)
   /* Always cleanup the CFG before trying to update SSA.  */
   if (flags & TODO_cleanup_cfg)
     {
-      cleanup_tree_cfg ();
+      cleanup_tree_cfg (flags & TODO_update_ssa_any);
 
       /* When cleanup_tree_cfg merges consecutive blocks, it may
         perform some simplistic propagation when removing single
index 51f70cd..3156712 100644 (file)
@@ -4355,6 +4355,7 @@ word_register_operation_p (const_rtx x)
 {
   switch (GET_CODE (x))
     {
+    case CONST_INT:
     case ROTATE:
     case ROTATERT:
     case SIGN_EXTRACT:
index 0e79e53..dabc540 100644 (file)
@@ -358,10 +358,10 @@ get_initial_register_offset (int from, int to)
   if (to == from)
     return 0;
 
-  /* It is not safe to call INITIAL_ELIMINATION_OFFSET
-     before the reload pass.  We need to give at least
-     an estimation for the resulting frame size.  */
-  if (! reload_completed)
+  /* It is not safe to call INITIAL_ELIMINATION_OFFSET before the epilogue
+     is completed, but we need to give at least an estimate for the stack
+     pointer based on the frame size.  */
+  if (!epilogue_completed)
     {
       offset1 = crtl->outgoing_args_size + get_frame_size ();
 #if !STACK_GROWS_DOWNWARD
index c261e71..6d57329 100644 (file)
@@ -43,6 +43,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-match.h"
 #include "gimple-fold.h"
 #include "tree-ssa-loop-niter.h"
+#include "tree-into-ssa.h"
+#include "tree-cfgcleanup.h"
 
 
 /* The set of blocks in that at least one of the following changes happened:
@@ -761,7 +763,7 @@ cleanup_control_flow_pre ()
 /* Iterate the cfg cleanups, while anything changes.  */
 
 static bool
-cleanup_tree_cfg_1 (void)
+cleanup_tree_cfg_1 (unsigned ssa_update_flags)
 {
   bool retval = false;
   basic_block bb;
@@ -786,6 +788,8 @@ cleanup_tree_cfg_1 (void)
 
   /* After doing the above SSA form should be valid (or an update SSA
      should be required).  */
+  if (ssa_update_flags)
+    update_ssa (ssa_update_flags);
 
   /* Continue by iterating over all basic blocks looking for BB merging
      opportunities.  */
@@ -828,7 +832,7 @@ mfb_keep_latches (edge e)
    Return true if the flowgraph was modified, false otherwise.  */
 
 static bool
-cleanup_tree_cfg_noloop (void)
+cleanup_tree_cfg_noloop (unsigned ssa_update_flags)
 {
   bool changed;
 
@@ -908,7 +912,7 @@ cleanup_tree_cfg_noloop (void)
          }
     }
 
-  changed |= cleanup_tree_cfg_1 ();
+  changed |= cleanup_tree_cfg_1 (ssa_update_flags);
 
   gcc_assert (dom_info_available_p (CDI_DOMINATORS));
 
@@ -966,9 +970,9 @@ repair_loop_structures (void)
 /* Cleanup cfg and repair loop structures.  */
 
 bool
-cleanup_tree_cfg (void)
+cleanup_tree_cfg (unsigned ssa_update_flags)
 {
-  bool changed = cleanup_tree_cfg_noloop ();
+  bool changed = cleanup_tree_cfg_noloop (ssa_update_flags);
 
   if (current_loops != NULL
       && loops_state_satisfies_p (LOOPS_NEED_FIXUP))
index 0b33d87..7b6dbc1 100644 (file)
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 /* In tree-cfgcleanup.c  */
 extern bitmap cfgcleanup_altered_bbs;
-extern bool cleanup_tree_cfg (void);
+extern bool cleanup_tree_cfg (unsigned = 0);
 extern bool fixup_noreturn_call (gimple *stmt);
 
 #endif /* GCC_TREE_CFGCLEANUP_H */
index 324c168..f7a3216 100644 (file)
@@ -5539,6 +5539,10 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy)
   if (CODE_CONTAINS_STRUCT (TREE_CODE (copy), TS_DECL_WRTL)
       && !TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
     SET_DECL_RTL (copy, 0);
+  /* For vector typed decls make sure to update DECL_MODE according
+     to the new function context.  */
+  if (VECTOR_TYPE_P (TREE_TYPE (copy)))
+    SET_DECL_MODE (copy, TYPE_MODE (TREE_TYPE (copy)));
 
   /* These args would always appear unused, if not for this.  */
   TREE_USED (copy) = 1;
index fefc9de..759bc61 100644 (file)
@@ -875,7 +875,7 @@ get_loop_exit_condition (const struct loop *loop)
       gimple *stmt;
 
       stmt = last_stmt (exit_edge->src);
-      if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
+      if (gcond *cond_stmt = safe_dyn_cast <gcond *> (stmt))
        res = cond_stmt;
     }
 
@@ -1421,6 +1421,11 @@ simplify_peeled_chrec (struct loop *loop, tree arg, tree init_cond)
       return build_polynomial_chrec (loop->num, init_cond, right);
     }
 
+  /* The affine code only deals with pointer and integer types.  */
+  if (!POINTER_TYPE_P (type)
+      && !INTEGRAL_TYPE_P (type))
+    return chrec_dont_know;
+
   /* Try harder to check if they are equal.  */
   tree_to_aff_combination_expand (left, type, &aff1, &peeled_chrec_map);
   tree_to_aff_combination_expand (step_val, type, &aff2, &peeled_chrec_map);
index b513676..bb373b3 100644 (file)
@@ -2729,8 +2729,12 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
 
              rchild->grp_hint = 1;
              new_acc->grp_hint |= new_acc->grp_read;
-             if (rchild->first_child)
-               ret |= propagate_subaccesses_across_link (new_acc, rchild);
+             if (rchild->first_child
+                 && propagate_subaccesses_across_link (new_acc, rchild))
+               {
+                 ret = 1;
+                 add_access_to_work_queue (new_acc);
+               }
            }
          else
            {
index f60e96c..0ebcc6d 100644 (file)
@@ -170,11 +170,10 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
   gimple *def_stmt = SSA_NAME_DEF_STMT (name);
   if (is_gimple_assign (def_stmt))
     {
-      /* We know the result of DEF_STMT was zero.  See if that allows
-        us to deduce anything about the SSA_NAMEs used on the RHS.  */
       enum tree_code code = gimple_assign_rhs_code (def_stmt);
       switch (code)
        {
+       /* If the result of an OR is zero, then its operands are, too.  */
        case BIT_IOR_EXPR:
          if (integer_zerop (value))
            {
@@ -188,8 +187,7 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
            }
          break;
 
-      /* We know the result of DEF_STMT was one.  See if that allows
-        us to deduce anything about the SSA_NAMEs used on the RHS.  */
+       /* If the result of an AND is nonzero, then its operands are, too.  */
        case BIT_AND_EXPR:
          if (!integer_zerop (value))
            {
@@ -296,7 +294,6 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
            break;
          }
 
-
        case EQ_EXPR:
        case NE_EXPR:
          {
@@ -336,7 +333,28 @@ edge_info::derive_equivalences (tree name, tree value, int recursion_limit)
        case NEGATE_EXPR:
          {
            tree rhs = gimple_assign_rhs1 (def_stmt);
-           tree res = fold_build1 (code, TREE_TYPE (rhs), value);
+           tree res;
+           /* If this is a NOT and the operand has a boolean range, then we
+              know its value must be zero or one.  We are not supposed to
+              have a BIT_NOT_EXPR for boolean types with precision > 1 in
+              the general case, see e.g. the handling of TRUTH_NOT_EXPR in
+              the gimplifier, but it can be generated by match.pd out of
+              a BIT_XOR_EXPR wrapped in a BIT_AND_EXPR.  Now the handling
+              of BIT_AND_EXPR above already forces a specific semantics for
+              boolean types with precision > 1 so we must do the same here,
+              otherwise we could change the semantics of TRUTH_NOT_EXPR for
+              boolean types with precision > 1.  */
+           if (code == BIT_NOT_EXPR
+               && TREE_CODE (rhs) == SSA_NAME
+               && ssa_name_has_boolean_range (rhs))
+             {
+               if ((TREE_INT_CST_LOW (value) & 1) == 0)
+                 res = build_one_cst (TREE_TYPE (rhs));
+               else
+                 res = build_zero_cst (TREE_TYPE (rhs));
+             }
+           else
+             res = fold_build1 (code, TREE_TYPE (rhs), value);
            derive_equivalences (rhs, res, recursion_limit - 1);
            break;
          }
index b63c600..828ee81 100644 (file)
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimplify-me.h"
 #include "tree-cfg.h"
 #include "tree-ssa.h"
+#include "params.h"
 
 #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
 #define LOGICAL_OP_NON_SHORT_CIRCUIT \
@@ -556,7 +557,11 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
        {
          tree t1, t2;
          gimple_stmt_iterator gsi;
-         if (!LOGICAL_OP_NON_SHORT_CIRCUIT || flag_sanitize_coverage)
+         bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
+         if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
+           logical_op_non_short_circuit
+             = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
+         if (!logical_op_non_short_circuit || flag_sanitize_coverage)
            return false;
          /* Only do this optimization if the inner bb contains only the conditional. */
          if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb)))
index 488999d..92e0c43 100644 (file)
@@ -376,11 +376,23 @@ ch_base::copy_headers (function *fun)
                {
                  gimple *stmt = gsi_stmt (bsi);
                  if (gimple_code (stmt) == GIMPLE_COND)
-                   gimple_set_no_warning (stmt, true);
+                   {
+                     tree lhs = gimple_cond_lhs (stmt);
+                     if (gimple_cond_code (stmt) != EQ_EXPR
+                         && gimple_cond_code (stmt) != NE_EXPR
+                         && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+                         && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs)))
+                       gimple_set_no_warning (stmt, true);
+                   }
                  else if (is_gimple_assign (stmt))
                    {
                      enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
-                     if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
+                     tree rhs1 = gimple_assign_rhs1 (stmt);
+                     if (TREE_CODE_CLASS (rhs_code) == tcc_comparison
+                         && rhs_code != EQ_EXPR
+                         && rhs_code != NE_EXPR
+                         && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+                         && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1)))
                        gimple_set_no_warning (stmt, true);
                    }
                }
index 7f8b519..5b6db6a 100644 (file)
@@ -1177,7 +1177,7 @@ canonicalize_loop_induction_variables (struct loop *loop,
        = niter_desc.may_be_zero && !integer_zerop (niter_desc.may_be_zero);
     }
   if (TREE_CODE (niter) == INTEGER_CST)
-    locus = gimple_location (last_stmt (exit->src));
+    locus = gimple_location_safe (last_stmt (exit->src));
   else
     {
       /* For non-constant niter fold may_be_zero into niter again.  */
@@ -1204,7 +1204,7 @@ canonicalize_loop_induction_variables (struct loop *loop,
        niter = find_loop_niter_by_eval (loop, &exit);
 
       if (exit)
-        locus = gimple_location (last_stmt (exit->src));
+        locus = gimple_location_safe (last_stmt (exit->src));
 
       if (TREE_CODE (niter) != INTEGER_CST)
        exit = NULL;
index 8463979..a8f275b 100644 (file)
@@ -603,7 +603,7 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
 
   /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x).  */
   if (sqrt_recip_count > square_recip_count)
-    return;
+    goto out;
 
   /* Do the expensive part only if we can hope to optimize something.  */
   if (count + square_recip_count >= threshold && count >= 1)
@@ -646,6 +646,7 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
        }
     }
 
+out:
   for (occ = occ_head; occ; )
     occ = free_bb (occ);
 
index 373946f..0e69629 100644 (file)
@@ -7552,7 +7552,10 @@ compute_dependence_clique (void)
            }
          if (used)
            {
-             bitmap_set_bit (rvars, restrict_var->id);
+             /* Add all subvars to the set of restrict pointed-to set. */
+             for (unsigned sv = restrict_var->head; sv != 0;
+                  sv = get_varinfo (sv)->next)
+               bitmap_set_bit (rvars, sv);
              varinfo_t escaped = get_varinfo (find (escaped_id));
              if (bitmap_bit_p (escaped->solution, restrict_var->id))
                escaped_p = true;
index 68f8027..0c04ff1 100644 (file)
@@ -206,26 +206,60 @@ vect_preserves_scalar_order_p (gimple *stmt_a, gimple *stmt_b)
     return true;
 
   /* STMT_A and STMT_B belong to overlapping groups.  All loads in a
-     group are emitted at the position of the last scalar load and all
-     stores in a group are emitted at the position of the last scalar store.
+     SLP group are emitted at the position of the last scalar load and
+     all loads in an interleaving group are emitted at the position
+     of the first scalar load.
+     Stores in a group are emitted at the position of the last scalar store.
      Compute that position and check whether the resulting order matches
-     the current one.  */
-  gimple *last_a = GROUP_FIRST_ELEMENT (stmtinfo_a);
+     the current one.
+     We have not yet decided between SLP and interleaving so we have
+     to conservatively assume both.  */
+  gimple *il_a;
+  gimple *last_a = il_a = GROUP_FIRST_ELEMENT (stmtinfo_a);
   if (last_a)
-    for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_a)); s;
-        s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
-      last_a = get_later_stmt (last_a, s);
+    {
+      for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_a)); s;
+          s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+       last_a = get_later_stmt (last_a, s);
+      if (!DR_IS_WRITE (STMT_VINFO_DATA_REF (stmtinfo_a)))
+       {
+         for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (il_a)); s;
+              s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+           if (get_later_stmt (il_a, s) == il_a)
+             il_a = s;
+       }
+      else
+       il_a = last_a;
+    }
   else
-    last_a = stmt_a;
-  gimple *last_b = GROUP_FIRST_ELEMENT (stmtinfo_b);
+    last_a = il_a = stmt_a;
+  gimple *il_b;
+  gimple *last_b = il_b = GROUP_FIRST_ELEMENT (stmtinfo_b);
   if (last_b)
-    for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_b)); s;
-        s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
-      last_b = get_later_stmt (last_b, s);
+    {
+      for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_b)); s;
+          s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+       last_b = get_later_stmt (last_b, s);
+      if (!DR_IS_WRITE (STMT_VINFO_DATA_REF (stmtinfo_b)))
+       {
+         for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (il_b)); s;
+              s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+           if (get_later_stmt (il_b, s) == il_b)
+             il_b = s;
+       }
+      else
+       il_b = last_b;
+    }
   else
-    last_b = stmt_b;
-  return ((get_later_stmt (last_a, last_b) == last_a)
-         == (get_later_stmt (stmt_a, stmt_b) == stmt_a));
+    last_b = il_b = stmt_b;
+  bool a_after_b = (get_later_stmt (stmt_a, stmt_b) == stmt_a);
+  return (/* SLP */
+         (get_later_stmt (last_a, last_b) == last_a) == a_after_b
+         /* Interleaving */
+         && (get_later_stmt (il_a, il_b) == il_a) == a_after_b
+         /* Mixed */
+         && (get_later_stmt (il_a, last_b) == il_a) == a_after_b
+         && (get_later_stmt (last_a, il_b) == last_a) == a_after_b);
 }
 
 /* A subroutine of vect_analyze_data_ref_dependence.  Handle
index 7f3dc17..8771365 100644 (file)
@@ -199,7 +199,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
           : "%r" ((USItype) (ah)),                                     \
             "rICal" ((USItype) (bh)),                                  \
             "%r" ((USItype) (al)),                                     \
-            "rICal" ((USItype) (bl)))
+            "rICal" ((USItype) (bl))                                   \
+          : "cc")
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
   __asm__ ("sub.f      %1, %4, %5\n\tsbc       %0, %2, %3"             \
           : "=r" ((USItype) (sh)),                                     \
@@ -207,7 +208,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
           : "r" ((USItype) (ah)),                                      \
             "rICal" ((USItype) (bh)),                                  \
             "r" ((USItype) (al)),                                      \
-            "rICal" ((USItype) (bl)))
+            "rICal" ((USItype) (bl))                                   \
+          : "cc")
 
 #define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
 #ifdef __ARC_NORM__
index a84084c..72fe2c0 100644 (file)
@@ -755,6 +755,11 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
       if (line_delta < 0
          || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
          || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
+         || ( /* We can't reuse the map if the line offset is sufficiently
+                 large to cause overflow when computing location_t values.  */
+             (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
+             >= (((uint64_t) 1)
+                 << (CHAR_BIT * sizeof (linenum_type) - column_bits)))
          || range_bits < map->m_range_bits)
        map = linemap_check_ordinary
                (const_cast <line_map *>
index 1945494..a2a883f 100644 (file)
@@ -248,7 +248,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __constant_char_array_p(const _CharT* __a, size_t __n)
     {
       size_t __i = 0;
-      while (__builtin_constant_p(__a[__i]) && __i < __n)
+      while (__i < __n && __builtin_constant_p(__a[__i]))
        __i++;
       return __i == __n;
     }