]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Merge with trunk.
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Dec 2013 12:54:49 +0000 (12:54 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Dec 2013 12:54:49 +0000 (12:54 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@205668 138bc75d-0d04-0410-961f-82ee72b054a4

117 files changed:
1  2 
gcc/Makefile.in
gcc/alias.c
gcc/builtins.c
gcc/c-family/c-common.c
gcc/c-family/c-lex.c
gcc/c-family/cilk.c
gcc/c/c-decl.c
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/cfgloop.c
gcc/cgraph.c
gcc/combine.c
gcc/config/aarch64/aarch64.c
gcc/config/arm/arm.c
gcc/config/avr/avr.c
gcc/config/bfin/bfin.c
gcc/config/darwin.c
gcc/config/i386/i386.c
gcc/config/nds32/nds32.c
gcc/config/rs6000/rs6000.c
gcc/config/sparc/sparc.c
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/tree.c
gcc/cp/typeck2.c
gcc/dbxout.c
gcc/doc/rtl.texi
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/dojump.c
gcc/dwarf2out.c
gcc/emit-rtl.c
gcc/expmed.c
gcc/expr.c
gcc/fold-const.c
gcc/fortran/trans-array.c
gcc/fortran/trans-expr.c
gcc/gengtype.c
gcc/genmodes.c
gcc/gimple-fold.c
gcc/gimple-pretty-print.c
gcc/gimple-ssa-strength-reduction.c
gcc/gimple.c
gcc/go/go-gcc.cc
gcc/graphite-clast-to-gimple.c
gcc/graphite-sese-to-poly.c
gcc/hooks.c
gcc/hooks.h
gcc/ipa-devirt.c
gcc/ipa-prop.c
gcc/java/jcf-parse.c
gcc/loop-unroll.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto/lto-lang.c
gcc/lto/lto.c
gcc/objc/objc-act.c
gcc/omp-low.c
gcc/optabs.c
gcc/predict.c
gcc/recog.c
gcc/rtl.h
gcc/stmt.c
gcc/stor-layout.c
gcc/target.def
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h
gcc/tree-affine.c
gcc/tree-call-cdce.c
gcc/tree-cfg.c
gcc/tree-chrec.c
gcc/tree-core.h
gcc/tree-data-ref.c
gcc/tree-dfa.c
gcc/tree-dfa.h
gcc/tree-inline.c
gcc/tree-object-size.c
gcc/tree-predcom.c
gcc/tree-pretty-print.c
gcc/tree-ssa-address.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-ivcanon.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-loop-niter.c
gcc/tree-ssa-math-opts.c
gcc/tree-ssa-phiopt.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-reassoc.c
gcc/tree-ssa-sccvn.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa-uninit.c
gcc/tree-ssa.c
gcc/tree-ssanames.c
gcc/tree-ssanames.h
gcc/tree-streamer-in.c
gcc/tree-streamer-out.c
gcc/tree-switch-conversion.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-generic.c
gcc/tree-vect-loop-manip.c
gcc/tree-vect-loop.c
gcc/tree-vect-patterns.c
gcc/tree-vect-stmts.c
gcc/tree-vrp.c
gcc/tree.c
gcc/tree.def
gcc/tree.h
gcc/value-prof.c
gcc/var-tracking.c
gcc/varasm.c

diff --cc gcc/Makefile.in
Simple merge
diff --cc gcc/alias.c
Simple merge
diff --cc gcc/builtins.c
index ddca5471810eb9aa0c80a2321956a5df6ff4aa80,4f1c8180a5b05d3dec92ac97f7211112c82a8e3b..91a6beab89d166fc2e2d1c7634334158422bcf6c
@@@ -3149,11 -3146,11 +3153,11 @@@ determine_block_size (tree len, rtx len
        }
        else if (range_type == VR_ANTI_RANGE)
        {
-         /* Anti range 0...N lets us to determine minmal size to N+1.  */
+         /* Anti range 0...N lets us to determine minimal size to N+1.  */
 -        if (min.is_zero ())
 +        if (min == 0)
            {
 -            if ((max + double_int_one).fits_uhwi ())
 -              *min_size = (max + double_int_one).to_uhwi ();
 +            if (wi::fits_uhwi_p (max) && max.to_uhwi () + 1 != 0)
 +              *min_size = max.to_uhwi () + 1;
            }
          /* Code like
  
index e5e93894a8498e095f89ad2ea8425ba39932a000,e652802fde180f64b9529611bdadc3341937c9a0..c0fc8bea293a4a32e9c3ef0345c5ac86328a42b8
@@@ -49,9 -48,7 +48,8 @@@ along with GCC; see the file COPYING3
  #include "opts.h"
  #include "cgraph.h"
  #include "target-def.h"
- #include "gimple.h"
  #include "gimplify.h"
 +#include "wide-int-print.h"
  
  cpp_reader *parse_in;         /* Declared in c-pragma.h.  */
  
Simple merge
Simple merge
diff --cc gcc/c/c-decl.c
Simple merge
Simple merge
Simple merge
diff --cc gcc/cfgloop.c
Simple merge
diff --cc gcc/cgraph.c
Simple merge
diff --cc gcc/combine.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/cp/call.c
Simple merge
diff --cc gcc/cp/class.c
index 027d235e83dc0428a3f3807f023037e53f8dc1d3,842b11c66c1183a172cd019a162c2643c053b602..6b2efbf43cbdc2d8adbba79a057c9649e02b4f7a
@@@ -38,11 -39,7 +39,8 @@@ along with GCC; see the file COPYING3
  #include "cgraph.h"
  #include "dumpfile.h"
  #include "splay-tree.h"
- #include "pointer-set.h"
- #include "hash-table.h"
- #include "gimple.h"
  #include "gimplify.h"
 +#include "wide-int.h"
  
  /* The number of nested classes being processed.  If we are not in the
     scope of any class, this is zero.  */
diff --cc gcc/cp/cvt.c
Simple merge
diff --cc gcc/cp/decl.c
Simple merge
diff --cc gcc/cp/init.c
index 7b6f4e28e193b9aa8bfb33cc09d3698b046f819e,1e6e6915bdcb07682f2414f7fc078bdf6ad63e9e..86b690349d24500252212fde995df1c04a487f21
@@@ -30,9 -30,7 +30,8 @@@ along with GCC; see the file COPYING3
  #include "cp-tree.h"
  #include "flags.h"
  #include "target.h"
- #include "gimple.h"
  #include "gimplify.h"
 +#include "wide-int.h"
  
  static bool begin_init_stmts (tree *, tree *);
  static tree finish_init_stmts (bool, tree, tree);
diff --cc gcc/cp/tree.c
index 2e3b58650d44f56392bdbab3158733561790cae0,cb05633b24d7743ff2f2bea1ed87e80cea44c953..c3f57d1a2c2b99d69121ffb95a634d355641c6dc
@@@ -33,10 -33,9 +33,10 @@@ along with GCC; see the file COPYING3
  #include "convert.h"
  #include "cgraph.h"
  #include "splay-tree.h"
- #include "gimple.h"
- #include "gimplify.h"
  #include "hash-table.h"
+ #include "gimple-expr.h"
+ #include "gimplify.h"
 +#include "wide-int.h"
  
  static tree bot_manip (tree *, int *, void *);
  static tree bot_replace (tree *, int *, void *);
Simple merge
diff --cc gcc/dbxout.c
Simple merge
Simple merge
diff --cc gcc/doc/tm.texi
Simple merge
index 55e96bbef4fd302cd465207d7ce3c62393081523,7e459ebd087d37dc0e46eb328058e37d6b160627..3d6a9d03dc1f806727f9f604c4a742761e3d5712
@@@ -8395,50 -8411,6 +8399,52 @@@ and the associated definitions of thos
  
  @hook TARGET_HAS_IFUNC_P
  
+ @hook TARGET_ATOMIC_ALIGN_FOR_MODE
  @hook TARGET_ATOMIC_ASSIGN_EXPAND_FENV
 +
 +@defmac TARGET_SUPPORTS_WIDE_INT
 +
 +On older ports, large integers are stored in @code{CONST_DOUBLE} rtl
 +objects.  Newer ports define @code{TARGET_SUPPORTS_WIDE_INT} to be nonzero
 +to indicate that large integers are stored in
 +@code{CONST_WIDE_INT} rtl objects.  The @code{CONST_WIDE_INT} allows
 +very large integer constants to be represented.  @code{CONST_DOUBLE}
 +is limited to twice the size of the host's @code{HOST_WIDE_INT}
 +representation.
 +
 +Converting a port mostly requires looking for the places where
 +@code{CONST_DOUBLE}s are used with @code{VOIDmode} and replacing that
 +code with code that accesses @code{CONST_WIDE_INT}s.  @samp{"grep -i
 +const_double"} at the port level gets you to 95% of the changes that
 +need to be made.  There are a few places that require a deeper look.
 +
 +@itemize @bullet
 +@item
 +There is no equivalent to @code{hval} and @code{lval} for
 +@code{CONST_WIDE_INT}s.  This would be difficult to express in the md
 +language since there are a variable number of elements.
 +
 +Most ports only check that @code{hval} is either 0 or -1 to see if the
 +value is small.  As mentioned above, this will no longer be necessary
 +since small constants are always @code{CONST_INT}.  Of course there
 +are still a few exceptions, the alpha's constraint used by the zap
 +instruction certainly requires careful examination by C code.
 +However, all the current code does is pass the hval and lval to C
 +code, so evolving the c code to look at the @code{CONST_WIDE_INT} is
 +not really a large change.
 +
 +@item
 +Because there is no standard template that ports use to materialize
 +constants, there is likely to be some futzing that is unique to each
 +port in this code.
 +
 +@item
 +The rtx costs may have to be adjusted to properly account for larger
 +constants that are represented as @code{CONST_WIDE_INT}.
 +@end itemize
 +
 +All and all it does not take long to convert ports that the
 +maintainer is familiar with.
 +
 +@end defmac
diff --cc gcc/dojump.c
Simple merge
diff --cc gcc/dwarf2out.c
Simple merge
diff --cc gcc/emit-rtl.c
Simple merge
diff --cc gcc/expmed.c
Simple merge
diff --cc gcc/expr.c
Simple merge
Simple merge
Simple merge
index bb5cfadd0f714990d7ef76a0f6d05a52ace2084e,62ba93203cd3f0ef7a866e203d7fc7daa09f5064..8d81f2b32161960d6a1f6c5e2a8e9eb0e13b9b71
@@@ -39,9 -39,8 +39,8 @@@ along with GCC; see the file COPYING3
  /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
  #include "trans-stmt.h"
  #include "dependency.h"
- #include "gimple.h"
  #include "gimplify.h"
 -
 +#include "wide-int.h"
  
  /* Convert a scalar to an array descriptor. To be used for assumed-rank
     arrays.  */
diff --cc gcc/gengtype.c
index 0c0195c1606b75a885657c097516577f234f06d7,ca7ce4d968e8f46b83603fa0e8a296f3b28aae56..33684331a93c8d373fb1f2fdf3e678004201c1bc
@@@ -1765,9 -1766,12 +1765,12 @@@ open_base_files (void
      static const char *const ifiles[] = {
        "config.h", "system.h", "coretypes.h", "tm.h",
        "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
 -      "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
 +      "tree.h", "rtl.h", "wide-int.h", "function.h", "insn-config.h", "expr.h",
        "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
        "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
+       "pointer-set.h", "hash-table.h", "vec.h", "ggc.h", "basic-block.h",
+       "tree-ssa-alias.h", "internal-fn.h", "gimple-fold.h", "tree-eh.h",
+       "gimple-expr.h", "is-a.h",
        "gimple.h", "gimple-iterator.h", "gimple-ssa.h", "tree-cfg.h",
        "tree-phinodes.h", "ssa-iterators.h", "stringpool.h", "tree-ssanames.h",
        "tree-ssa-loop.h", "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h",
diff --cc gcc/genmodes.c
Simple merge
Simple merge
Simple merge
index 516756fd75fd71db2f9fdbdd3084d7ddf704f818,8471812b8f157f63181e659ca44008cd903dbda5..6dbb36c1ec0166f640ea7597500526b43f328f44
@@@ -53,12 -59,10 +59,11 @@@ along with GCC; see the file COPYING3
  #include "stringpool.h"
  #include "tree-ssanames.h"
  #include "domwalk.h"
- #include "pointer-set.h"
  #include "expmed.h"
  #include "params.h"
- #include "hash-table.h"
  #include "tree-ssa-address.h"
+ #include "tree-affine.h"
 +#include "wide-int-print.h"
  \f
  /* Information about a strength reduction candidate.  Each statement
     in the candidate table represents an expression of one of the
@@@ -426,6 -430,42 +431,42 @@@ cand_chain_hasher::equal (const value_t
  /* Hash table embodying a mapping from base exprs to chains of candidates.  */
  static hash_table <cand_chain_hasher> base_cand_map;
  \f
 -      aff.offset = tree_to_double_int (integer_zero_node);
+ /* Pointer map used by tree_to_aff_combination_expand.  */
+ static struct pointer_map_t *name_expansions;
+ /* Pointer map embodying a mapping from bases to alternative bases.  */
+ static struct pointer_map_t *alt_base_map;
+ /* Given BASE, use the tree affine combiniation facilities to
+    find the underlying tree expression for BASE, with any
+    immediate offset excluded.  */
+ static tree
+ get_alternative_base (tree base)
+ {
+   tree *result = (tree *) pointer_map_contains (alt_base_map, base);
+   if (result == NULL)
+     {
+       tree expr;
+       aff_tree aff;
+       tree_to_aff_combination_expand (base, TREE_TYPE (base),
+                                     &aff, &name_expansions);
++      aff.offset = 0;
+       expr = aff_combination_to_tree (&aff);
+       result = (tree *) pointer_map_insert (alt_base_map, base);
+       gcc_assert (!*result);
+       if (expr == base)
+       *result = NULL;
+       else
+       *result = expr;
+     }
+   return *result;
+ }
  /* Look in the candidate table for a CAND_PHI that defines BASE and
     return it if found; otherwise return NULL.  */
  
@@@ -560,11 -612,19 +613,19 @@@ record_potential_basis (slsr_cand_t c, 
  }
  
  /* Allocate storage for a new candidate and initialize its fields.
-    Attempt to find a basis for the candidate.  */
+    Attempt to find a basis for the candidate.
+    For CAND_REF, an alternative base may also be recorded and used
+    to find a basis.  This helps cases where the expression hidden
+    behind BASE (which is usually an SSA_NAME) has immediate offset,
+    e.g.
+      a2[i][j] = 1;
+      a2[i + 20][j] = 2;  */
  
  static slsr_cand_t
- alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base, 
+ alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base,
 -                         double_int index, tree stride, tree ctype,
 +                         const widest_int &index, tree stride, tree ctype,
                           unsigned savings)
  {
    slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack,
diff --cc gcc/gimple.c
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/hooks.c
Simple merge
diff --cc gcc/hooks.h
Simple merge
Simple merge
diff --cc gcc/ipa-prop.c
index 39534425c536761ffb7e292c77fa3acb3f0bfcb9,712dab76c50db69aa437745772a5fd7b35d61204..acc01fcfbbb0b5e6dff9fdb700614b51f872b200
@@@ -3757,6 -3766,124 +3765,124 @@@ ipa_modify_call_arguments (struct cgrap
    free_dominance_info (CDI_DOMINATORS);
  }
  
 -      offset += mem_ref_offset (base).low * BITS_PER_UNIT;
+ /* If the expression *EXPR should be replaced by a reduction of a parameter, do
+    so.  ADJUSTMENTS is a pointer to a vector of adjustments.  CONVERT
+    specifies whether the function should care about type incompatibility the
+    current and new expressions.  If it is false, the function will leave
+    incompatibility issues to the caller.  Return true iff the expression
+    was modified. */
+ bool
+ ipa_modify_expr (tree *expr, bool convert,
+                ipa_parm_adjustment_vec adjustments)
+ {
+   struct ipa_parm_adjustment *cand
+     = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
+   if (!cand)
+     return false;
+   tree src;
+   if (cand->by_ref)
+     src = build_simple_mem_ref (cand->new_decl);
+   else
+     src = cand->new_decl;
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     {
+       fprintf (dump_file, "About to replace expr ");
+       print_generic_expr (dump_file, *expr, 0);
+       fprintf (dump_file, " with ");
+       print_generic_expr (dump_file, src, 0);
+       fprintf (dump_file, "\n");
+     }
+   if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
+     {
+       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
+       *expr = vce;
+     }
+   else
+     *expr = src;
+   return true;
+ }
+ /* If T is an SSA_NAME, return NULL if it is not a default def or
+    return its base variable if it is.  If IGNORE_DEFAULT_DEF is true,
+    the base variable is always returned, regardless if it is a default
+    def.  Return T if it is not an SSA_NAME.  */
+ static tree
+ get_ssa_base_param (tree t, bool ignore_default_def)
+ {
+   if (TREE_CODE (t) == SSA_NAME)
+     {
+       if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
+       return SSA_NAME_VAR (t);
+       else
+       return NULL_TREE;
+     }
+   return t;
+ }
+ /* Given an expression, return an adjustment entry specifying the
+    transformation to be done on EXPR.  If no suitable adjustment entry
+    was found, returns NULL.
+    If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
+    default def, otherwise bail on them.
+    If CONVERT is non-NULL, this function will set *CONVERT if the
+    expression provided is a component reference.  ADJUSTMENTS is the
+    adjustments vector.  */
+ ipa_parm_adjustment *
+ ipa_get_adjustment_candidate (tree **expr, bool *convert,
+                             ipa_parm_adjustment_vec adjustments,
+                             bool ignore_default_def)
+ {
+   if (TREE_CODE (**expr) == BIT_FIELD_REF
+       || TREE_CODE (**expr) == IMAGPART_EXPR
+       || TREE_CODE (**expr) == REALPART_EXPR)
+     {
+       *expr = &TREE_OPERAND (**expr, 0);
+       if (convert)
+       *convert = true;
+     }
+   HOST_WIDE_INT offset, size, max_size;
+   tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
+   if (!base || size == -1 || max_size == -1)
+     return NULL;
+   if (TREE_CODE (base) == MEM_REF)
+     {
++      offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
+       base = TREE_OPERAND (base, 0);
+     }
+   base = get_ssa_base_param (base, ignore_default_def);
+   if (!base || TREE_CODE (base) != PARM_DECL)
+     return NULL;
+   struct ipa_parm_adjustment *cand = NULL;
+   unsigned int len = adjustments.length ();
+   for (unsigned i = 0; i < len; i++)
+     {
+       struct ipa_parm_adjustment *adj = &adjustments[i];
+       if (adj->base == base
+         && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
+       {
+         cand = adj;
+         break;
+       }
+     }
+   if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
+     return NULL;
+   return cand;
+ }
  /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once.  */
  
  static bool
Simple merge
Simple merge
index f2a3c0fd869a47dfae55e4127d432b2a38bdcc0e,c5cb23c95d3203fc84b67ebf1947ae11d3aca692..3fbe820d23e937b756dfa9e3b3bc576c5968a6f8
@@@ -714,16 -711,15 +717,21 @@@ input_cfg (struct lto_input_block *ib, 
        loop->any_estimate = streamer_read_hwi (ib);
        if (loop->any_estimate)
        {
 -        loop->nb_iterations_estimate.low = streamer_read_uhwi (ib);
 -        loop->nb_iterations_estimate.high = streamer_read_hwi (ib);
 +        HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
 +        int i;
 +        int prec ATTRIBUTE_UNUSED = streamer_read_uhwi (ib);
 +        int len = streamer_read_uhwi (ib);
 +        for (i = 0; i < len; i++)
 +          a[i] = streamer_read_hwi (ib);
 +
 +        loop->nb_iterations_estimate = widest_int::from_array (a, len);
        }
  
+       /* Read OMP SIMD related info.  */
+       loop->safelen = streamer_read_hwi (ib);
+       loop->force_vect = streamer_read_hwi (ib);
+       loop->simduid = stream_read_tree (ib, data_in);
        place_new_loop (fn, loop);
  
        /* flow_loops_find doesn't like loops not in the tree, hook them
index a06f38639eb4455f6efd4e859280f57b4f6a6b1c,3135f008a22966b1d2ed8fe18e439cc0e9d5f0e2..6b78f4b02a3fcd306c1721ad74e28abf6e32f72b
@@@ -1645,14 -1681,14 +1689,19 @@@ output_cfg (struct output_block *ob, st
        streamer_write_hwi (ob, loop->any_estimate);
        if (loop->any_estimate)
        {
 -        streamer_write_uhwi (ob, loop->nb_iterations_estimate.low);
 -        streamer_write_hwi (ob, loop->nb_iterations_estimate.high);
 +        int len = loop->nb_iterations_estimate.get_len ();
 +        int i;
 +
 +        streamer_write_uhwi (ob, loop->nb_iterations_estimate.get_precision ());
 +        streamer_write_uhwi (ob, len);
 +        for (i = 0; i < len; i++)
 +          streamer_write_hwi (ob, loop->nb_iterations_estimate.elt (i));
        }
+       /* Write OMP SIMD related info.  */
+       streamer_write_hwi (ob, loop->safelen);
+       streamer_write_hwi (ob, loop->force_vect);
+       stream_write_tree (ob, loop->simduid, true);
      }
  
    ob->main_stream = tmp_stream;
Simple merge
diff --cc gcc/lto/lto.c
Simple merge
Simple merge
diff --cc gcc/omp-low.c
Simple merge
diff --cc gcc/optabs.c
Simple merge
diff --cc gcc/predict.c
Simple merge
diff --cc gcc/recog.c
Simple merge
diff --cc gcc/rtl.h
Simple merge
diff --cc gcc/stmt.c
Simple merge
Simple merge
diff --cc gcc/target.def
Simple merge
diff --cc gcc/target.h
Simple merge
diff --cc gcc/targhooks.c
Simple merge
diff --cc gcc/targhooks.h
index aed57788bad9fd9b450d9411e2b44dc0311b7521,c24db1689a2e7def23cd56c3f921db0c1755626a..0d8a30e43c42087271edcb40a6d5cea9e7e1037c
@@@ -206,13 -206,5 +206,6 @@@ extern bool default_member_type_forces_
  extern void default_atomic_assign_expand_fenv (tree *, tree *, tree *);
  extern tree build_va_arg_indirect_ref (tree);
  extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
- extern rtx default_load_bounds_for_arg (rtx, rtx, rtx);
- extern void default_store_bounds_for_arg (rtx, rtx, rtx, rtx);
- extern tree default_fn_abi_va_list_bounds_size (tree);
- extern tree default_chkp_bound_type (void);
- extern enum machine_mode default_chkp_bound_mode (void);
- extern tree default_builtin_chkp_function (unsigned int);
 -extern bool can_use_doloop_if_innermost (double_int, double_int,
 +extern bool can_use_doloop_if_innermost (const widest_int &,
 +                                       const widest_int &,
                                         unsigned int, bool);
Simple merge
Simple merge
diff --cc gcc/tree-cfg.c
Simple merge
Simple merge
diff --cc gcc/tree-core.h
Simple merge
Simple merge
diff --cc gcc/tree-dfa.c
Simple merge
diff --cc gcc/tree-dfa.h
index ab7dd19f09f2deb30794df8cdca74e766a5b5af7,71f2c21965c3ae1c7912201937081c2652e66004..13811a07edfbe376bdbc04776bf257323f8f517c
@@@ -102,11 -102,11 +102,10 @@@ get_addr_base_and_unit_offset_1 (tree e
                && (unit_size = array_ref_element_size (exp),
                    TREE_CODE (unit_size) == INTEGER_CST))
              {
-               HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
-               hindex -= TREE_INT_CST_LOW (low_bound);
-               hindex *= TREE_INT_CST_LOW (unit_size);
-               byte_offset += hindex;
 -              double_int doffset
 -                = (TREE_INT_CST (index) - TREE_INT_CST (low_bound))
 -                  .sext (TYPE_PRECISION (TREE_TYPE (index)));
 -              doffset *= tree_to_double_int (unit_size);
 -              byte_offset += doffset.to_shwi ();
++              offset_int woffset
++                = offset_int::from (wi::sub (index, low_bound), SIGNED);
++              woffset *= wi::to_offset (unit_size);
++              byte_offset += woffset.to_shwi ();
              }
            else
              return NULL_TREE;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index acd7fa15120d42b249d506312c70678ddc8f8030,3d052582bc48fbabbcf25eeb07853355e5ba72fa..473ee9227bc4284ec8a9075993bec7b4bc73c691
@@@ -146,8 -144,6 +153,7 @@@ along with GCC; see the file COPYING3
  #include "diagnostic-core.h"
  #include "dbgcnt.h"
  #include "params.h"
- #include "hash-table.h"
 +#include "wide-int-print.h"
  
  
  /* Possible lattice values.  */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc gcc/tree-ssa.c
Simple merge
Simple merge
Simple merge
Simple merge
index c7dca47a35a0b83859fef4bd2d9e14a373acb1d3,b86092aef4ef11702ed5bbe41ba5f5bdcc2abf65..c1dab1447e02b164f9c524f1bef4970d0e9fb628
@@@ -961,12 -1032,8 +1035,14 @@@ streamer_write_tree_header (struct outp
      streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
    else if (TREE_CODE (expr) == CALL_EXPR)
      streamer_write_uhwi (ob, call_expr_nargs (expr));
+   else if (TREE_CODE (expr) == OMP_CLAUSE)
+     streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
 +  else if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
 +    {
 +      gcc_checking_assert (TREE_INT_CST_NUNITS (expr));
 +      streamer_write_uhwi (ob, TREE_INT_CST_NUNITS (expr));
 +      streamer_write_uhwi (ob, TREE_INT_CST_EXT_NUNITS (expr));
 +    }
  }
  
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 1aede48dc77547eed9df3c708ad1f7e947a8e8b7,ff7b59aa52d34cbd01a1505311f727dd22b4601c..5d0ccb6bcff8a41a5151790929890d3943391011
@@@ -2105,6 -2108,605 +2108,603 @@@ vectorizable_call (gimple stmt, gimple_
  }
  
  
 -                double_int cst
 -                  = double_int::from_shwi
 -                      (bestn->simdclone->args[i].linear_step);
 -                cst *= double_int::from_uhwi (ncopies * nunits);
 -                tree tcst = double_int_to_tree (type, cst);
+ struct simd_call_arg_info
+ {
+   tree vectype;
+   tree op;
+   enum vect_def_type dt;
+   HOST_WIDE_INT linear_step;
+   unsigned int align;
+ };
+ /* Function vectorizable_simd_clone_call.
+    Check if STMT performs a function call that can be vectorized
+    by calling a simd clone of the function.
+    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
+    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+ static bool
+ vectorizable_simd_clone_call (gimple stmt, gimple_stmt_iterator *gsi,
+                             gimple *vec_stmt, slp_tree slp_node)
+ {
+   tree vec_dest;
+   tree scalar_dest;
+   tree op, type;
+   tree vec_oprnd0 = NULL_TREE;
+   stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info;
+   tree vectype;
+   unsigned int nunits;
+   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+   struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
+   tree fndecl, new_temp, def;
+   gimple def_stmt;
+   gimple new_stmt = NULL;
+   int ncopies, j;
+   vec<simd_call_arg_info> arginfo = vNULL;
+   vec<tree> vargs = vNULL;
+   size_t i, nargs;
+   tree lhs, rtype, ratype;
+   vec<constructor_elt, va_gc> *ret_ctor_elts;
+   /* Is STMT a vectorizable call?   */
+   if (!is_gimple_call (stmt))
+     return false;
+   fndecl = gimple_call_fndecl (stmt);
+   if (fndecl == NULL_TREE)
+     return false;
+   struct cgraph_node *node = cgraph_get_node (fndecl);
+   if (node == NULL || node->simd_clones == NULL)
+     return false;
+   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
+     return false;
+   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
+     return false;
+   if (gimple_call_lhs (stmt)
+       && TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
+     return false;
+   gcc_checking_assert (!stmt_can_throw_internal (stmt));
+   vectype = STMT_VINFO_VECTYPE (stmt_info);
+   if (loop_vinfo && nested_in_vect_loop_p (loop, stmt))
+     return false;
+   /* FORNOW */
+   if (slp_node || PURE_SLP_STMT (stmt_info))
+     return false;
+   /* Process function arguments.  */
+   nargs = gimple_call_num_args (stmt);
+   /* Bail out if the function has zero arguments.  */
+   if (nargs == 0)
+     return false;
+   arginfo.create (nargs);
+   for (i = 0; i < nargs; i++)
+     {
+       simd_call_arg_info thisarginfo;
+       affine_iv iv;
+       thisarginfo.linear_step = 0;
+       thisarginfo.align = 0;
+       thisarginfo.op = NULL_TREE;
+       op = gimple_call_arg (stmt, i);
+       if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo,
+                                &def_stmt, &def, &thisarginfo.dt,
+                                &thisarginfo.vectype)
+         || thisarginfo.dt == vect_uninitialized_def)
+       {
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "use not simple.\n");
+         arginfo.release ();
+         return false;
+       }
+       if (thisarginfo.dt == vect_constant_def
+         || thisarginfo.dt == vect_external_def)
+       gcc_assert (thisarginfo.vectype == NULL_TREE);
+       else
+       gcc_assert (thisarginfo.vectype != NULL_TREE);
+       if (thisarginfo.dt != vect_constant_def
+         && thisarginfo.dt != vect_external_def
+         && loop_vinfo
+         && TREE_CODE (op) == SSA_NAME
+         && simple_iv (loop, loop_containing_stmt (stmt), op, &iv, false)
+         && tree_fits_shwi_p (iv.step))
+       {
+         thisarginfo.linear_step = tree_to_shwi (iv.step);
+         thisarginfo.op = iv.base;
+       }
+       else if ((thisarginfo.dt == vect_constant_def
+               || thisarginfo.dt == vect_external_def)
+              && POINTER_TYPE_P (TREE_TYPE (op)))
+       thisarginfo.align = get_pointer_alignment (op) / BITS_PER_UNIT;
+       arginfo.quick_push (thisarginfo);
+     }
+   unsigned int badness = 0;
+   struct cgraph_node *bestn = NULL;
+   if (STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info))
+     bestn = cgraph_get_node (STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info));
+   else
+     for (struct cgraph_node *n = node->simd_clones; n != NULL;
+        n = n->simdclone->next_clone)
+       {
+       unsigned int this_badness = 0;
+       if (n->simdclone->simdlen
+           > (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo)
+           || n->simdclone->nargs != nargs)
+         continue;
+       if (n->simdclone->simdlen
+           < (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo))
+         this_badness += (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo))
+                          - exact_log2 (n->simdclone->simdlen)) * 1024;
+       if (n->simdclone->inbranch)
+         this_badness += 2048;
+       int target_badness = targetm.simd_clone.usable (n);
+       if (target_badness < 0)
+         continue;
+       this_badness += target_badness * 512;
+       /* FORNOW: Have to add code to add the mask argument.  */
+       if (n->simdclone->inbranch)
+         continue;
+       for (i = 0; i < nargs; i++)
+         {
+           switch (n->simdclone->args[i].arg_type)
+             {
+             case SIMD_CLONE_ARG_TYPE_VECTOR:
+               if (!useless_type_conversion_p
+                       (n->simdclone->args[i].orig_type,
+                        TREE_TYPE (gimple_call_arg (stmt, i))))
+                 i = -1;
+               else if (arginfo[i].dt == vect_constant_def
+                        || arginfo[i].dt == vect_external_def
+                        || arginfo[i].linear_step)
+                 this_badness += 64;
+               break;
+             case SIMD_CLONE_ARG_TYPE_UNIFORM:
+               if (arginfo[i].dt != vect_constant_def
+                   && arginfo[i].dt != vect_external_def)
+                 i = -1;
+               break;
+             case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
+               if (arginfo[i].dt == vect_constant_def
+                   || arginfo[i].dt == vect_external_def
+                   || (arginfo[i].linear_step
+                       != n->simdclone->args[i].linear_step))
+                 i = -1;
+               break;
+             case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
+               /* FORNOW */
+               i = -1;
+               break;
+             case SIMD_CLONE_ARG_TYPE_MASK:
+               gcc_unreachable ();
+             }
+           if (i == (size_t) -1)
+             break;
+           if (n->simdclone->args[i].alignment > arginfo[i].align)
+             {
+               i = -1;
+               break;
+             }
+           if (arginfo[i].align)
+             this_badness += (exact_log2 (arginfo[i].align)
+                              - exact_log2 (n->simdclone->args[i].alignment));
+         }
+       if (i == (size_t) -1)
+         continue;
+       if (bestn == NULL || this_badness < badness)
+         {
+           bestn = n;
+           badness = this_badness;
+         }
+       }
+   if (bestn == NULL)
+     {
+       arginfo.release ();
+       return false;
+     }
+   for (i = 0; i < nargs; i++)
+     if ((arginfo[i].dt == vect_constant_def
+        || arginfo[i].dt == vect_external_def)
+       && bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
+       {
+       arginfo[i].vectype
+         = get_vectype_for_scalar_type (TREE_TYPE (gimple_call_arg (stmt,
+                                                                    i)));
+       if (arginfo[i].vectype == NULL
+           || (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
+               > bestn->simdclone->simdlen))
+         {
+           arginfo.release ();
+           return false;
+         }
+       }
+   fndecl = bestn->decl;
+   nunits = bestn->simdclone->simdlen;
+   ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+   /* If the function isn't const, only allow it in simd loops where user
+      has asserted that at least nunits consecutive iterations can be
+      performed using SIMD instructions.  */
+   if ((loop == NULL || (unsigned) loop->safelen < nunits)
+       && gimple_vuse (stmt))
+     {
+       arginfo.release ();
+       return false;
+     }
+   /* Sanity check: make sure that at least one copy of the vectorized stmt
+      needs to be generated.  */
+   gcc_assert (ncopies >= 1);
+   if (!vec_stmt) /* transformation not required.  */
+     {
+       STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info) = bestn->decl;
+       STMT_VINFO_TYPE (stmt_info) = call_simd_clone_vec_info_type;
+       if (dump_enabled_p ())
+       dump_printf_loc (MSG_NOTE, vect_location,
+                        "=== vectorizable_simd_clone_call ===\n");
+ /*      vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); */
+       arginfo.release ();
+       return true;
+     }
+   /** Transform.  **/
+   if (dump_enabled_p ())
+     dump_printf_loc (MSG_NOTE, vect_location, "transform call.\n");
+   /* Handle def.  */
+   scalar_dest = gimple_call_lhs (stmt);
+   vec_dest = NULL_TREE;
+   rtype = NULL_TREE;
+   ratype = NULL_TREE;
+   if (scalar_dest)
+     {
+       vec_dest = vect_create_destination_var (scalar_dest, vectype);
+       rtype = TREE_TYPE (TREE_TYPE (fndecl));
+       if (TREE_CODE (rtype) == ARRAY_TYPE)
+       {
+         ratype = rtype;
+         rtype = TREE_TYPE (ratype);
+       }
+     }
+   prev_stmt_info = NULL;
+   for (j = 0; j < ncopies; ++j)
+     {
+       /* Build argument list for the vectorized call.  */
+       if (j == 0)
+       vargs.create (nargs);
+       else
+       vargs.truncate (0);
+       for (i = 0; i < nargs; i++)
+       {
+         unsigned int k, l, m, o;
+         tree atype;
+         op = gimple_call_arg (stmt, i);
+         switch (bestn->simdclone->args[i].arg_type)
+           {
+           case SIMD_CLONE_ARG_TYPE_VECTOR:
+             atype = bestn->simdclone->args[i].vector_type;
+             o = nunits / TYPE_VECTOR_SUBPARTS (atype);
+             for (m = j * o; m < (j + 1) * o; m++)
+               {
+                 if (TYPE_VECTOR_SUBPARTS (atype)
+                     < TYPE_VECTOR_SUBPARTS (arginfo[i].vectype))
+                   {
+                     unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (atype));
+                     k = (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
+                          / TYPE_VECTOR_SUBPARTS (atype));
+                     gcc_assert ((k & (k - 1)) == 0);
+                     if (m == 0)
+                       vec_oprnd0
+                         = vect_get_vec_def_for_operand (op, stmt, NULL);
+                     else
+                       {
+                         vec_oprnd0 = arginfo[i].op;
+                         if ((m & (k - 1)) == 0)
+                           vec_oprnd0
+                             = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
+                                                               vec_oprnd0);
+                       }
+                     arginfo[i].op = vec_oprnd0;
+                     vec_oprnd0
+                       = build3 (BIT_FIELD_REF, atype, vec_oprnd0,
+                                 size_int (prec),
+                                 bitsize_int ((m & (k - 1)) * prec));
+                     new_stmt
+                       = gimple_build_assign (make_ssa_name (atype, NULL),
+                                              vec_oprnd0);
+                     vect_finish_stmt_generation (stmt, new_stmt, gsi);
+                     vargs.safe_push (gimple_assign_lhs (new_stmt));
+                   }
+                 else
+                   {
+                     k = (TYPE_VECTOR_SUBPARTS (atype)
+                          / TYPE_VECTOR_SUBPARTS (arginfo[i].vectype));
+                     gcc_assert ((k & (k - 1)) == 0);
+                     vec<constructor_elt, va_gc> *ctor_elts;
+                     if (k != 1)
+                       vec_alloc (ctor_elts, k);
+                     else
+                       ctor_elts = NULL;
+                     for (l = 0; l < k; l++)
+                       {
+                         if (m == 0 && l == 0)
+                           vec_oprnd0
+                             = vect_get_vec_def_for_operand (op, stmt, NULL);
+                         else
+                           vec_oprnd0
+                             = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
+                                                               arginfo[i].op);
+                         arginfo[i].op = vec_oprnd0;
+                         if (k == 1)
+                           break;
+                         CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE,
+                                                 vec_oprnd0);
+                       }
+                     if (k == 1)
+                       vargs.safe_push (vec_oprnd0);
+                     else
+                       {
+                         vec_oprnd0 = build_constructor (atype, ctor_elts);
+                         new_stmt
+                           = gimple_build_assign (make_ssa_name (atype, NULL),
+                                                  vec_oprnd0);
+                         vect_finish_stmt_generation (stmt, new_stmt, gsi);
+                         vargs.safe_push (gimple_assign_lhs (new_stmt));
+                       }
+                   }
+               }
+             break;
+           case SIMD_CLONE_ARG_TYPE_UNIFORM:
+             vargs.safe_push (op);
+             break;
+           case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
+             if (j == 0)
+               {
+                 gimple_seq stmts;
+                 arginfo[i].op
+                   = force_gimple_operand (arginfo[i].op, &stmts, true,
+                                           NULL_TREE);
+                 if (stmts != NULL)
+                   {
+                     basic_block new_bb;
+                     edge pe = loop_preheader_edge (loop);
+                     new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
+                     gcc_assert (!new_bb);
+                   }
+                 tree phi_res = copy_ssa_name (op, NULL);
+                 gimple new_phi = create_phi_node (phi_res, loop->header);
+                 set_vinfo_for_stmt (new_phi,
+                                     new_stmt_vec_info (new_phi, loop_vinfo,
+                                                        NULL));
+                 add_phi_arg (new_phi, arginfo[i].op,
+                              loop_preheader_edge (loop), UNKNOWN_LOCATION);
+                 enum tree_code code
+                   = POINTER_TYPE_P (TREE_TYPE (op))
+                     ? POINTER_PLUS_EXPR : PLUS_EXPR;
+                 tree type = POINTER_TYPE_P (TREE_TYPE (op))
+                             ? sizetype : TREE_TYPE (op);
 -                double_int cst
 -                  = double_int::from_shwi
 -                      (bestn->simdclone->args[i].linear_step);
 -                cst *= double_int::from_uhwi (j * nunits);
 -                tree tcst = double_int_to_tree (type, cst);
++                widest_int cst
++                  = wi::mul (bestn->simdclone->args[i].linear_step,
++                             ncopies * nunits);
++                tree tcst = wide_int_to_tree (type, cst);
+                 tree phi_arg = copy_ssa_name (op, NULL);
+                 new_stmt = gimple_build_assign_with_ops (code, phi_arg,
+                                                          phi_res, tcst);
+                 gimple_stmt_iterator si = gsi_after_labels (loop->header);
+                 gsi_insert_after (&si, new_stmt, GSI_NEW_STMT);
+                 set_vinfo_for_stmt (new_stmt,
+                                     new_stmt_vec_info (new_stmt, loop_vinfo,
+                                                        NULL));
+                 add_phi_arg (new_phi, phi_arg, loop_latch_edge (loop),
+                              UNKNOWN_LOCATION);
+                 arginfo[i].op = phi_res;
+                 vargs.safe_push (phi_res);
+               }
+             else
+               {
+                 enum tree_code code
+                   = POINTER_TYPE_P (TREE_TYPE (op))
+                     ? POINTER_PLUS_EXPR : PLUS_EXPR;
+                 tree type = POINTER_TYPE_P (TREE_TYPE (op))
+                             ? sizetype : TREE_TYPE (op);
++                widest_int cst
++                  = wi::mul (bestn->simdclone->args[i].linear_step,
++                             j * nunits);
++                tree tcst = wide_int_to_tree (type, cst);
+                 new_temp = make_ssa_name (TREE_TYPE (op), NULL);
+                 new_stmt
+                   = gimple_build_assign_with_ops (code, new_temp,
+                                                   arginfo[i].op, tcst);
+                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
+                 vargs.safe_push (new_temp);
+               }
+             break;
+           case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
+           default:
+             gcc_unreachable ();
+           }
+       }
+       new_stmt = gimple_build_call_vec (fndecl, vargs);
+       if (vec_dest)
+       {
+         gcc_assert (ratype || TYPE_VECTOR_SUBPARTS (rtype) == nunits);
+         if (ratype)
+           new_temp = create_tmp_var (ratype, NULL);
+         else if (TYPE_VECTOR_SUBPARTS (vectype)
+                  == TYPE_VECTOR_SUBPARTS (rtype))
+           new_temp = make_ssa_name (vec_dest, new_stmt);
+         else
+           new_temp = make_ssa_name (rtype, new_stmt);
+         gimple_call_set_lhs (new_stmt, new_temp);
+       }
+       vect_finish_stmt_generation (stmt, new_stmt, gsi);
+       if (vec_dest)
+       {
+         if (TYPE_VECTOR_SUBPARTS (vectype) < nunits)
+           {
+             unsigned int k, l;
+             unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (vectype));
+             k = nunits / TYPE_VECTOR_SUBPARTS (vectype);
+             gcc_assert ((k & (k - 1)) == 0);
+             for (l = 0; l < k; l++)
+               {
+                 tree t;
+                 if (ratype)
+                   {
+                     t = build_fold_addr_expr (new_temp);
+                     t = build2 (MEM_REF, vectype, t,
+                                 build_int_cst (TREE_TYPE (t),
+                                                l * prec / BITS_PER_UNIT));
+                   }
+                 else
+                   t = build3 (BIT_FIELD_REF, vectype, new_temp,
+                               size_int (prec), bitsize_int (l * prec));
+                 new_stmt
+                   = gimple_build_assign (make_ssa_name (vectype, NULL), t);
+                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
+                 if (j == 0 && l == 0)
+                   STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+                 else
+                   STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+                 prev_stmt_info = vinfo_for_stmt (new_stmt);
+               }
+             if (ratype)
+               {
+                 tree clobber = build_constructor (ratype, NULL);
+                 TREE_THIS_VOLATILE (clobber) = 1;
+                 new_stmt = gimple_build_assign (new_temp, clobber);
+                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
+               }
+             continue;
+           }
+         else if (TYPE_VECTOR_SUBPARTS (vectype) > nunits)
+           {
+             unsigned int k = (TYPE_VECTOR_SUBPARTS (vectype)
+                               / TYPE_VECTOR_SUBPARTS (rtype));
+             gcc_assert ((k & (k - 1)) == 0);
+             if ((j & (k - 1)) == 0)
+               vec_alloc (ret_ctor_elts, k);
+             if (ratype)
+               {
+                 unsigned int m, o = nunits / TYPE_VECTOR_SUBPARTS (rtype);
+                 for (m = 0; m < o; m++)
+                   {
+                     tree tem = build4 (ARRAY_REF, rtype, new_temp,
+                                        size_int (m), NULL_TREE, NULL_TREE);
+                     new_stmt
+                       = gimple_build_assign (make_ssa_name (rtype, NULL),
+                                              tem);
+                     vect_finish_stmt_generation (stmt, new_stmt, gsi);
+                     CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE,
+                                             gimple_assign_lhs (new_stmt));
+                   }
+                 tree clobber = build_constructor (ratype, NULL);
+                 TREE_THIS_VOLATILE (clobber) = 1;
+                 new_stmt = gimple_build_assign (new_temp, clobber);
+                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
+               }
+             else
+               CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE, new_temp);
+             if ((j & (k - 1)) != k - 1)
+               continue;
+             vec_oprnd0 = build_constructor (vectype, ret_ctor_elts);
+             new_stmt
+               = gimple_build_assign (make_ssa_name (vec_dest, NULL),
+                                      vec_oprnd0);
+             vect_finish_stmt_generation (stmt, new_stmt, gsi);
+             if ((unsigned) j == k - 1)
+               STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+             else
+               STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+             prev_stmt_info = vinfo_for_stmt (new_stmt);
+             continue;
+           }
+         else if (ratype)
+           {
+             tree t = build_fold_addr_expr (new_temp);
+             t = build2 (MEM_REF, vectype, t,
+                         build_int_cst (TREE_TYPE (t), 0));
+             new_stmt
+               = gimple_build_assign (make_ssa_name (vec_dest, NULL), t);
+             vect_finish_stmt_generation (stmt, new_stmt, gsi);
+             tree clobber = build_constructor (ratype, NULL);
+             TREE_THIS_VOLATILE (clobber) = 1;
+             vect_finish_stmt_generation (stmt,
+                                          gimple_build_assign (new_temp,
+                                                               clobber), gsi);
+           }
+       }
+       if (j == 0)
+       STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+       else
+       STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+       prev_stmt_info = vinfo_for_stmt (new_stmt);
+     }
+   vargs.release ();
+   /* The call in STMT might prevent it from being removed in dce.
+      We however cannot remove it here, due to the way the ssa name
+      it defines is mapped to the new definition.  So just replace
+      rhs of the statement with something harmless.  */
+   if (slp_node)
+     return true;
+   if (scalar_dest)
+     {
+       type = TREE_TYPE (scalar_dest);
+       if (is_pattern_stmt_p (stmt_info))
+       lhs = gimple_call_lhs (STMT_VINFO_RELATED_STMT (stmt_info));
+       else
+       lhs = gimple_call_lhs (stmt);
+       new_stmt = gimple_build_assign (lhs, build_zero_cst (type));
+     }
+   else
+     new_stmt = gimple_build_nop ();
+   set_vinfo_for_stmt (new_stmt, stmt_info);
+   set_vinfo_for_stmt (stmt, NULL);
+   STMT_VINFO_STMT (stmt_info) = new_stmt;
+   gsi_replace (gsi, new_stmt, false);
+   unlink_stmt_vdef (stmt);
+   return true;
+ }
  /* Function vect_gen_widened_results_half
  
     Create a vector stmt whose code, type, number of arguments, and result
diff --cc gcc/tree-vrp.c
Simple merge
diff --cc gcc/tree.c
index 0196a32c4d11eb106f545eb6f285dbde3b21b00b,0967b432964e31e680fea9f455d594a6b22269be..99128992431faeea1b6aece07f72338b9555e770
@@@ -1197,103 -1147,73 +1200,102 @@@ wide_int_to_tree (tree type, const wide
    int limit = 0;
  
    gcc_assert (type);
 +  unsigned int prec = TYPE_PRECISION (type);
 +  signop sgn = TYPE_SIGN (type);
  
 -  switch (TREE_CODE (type))
 +  /* Verify that everything is canonical.  */
 +  int l = pcst.get_len ();
 +  if (l > 1)
      {
 -    case NULLPTR_TYPE:
 -      gcc_assert (hi == 0 && low == 0);
 -      /* Fallthru.  */
 -
 -    case POINTER_TYPE:
 -    case REFERENCE_TYPE:
 -      /* Cache NULL pointer.  */
 -      if (!hi && !low)
 -      {
 -        limit = 1;
 -        ix = 0;
 -      }
 -      break;
 +      if (pcst.elt (l - 1) == 0)
 +      gcc_checking_assert (pcst.elt (l - 2) < 0);
 +      if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1)
 +      gcc_checking_assert (pcst.elt (l - 2) >= 0);
 +    }
  
 -    case BOOLEAN_TYPE:
 -      /* Cache false or true.  */
 -      limit = 2;
 -      if (!hi && low < 2)
 -      ix = low;
 -      break;
 +  wide_int cst = wide_int::from (pcst, prec, sgn);
 +  unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
  
 -    case INTEGER_TYPE:
 -    case OFFSET_TYPE:
 +  if (ext_len == 1)
 +    {
 +      /* We just need to store a single HOST_WIDE_INT.  */
 +      HOST_WIDE_INT hwi;
        if (TYPE_UNSIGNED (type))
 -      {
 -        /* Cache 0..N */
 -        limit = INTEGER_SHARE_LIMIT;
 -        if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
 -          ix = low;
 -      }
 +      hwi = cst.to_uhwi ();
        else
 +      hwi = cst.to_shwi ();
 +
 +      switch (TREE_CODE (type))
        {
 -        /* Cache -1..N */
 -        limit = INTEGER_SHARE_LIMIT + 1;
 -        if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
 -          ix = low + 1;
 -        else if (hi == -1 && low == -(unsigned HOST_WIDE_INT)1)
 -          ix = 0;
 -      }
 -      break;
 +      case NULLPTR_TYPE:
 +        gcc_assert (hwi == 0);
 +        /* Fallthru.  */
 +
 +      case POINTER_TYPE:
 +      case REFERENCE_TYPE:
-       case POINTER_BOUNDS_TYPE:
-         /* Cache NULL pointer and zero bounds.  */
++        /* Cache NULL pointer.  */
 +        if (hwi == 0)
 +          {
 +            limit = 1;
 +            ix = 0;
 +          }
 +        break;
  
 -    case ENUMERAL_TYPE:
 -      break;
 +      case BOOLEAN_TYPE:
 +        /* Cache false or true.  */
 +        limit = 2;
 +        if (hwi < 2)
 +          ix = hwi;
 +        break;
  
 -    default:
 -      gcc_unreachable ();
 -    }
 +      case INTEGER_TYPE:
 +      case OFFSET_TYPE:
 +        if (TYPE_SIGN (type) == UNSIGNED)
 +          {
 +            /* Cache [0, N).  */
 +            limit = INTEGER_SHARE_LIMIT;
 +            if (IN_RANGE (hwi, 0, INTEGER_SHARE_LIMIT - 1))
 +              ix = hwi;
 +          }
 +        else
 +          {
 +            /* Cache [-1, N).  */
 +            limit = INTEGER_SHARE_LIMIT + 1;
 +            if (IN_RANGE (hwi, -1, INTEGER_SHARE_LIMIT - 1))
 +              ix = hwi + 1;
 +          }
 +        break;
  
 -  if (ix >= 0)
 -    {
 -      /* Look for it in the type's vector of small shared ints.  */
 -      if (!TYPE_CACHED_VALUES_P (type))
 -      {
 -        TYPE_CACHED_VALUES_P (type) = 1;
 -        TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
 +      case ENUMERAL_TYPE:
 +        break;
 +
 +      default:
 +        gcc_unreachable ();
        }
  
 -      t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
 -      if (t)
 +      if (ix >= 0)
        {
 -        /* Make sure no one is clobbering the shared constant.  */
 -        gcc_assert (TREE_TYPE (t) == type);
 -        gcc_assert (TREE_INT_CST_LOW (t) == low);
 -        gcc_assert (TREE_INT_CST_HIGH (t) == hi);
 +        /* Look for it in the type's vector of small shared ints.  */
 +        if (!TYPE_CACHED_VALUES_P (type))
 +          {
 +            TYPE_CACHED_VALUES_P (type) = 1;
 +            TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
 +          }
 +
 +        t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
 +        if (t)
 +          /* Make sure no one is clobbering the shared constant.  */
 +          gcc_checking_assert (TREE_TYPE (t) == type
 +                               && TREE_INT_CST_NUNITS (t) == 1
 +                               && TREE_INT_CST_OFFSET_NUNITS (t) == 1
 +                               && TREE_INT_CST_EXT_NUNITS (t) == 1
 +                               && TREE_INT_CST_ELT (t, 0) == hwi);
 +        else
 +          {
 +            /* Create a new shared int.  */
 +            t = build_new_int_cst (type, cst);
 +            TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
 +          }
        }
        else
        {
diff --cc gcc/tree.def
Simple merge
diff --cc gcc/tree.h
Simple merge
Simple merge
Simple merge
diff --cc gcc/varasm.c
Simple merge