This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [06/nn] Add VEC_SERIES_{CST,EXPR} and associated optab


On Mon, Nov 6, 2017 at 4:21 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Richard Biener <richard.guenther@gmail.com> writes:
>> On Thu, Oct 26, 2017 at 2:23 PM, Richard Biener
>> <richard.guenther@gmail.com> wrote:
>>> On Mon, Oct 23, 2017 at 1:20 PM, Richard Sandiford
>>> <richard.sandiford@linaro.org> wrote:
>>>> Similarly to the VEC_DUPLICATE_{CST,EXPR}, this patch adds two
>>>> tree code equivalents of the VEC_SERIES rtx code.  VEC_SERIES_EXPR
>>>> is for non-constant inputs and is a normal tcc_binary.  VEC_SERIES_CST
>>>> is a tcc_constant.
>>>>
>>>> Like VEC_DUPLICATE_CST, VEC_SERIES_CST is only used for variable-length
>>>> vectors.  This avoids the need to handle combinations of VECTOR_CST
>>>> and VEC_SERIES_CST.
>>>
>>> Similar to the other patch can you document and verify that VEC_SERIES_CST
>>> is only used on variable length vectors?
>
> OK, done with the below, which also makes build_vec_series create
> a VECTOR_CST for fixed-length vectors.  I also added some selftests.
>
>>> Ok with that change.
>>
>> Btw, did you think of merging VEC_DUPLICATE_CST with VEC_SERIES_CST
>> via setting step == 0?  I think you can do {1, 1, 1, 1... } + {1, 2,3
>> ,4,5 } constant
>> folding but you don't implement that.
>
> That was done via vec_series_equivalent_p.

Constant folding of VEC_DUPLICATE_CST + VEC_SERIES_CST?  Didn't see that.

> The problem with using VEC_SERIES with a step of zero is that we'd
> then have to define VEC_SERIES for floats too (even in strict math
> modes), but probably only for the special case of a zero step.
> I think that'd end up being more complicated overall.
>
>> Propagation can also turn
>> VEC_SERIES_EXPR into VEC_SERIES_CST and VEC_DUPLICATE_EXPR
>> into VEC_DUPLICATE_CST (didn't see the former, don't remember the latter).
>
> VEC_SERIES_EXPR -> VEC_SERIES_CST/VECTOR_CST was done by const_binop.

Ok, must have missed that.  Would be nice to add comments before the
"transform".

> And yeah, VEC_DUPLICATE_EXPR -> VEC_DUPLICATE_CST/VECTOR_CST was done
> by const_unop in the VEC_DUPLICATE patch.
>
> Tested as before.  OK to install?

Ok.

Thanks,
Richard.

> Thanks,
> Richard
>
>
> 2017-11-06  Richard Sandiford  <richard.sandiford@linaro.org>
>             Alan Hayward  <alan.hayward@arm.com>
>             David Sherwood  <david.sherwood@arm.com>
>
> gcc/
>         * doc/generic.texi (VEC_SERIES_CST, VEC_SERIES_EXPR): Document.
>         * doc/md.texi (vec_series@var{m}): Document.
>         * tree.def (VEC_SERIES_CST, VEC_SERIES_EXPR): New tree codes.
>         * tree.h (TREE_OVERFLOW): Add VEC_SERIES_CST to the list of valid
>         codes.
>         (VEC_SERIES_CST_BASE, VEC_SERIES_CST_STEP): New macros.
>         (build_vec_series): Declare.
>         * tree.c (tree_node_structure_for_code, tree_code_size, tree_size)
>         (add_expr, walk_tree_1, drop_tree_overflow): Handle VEC_SERIES_CST.
>         (build_vec_series_cst, build_vec_series): New functions.
>         * cfgexpand.c (expand_debug_expr): Handle the new codes.
>         * tree-pretty-print.c (dump_generic_node): Likewise.
>         * dwarf2out.c (rtl_for_decl_init): Handle VEC_SERIES_CST.
>         * gimple-expr.h (is_gimple_constant): Likewise.
>         * gimplify.c (gimplify_expr): Likewise.
>         * graphite-scop-detection.c (scan_tree_for_params): Likewise.
>         * ipa-icf-gimple.c (func_checker::compare_cst_or_decl): Likewise.
>         (func_checker::compare_operand): Likewise.
>         * ipa-icf.c (sem_item::add_expr, sem_variable::equals): Likewise.
>         * print-tree.c (print_node): Likewise.
>         * tree-ssa-loop.c (for_each_index): Likewise.
>         * tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
>         * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
>         (ao_ref_init_from_vn_reference): Likewise.
>         * varasm.c (const_hash_1, compare_constant): Likewise.
>         * fold-const.c (negate_expr_p, fold_negate_expr_1, operand_equal_p)
>         (fold_checksum_tree): Likewise.
>         (vec_series_equivalent_p): New function.
>         (const_binop): Use it.  Fold VEC_SERIES_EXPRs of constants.
>         (test_vec_series_folding): New function.
>         (fold_const_c_tests): Call it.
>         * expmed.c (make_tree): Handle VEC_SERIES.
>         * gimple-pretty-print.c (dump_binary_rhs): Likewise.
>         * tree-inline.c (estimate_operator_cost): Likewise.
>         * expr.c (const_vector_element): Include VEC_SERIES_CST in comment.
>         (expand_expr_real_2): Handle VEC_SERIES_EXPR.
>         (expand_expr_real_1): Handle VEC_SERIES_CST.
>         * optabs.def (vec_series_optab): New optab.
>         * optabs.h (expand_vec_series_expr): Declare.
>         * optabs.c (expand_vec_series_expr): New function.
>         * optabs-tree.c (optab_for_tree_code): Handle VEC_SERIES_EXPR.
>         * tree-cfg.c (verify_gimple_assign_binary): Handle VEC_SERIES_EXPR.
>         (verify_gimple_assign_single): Handle VEC_SERIES_CST.
>         * tree-vect-generic.c (expand_vector_operations_1): Check that
>         the operands also have vector type.
>
> Index: gcc/doc/generic.texi
> ===================================================================
> --- gcc/doc/generic.texi        2017-11-06 12:20:31.075167123 +0000
> +++ gcc/doc/generic.texi        2017-11-06 12:21:29.321209826 +0000
> @@ -1037,6 +1037,7 @@ As this example indicates, the operands
>  @tindex COMPLEX_CST
>  @tindex VECTOR_CST
>  @tindex VEC_DUPLICATE_CST
> +@tindex VEC_SERIES_CST
>  @tindex STRING_CST
>  @findex TREE_STRING_LENGTH
>  @findex TREE_STRING_POINTER
> @@ -1098,6 +1099,18 @@ instead.  The scalar element value is gi
>  @code{VEC_DUPLICATE_CST_ELT} and has the same restrictions as the
>  element of a @code{VECTOR_CST}.
>
> +@item VEC_SERIES_CST
> +These nodes represent a vector constant in which element @var{i}
> +has the value @samp{@var{base} + @var{i} * @var{step}}, for some
> +constant @var{base} and @var{step}.  The value of @var{base} is
> +given by @code{VEC_SERIES_CST_BASE} and the value of @var{step} is
> +given by @code{VEC_SERIES_CST_STEP}.
> +
> +At present only variable-length vectors use @code{VEC_SERIES_CST};
> +constant-length vectors use @code{VECTOR_CST} instead.  The nodes
> +are also restricted to integral types, in order to avoid specifying
> +the rounding behavior for floating-point types.
> +
>  @item STRING_CST
>  These nodes represent string-constants.  The @code{TREE_STRING_LENGTH}
>  returns the length of the string, as an @code{int}.  The
> @@ -1702,6 +1715,7 @@ a value from @code{enum annot_expr_kind}
>  @node Vectors
>  @subsection Vectors
>  @tindex VEC_DUPLICATE_EXPR
> +@tindex VEC_SERIES_EXPR
>  @tindex VEC_LSHIFT_EXPR
>  @tindex VEC_RSHIFT_EXPR
>  @tindex VEC_WIDEN_MULT_HI_EXPR
> @@ -1721,6 +1735,14 @@ a value from @code{enum annot_expr_kind}
>  This node has a single operand and represents a vector in which every
>  element is equal to that operand.
>
> +@item VEC_SERIES_EXPR
> +This node represents a vector formed from a scalar base and step,
> +given as the first and second operands respectively.  Element @var{i}
> +of the result is equal to @samp{@var{base} + @var{i}*@var{step}}.
> +
> +This node is restricted to integral types, in order to avoid
> +specifying the rounding behavior for floating-point types.
> +
>  @item VEC_LSHIFT_EXPR
>  @itemx VEC_RSHIFT_EXPR
>  These nodes represent whole vector left and right shifts, respectively.
> Index: gcc/doc/md.texi
> ===================================================================
> --- gcc/doc/md.texi     2017-11-06 12:20:31.076995065 +0000
> +++ gcc/doc/md.texi     2017-11-06 12:21:29.322209826 +0000
> @@ -4899,6 +4899,19 @@ vectors go through the @code{mov@var{m}}
>
>  This pattern is not allowed to @code{FAIL}.
>
> +@cindex @code{vec_series@var{m}} instruction pattern
> +@item @samp{vec_series@var{m}}
> +Initialize vector output operand 0 so that element @var{i} is equal to
> +operand 1 plus @var{i} times operand 2.  In other words, create a linear
> +series whose base value is operand 1 and whose step is operand 2.
> +
> +The vector output has mode @var{m} and the scalar inputs have the mode
> +appropriate for one element of @var{m}.  This pattern is not used for
> +floating-point vectors, in order to avoid having to specify the
> +rounding behavior for @var{i} > 1.
> +
> +This pattern is not allowed to @code{FAIL}.
> +
>  @cindex @code{vec_cmp@var{m}@var{n}} instruction pattern
>  @item @samp{vec_cmp@var{m}@var{n}}
>  Output a vector comparison.  Operand 0 of mode @var{n} is the destination for
> Index: gcc/tree.def
> ===================================================================
> --- gcc/tree.def        2017-11-06 12:20:31.098930366 +0000
> +++ gcc/tree.def        2017-11-06 12:21:29.335209826 +0000
> @@ -309,6 +309,12 @@ DEFTREECODE (VECTOR_CST, "vector_cst", t
>     vectors; fixed-length vectors must use VECTOR_CST instead.  */
>  DEFTREECODE (VEC_DUPLICATE_CST, "vec_duplicate_cst", tcc_constant, 0)
>
> +/* Represents a vector constant in which element i is equal to
> +   VEC_SERIES_CST_BASE + i * VEC_SERIES_CST_STEP.  This is only ever
> +   used for variable-length vectors; fixed-length vectors must use
> +   VECTOR_CST instead.  */
> +DEFTREECODE (VEC_SERIES_CST, "vec_series_cst", tcc_constant, 0)
> +
>  /* Contents are TREE_STRING_LENGTH and the actual contents of the string.  */
>  DEFTREECODE (STRING_CST, "string_cst", tcc_constant, 0)
>
> @@ -542,6 +548,16 @@ DEFTREECODE (COND_EXPR, "cond_expr", tcc
>  /* Represents a vector in which every element is equal to operand 0.  */
>  DEFTREECODE (VEC_DUPLICATE_EXPR, "vec_duplicate_expr", tcc_unary, 1)
>
> +/* Vector series created from a start (base) value and a step.
> +
> +   A = VEC_SERIES_EXPR (B, C)
> +
> +   means
> +
> +   for (i = 0; i < N; i++)
> +     A[i] = B + C * i;  */
> +DEFTREECODE (VEC_SERIES_EXPR, "vec_series_expr", tcc_binary, 2)
> +
>  /* Vector conditional expression. It is like COND_EXPR, but with
>     vector operands.
>
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h  2017-11-06 12:20:31.099844337 +0000
> +++ gcc/tree.h  2017-11-06 12:21:29.336209826 +0000
> @@ -709,8 +709,8 @@ #define TREE_SYMBOL_REFERENCED(NODE) \
>  #define TYPE_REF_CAN_ALIAS_ALL(NODE) \
>    (PTR_OR_REF_CHECK (NODE)->base.static_flag)
>
> -/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST or VEC_DUPLICATE_CST,
> -   this means there was an overflow in folding.  */
> +/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST, VEC_DUPLICATE_CST
> +   or VEC_SERES_CST, this means there was an overflow in folding.  */
>
>  #define TREE_OVERFLOW(NODE) (CST_CHECK (NODE)->base.public_flag)
>
> @@ -1013,6 +1013,12 @@ #define VECTOR_CST_ELT(NODE,IDX) (VECTOR
>  #define VEC_DUPLICATE_CST_ELT(NODE) \
>    (VEC_DUPLICATE_CST_CHECK (NODE)->vector.elts[0])
>
> +/* In a VEC_SERIES_CST node.  */
> +#define VEC_SERIES_CST_BASE(NODE) \
> +  (VEC_SERIES_CST_CHECK (NODE)->vector.elts[0])
> +#define VEC_SERIES_CST_STEP(NODE) \
> +  (VEC_SERIES_CST_CHECK (NODE)->vector.elts[1])
> +
>  /* Define fields and accessors for some special-purpose tree nodes.  */
>
>  #define IDENTIFIER_LENGTH(NODE) \
> @@ -4017,6 +4023,7 @@ extern tree make_vector (unsigned CXX_ME
>  extern tree build_vector (tree, vec<tree> CXX_MEM_STAT_INFO);
>  extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *);
>  extern tree build_vector_from_val (tree, tree);
> +extern tree build_vec_series (tree, tree, tree);
>  extern void recompute_constructor_flags (tree);
>  extern void verify_constructor_flags (tree);
>  extern tree build_constructor (tree, vec<constructor_elt, va_gc> *);
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c  2017-11-06 12:20:31.098930366 +0000
> +++ gcc/tree.c  2017-11-06 12:21:29.335209826 +0000
> @@ -465,6 +465,7 @@ tree_node_structure_for_code (enum tree_
>      case COMPLEX_CST:          return TS_COMPLEX;
>      case VECTOR_CST:           return TS_VECTOR;
>      case VEC_DUPLICATE_CST:    return TS_VECTOR;
> +    case VEC_SERIES_CST:       return TS_VECTOR;
>      case STRING_CST:           return TS_STRING;
>        /* tcc_exceptional cases.  */
>      case ERROR_MARK:           return TS_COMMON;
> @@ -831,6 +832,7 @@ tree_code_size (enum tree_code code)
>         case COMPLEX_CST:       return sizeof (tree_complex);
>         case VECTOR_CST:        return sizeof (tree_vector);
>         case VEC_DUPLICATE_CST: return sizeof (tree_vector);
> +       case VEC_SERIES_CST:    return sizeof (tree_vector) + sizeof (tree);
>         case STRING_CST:        gcc_unreachable ();
>         default:
>           gcc_checking_assert (code >= NUM_TREE_CODES);
> @@ -895,6 +897,9 @@ tree_size (const_tree node)
>      case VEC_DUPLICATE_CST:
>        return sizeof (struct tree_vector);
>
> +    case VEC_SERIES_CST:
> +      return sizeof (struct tree_vector) + sizeof (tree);
> +
>      case STRING_CST:
>        return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
>
> @@ -1730,6 +1735,34 @@ build_vec_duplicate_cst (tree type, tree
>    return t;
>  }
>
> +/* Build a new VEC_SERIES_CST with type TYPE, base BASE and step STEP.
> +
> +   Note that this function is only suitable for callers that specifically
> +   need a VEC_SERIES_CST node.  Use build_vec_series to build a general
> +   series vector from a general base and step.  */
> +
> +static tree
> +build_vec_series_cst (tree type, tree base, tree step MEM_STAT_DECL)
> +{
> +  /* Shouldn't be used until we have variable-length vectors.  */
> +  gcc_unreachable ();
> +
> +  int length = sizeof (struct tree_vector) + sizeof (tree);
> +
> +  record_node_allocation_statistics (VEC_SERIES_CST, length);
> +
> +  tree t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
> +
> +  TREE_SET_CODE (t, VEC_SERIES_CST);
> +  TREE_TYPE (t) = type;
> +  t->base.u.nelts = 2;
> +  VEC_SERIES_CST_BASE (t) = base;
> +  VEC_SERIES_CST_STEP (t) = step;
> +  TREE_CONSTANT (t) = 1;
> +
> +  return t;
> +}
> +
>  /* Build a newly constructed VECTOR_CST node of length LEN.  */
>
>  tree
> @@ -1847,6 +1880,33 @@ build_vector_from_val (tree vectype, tre
>      }
>  }
>
> +/* Build a vector series of type TYPE in which element I has the value
> +   BASE + I * STEP.  The result is a constant if BASE and STEP are constant
> +   and a VEC_SERIES_EXPR otherwise.  */
> +
> +tree
> +build_vec_series (tree type, tree base, tree step)
> +{
> +  if (integer_zerop (step))
> +    return build_vector_from_val (type, base);
> +  if (CONSTANT_CLASS_P (base) && CONSTANT_CLASS_P (step))
> +    {
> +      unsigned int nunits = TYPE_VECTOR_SUBPARTS (type);
> +      if (0)
> +       return build_vec_series_cst (type, base, step);
> +
> +      auto_vec<tree, 32> v (nunits);
> +      v.quick_push (base);
> +      for (unsigned int i = 1; i < nunits; ++i)
> +       {
> +         base = const_binop (PLUS_EXPR, TREE_TYPE (base), base, step);
> +         v.quick_push (base);
> +       }
> +      return build_vector (type, v);
> +    }
> +  return build2 (VEC_SERIES_EXPR, type, base, step);
> +}
> +
>  /* Something has messed with the elements of CONSTRUCTOR C after it was built;
>     calculate TREE_CONSTANT and TREE_SIDE_EFFECTS.  */
>
> @@ -7162,6 +7222,10 @@ add_expr (const_tree t, inchash::hash &h
>      case VEC_DUPLICATE_CST:
>        inchash::add_expr (VEC_DUPLICATE_CST_ELT (t), hstate);
>        return;
> +    case VEC_SERIES_CST:
> +      inchash::add_expr (VEC_SERIES_CST_BASE (t), hstate);
> +      inchash::add_expr (VEC_SERIES_CST_STEP (t), hstate);
> +      return;
>      case SSA_NAME:
>        /* We can just compare by pointer.  */
>        hstate.add_hwi (SSA_NAME_VERSION (t));
> @@ -11210,6 +11274,7 @@ #define WALK_SUBTREE_TAIL(NODE)                         \
>      case FIXED_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>      case STRING_CST:
>      case BLOCK:
>      case PLACEHOLDER_EXPR:
> @@ -12502,6 +12567,15 @@ drop_tree_overflow (tree t)
>        if (TREE_OVERFLOW (*elt))
>         *elt = drop_tree_overflow (*elt);
>      }
> +  if (TREE_CODE (t) == VEC_SERIES_CST)
> +    {
> +      tree *elt = &VEC_SERIES_CST_BASE (t);
> +      if (TREE_OVERFLOW (*elt))
> +       *elt = drop_tree_overflow (*elt);
> +      elt = &VEC_SERIES_CST_STEP (t);
> +      if (TREE_OVERFLOW (*elt))
> +       *elt = drop_tree_overflow (*elt);
> +    }
>    return t;
>  }
>
> Index: gcc/cfgexpand.c
> ===================================================================
> --- gcc/cfgexpand.c     2017-11-06 12:20:31.074253152 +0000
> +++ gcc/cfgexpand.c     2017-11-06 12:21:29.321209826 +0000
> @@ -5070,6 +5070,8 @@ expand_debug_expr (tree exp)
>      case VEC_PERM_EXPR:
>      case VEC_DUPLICATE_CST:
>      case VEC_DUPLICATE_EXPR:
> +    case VEC_SERIES_CST:
> +    case VEC_SERIES_EXPR:
>        return NULL;
>
>      /* Misc codes.  */
> Index: gcc/tree-pretty-print.c
> ===================================================================
> --- gcc/tree-pretty-print.c     2017-11-06 12:20:31.093446541 +0000
> +++ gcc/tree-pretty-print.c     2017-11-06 12:21:29.333209826 +0000
> @@ -1808,6 +1808,14 @@ dump_generic_node (pretty_printer *pp, t
>        pp_string (pp, ", ... }");
>        break;
>
> +    case VEC_SERIES_CST:
> +      pp_string (pp, "{ ");
> +      dump_generic_node (pp, VEC_SERIES_CST_BASE (node), spc, flags, false);
> +      pp_string (pp, ", +, ");
> +      dump_generic_node (pp, VEC_SERIES_CST_STEP (node), spc, flags, false);
> +      pp_string (pp, "}");
> +      break;
> +
>      case FUNCTION_TYPE:
>      case METHOD_TYPE:
>        dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
> @@ -3221,6 +3229,7 @@ dump_generic_node (pretty_printer *pp, t
>        pp_string (pp, " > ");
>        break;
>
> +    case VEC_SERIES_EXPR:
>      case VEC_WIDEN_MULT_HI_EXPR:
>      case VEC_WIDEN_MULT_LO_EXPR:
>      case VEC_WIDEN_MULT_EVEN_EXPR:
> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c     2017-11-06 12:20:31.080650948 +0000
> +++ gcc/dwarf2out.c     2017-11-06 12:21:29.325209826 +0000
> @@ -18879,6 +18879,7 @@ rtl_for_decl_init (tree init, tree type)
>           {
>           case VECTOR_CST:
>           case VEC_DUPLICATE_CST:
> +         case VEC_SERIES_CST:
>             break;
>           case CONSTRUCTOR:
>             if (TREE_CONSTANT (init))
> Index: gcc/gimple-expr.h
> ===================================================================
> --- gcc/gimple-expr.h   2017-11-06 12:20:31.087048745 +0000
> +++ gcc/gimple-expr.h   2017-11-06 12:21:29.328209826 +0000
> @@ -135,6 +135,7 @@ is_gimple_constant (const_tree t)
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>      case STRING_CST:
>        return true;
>
> Index: gcc/gimplify.c
> ===================================================================
> --- gcc/gimplify.c      2017-11-06 12:20:31.088876686 +0000
> +++ gcc/gimplify.c      2017-11-06 12:21:29.329209826 +0000
> @@ -11508,6 +11508,7 @@ gimplify_expr (tree *expr_p, gimple_seq
>         case COMPLEX_CST:
>         case VECTOR_CST:
>         case VEC_DUPLICATE_CST:
> +       case VEC_SERIES_CST:
>           /* Drop the overflow flag on constants, we do not want
>              that in the GIMPLE IL.  */
>           if (TREE_OVERFLOW_P (*expr_p))
> Index: gcc/graphite-scop-detection.c
> ===================================================================
> --- gcc/graphite-scop-detection.c       2017-11-06 12:20:31.088876686 +0000
> +++ gcc/graphite-scop-detection.c       2017-11-06 12:21:29.329209826 +0000
> @@ -1213,6 +1213,7 @@ scan_tree_for_params (sese_info_p s, tre
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>        break;
>
>     default:
> Index: gcc/ipa-icf-gimple.c
> ===================================================================
> --- gcc/ipa-icf-gimple.c        2017-11-06 12:20:31.088876686 +0000
> +++ gcc/ipa-icf-gimple.c        2017-11-06 12:21:29.329209826 +0000
> @@ -334,6 +334,7 @@ func_checker::compare_cst_or_decl (tree
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>      case STRING_CST:
>      case REAL_CST:
>        {
> @@ -530,6 +531,7 @@ func_checker::compare_operand (tree t1,
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>      case STRING_CST:
>      case REAL_CST:
>      case FUNCTION_DECL:
> Index: gcc/ipa-icf.c
> ===================================================================
> --- gcc/ipa-icf.c       2017-11-06 12:20:31.089790657 +0000
> +++ gcc/ipa-icf.c       2017-11-06 12:21:29.330209826 +0000
> @@ -1480,6 +1480,7 @@ sem_item::add_expr (const_tree exp, inch
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>        inchash::add_expr (exp, hstate);
>        break;
>      case CONSTRUCTOR:
> @@ -2040,6 +2041,11 @@ sem_variable::equals (tree t1, tree t2)
>      case VEC_DUPLICATE_CST:
>        return sem_variable::equals (VEC_DUPLICATE_CST_ELT (t1),
>                                    VEC_DUPLICATE_CST_ELT (t2));
> +     case VEC_SERIES_CST:
> +       return (sem_variable::equals (VEC_SERIES_CST_BASE (t1),
> +                                    VEC_SERIES_CST_BASE (t2))
> +              && sem_variable::equals (VEC_SERIES_CST_STEP (t1),
> +                                       VEC_SERIES_CST_STEP (t2)));
>      case ARRAY_REF:
>      case ARRAY_RANGE_REF:
>        {
> Index: gcc/print-tree.c
> ===================================================================
> --- gcc/print-tree.c    2017-11-06 12:20:31.090704628 +0000
> +++ gcc/print-tree.c    2017-11-06 12:21:29.331209826 +0000
> @@ -787,6 +787,11 @@ print_node (FILE *file, const char *pref
>           print_node (file, "elt", VEC_DUPLICATE_CST_ELT (node), indent + 4);
>           break;
>
> +       case VEC_SERIES_CST:
> +         print_node (file, "base", VEC_SERIES_CST_BASE (node), indent + 4);
> +         print_node (file, "step", VEC_SERIES_CST_STEP (node), indent + 4);
> +         break;
> +
>         case COMPLEX_CST:
>           print_node (file, "real", TREE_REALPART (node), indent + 4);
>           print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
> Index: gcc/tree-ssa-loop.c
> ===================================================================
> --- gcc/tree-ssa-loop.c 2017-11-06 12:20:31.093446541 +0000
> +++ gcc/tree-ssa-loop.c 2017-11-06 12:21:29.333209826 +0000
> @@ -617,6 +617,7 @@ for_each_index (tree *addr_p, bool (*cbc
>         case RESULT_DECL:
>         case VECTOR_CST:
>         case VEC_DUPLICATE_CST:
> +       case VEC_SERIES_CST:
>         case COMPLEX_CST:
>         case INTEGER_CST:
>         case REAL_CST:
> Index: gcc/tree-ssa-pre.c
> ===================================================================
> --- gcc/tree-ssa-pre.c  2017-11-06 12:20:31.093446541 +0000
> +++ gcc/tree-ssa-pre.c  2017-11-06 12:21:29.333209826 +0000
> @@ -2628,6 +2628,7 @@ create_component_ref_by_pieces_1 (basic_
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>      case REAL_CST:
>      case CONSTRUCTOR:
>      case VAR_DECL:
> Index: gcc/tree-ssa-sccvn.c
> ===================================================================
> --- gcc/tree-ssa-sccvn.c        2017-11-06 12:20:31.094360512 +0000
> +++ gcc/tree-ssa-sccvn.c        2017-11-06 12:21:29.334209826 +0000
> @@ -867,6 +867,7 @@ copy_reference_ops_from_ref (tree ref, v
>         case COMPLEX_CST:
>         case VECTOR_CST:
>         case VEC_DUPLICATE_CST:
> +       case VEC_SERIES_CST:
>         case REAL_CST:
>         case FIXED_CST:
>         case CONSTRUCTOR:
> @@ -1060,6 +1061,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
>         case COMPLEX_CST:
>         case VECTOR_CST:
>         case VEC_DUPLICATE_CST:
> +       case VEC_SERIES_CST:
>         case REAL_CST:
>         case CONSTRUCTOR:
>         case CONST_DECL:
> Index: gcc/varasm.c
> ===================================================================
> --- gcc/varasm.c        2017-11-06 12:20:31.100758308 +0000
> +++ gcc/varasm.c        2017-11-06 12:21:29.337209826 +0000
> @@ -3065,6 +3065,10 @@ const_hash_1 (const tree exp)
>        return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9
>               + const_hash_1 (TREE_OPERAND (exp, 1)));
>
> +    case VEC_SERIES_CST:
> +      return (const_hash_1 (VEC_SERIES_CST_BASE (exp)) * 11
> +             + const_hash_1 (VEC_SERIES_CST_STEP (exp)));
> +
>      CASE_CONVERT:
>        return const_hash_1 (TREE_OPERAND (exp, 0)) * 7 + 2;
>
> @@ -3165,6 +3169,12 @@ compare_constant (const tree t1, const t
>        return compare_constant (VEC_DUPLICATE_CST_ELT (t1),
>                                VEC_DUPLICATE_CST_ELT (t2));
>
> +    case VEC_SERIES_CST:
> +      return (compare_constant (VEC_SERIES_CST_BASE (t1),
> +                               VEC_SERIES_CST_BASE (t2))
> +             && compare_constant (VEC_SERIES_CST_STEP (t1),
> +                                  VEC_SERIES_CST_STEP (t2)));
> +
>      case CONSTRUCTOR:
>        {
>         vec<constructor_elt, va_gc> *v1, *v2;
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c    2017-11-06 12:20:31.087048745 +0000
> +++ gcc/fold-const.c    2017-11-06 12:21:29.328209826 +0000
> @@ -421,6 +421,10 @@ negate_expr_p (tree t)
>      case VEC_DUPLICATE_CST:
>        return negate_expr_p (VEC_DUPLICATE_CST_ELT (t));
>
> +    case VEC_SERIES_CST:
> +      return (negate_expr_p (VEC_SERIES_CST_BASE (t))
> +             && negate_expr_p (VEC_SERIES_CST_STEP (t)));
> +
>      case COMPLEX_EXPR:
>        return negate_expr_p (TREE_OPERAND (t, 0))
>              && negate_expr_p (TREE_OPERAND (t, 1));
> @@ -590,6 +594,17 @@ fold_negate_expr_1 (location_t loc, tree
>         return build_vector_from_val (type, sub);
>        }
>
> +    case VEC_SERIES_CST:
> +      {
> +       tree neg_base = fold_negate_expr (loc, VEC_SERIES_CST_BASE (t));
> +       if (!neg_base)
> +         return NULL_TREE;
> +       tree neg_step = fold_negate_expr (loc, VEC_SERIES_CST_STEP (t));
> +       if (!neg_step)
> +         return NULL_TREE;
> +       return build_vec_series (type, neg_base, neg_step);
> +      }
> +
>      case COMPLEX_EXPR:
>        if (negate_expr_p (t))
>         return fold_build2_loc (loc, COMPLEX_EXPR, type,
> @@ -1131,6 +1146,28 @@ int_const_binop (enum tree_code code, co
>    return int_const_binop_1 (code, arg1, arg2, 1);
>  }
>
> +/* Return true if EXP is a VEC_DUPLICATE_CST or a VEC_SERIES_CST,
> +   and if so express it as a linear series in *BASE_OUT and *STEP_OUT.
> +   The step will be zero for VEC_DUPLICATE_CST.  */
> +
> +static bool
> +vec_series_equivalent_p (const_tree exp, tree *base_out, tree *step_out)
> +{
> +  if (TREE_CODE (exp) == VEC_SERIES_CST)
> +    {
> +      *base_out = VEC_SERIES_CST_BASE (exp);
> +      *step_out = VEC_SERIES_CST_STEP (exp);
> +      return true;
> +    }
> +  if (TREE_CODE (exp) == VEC_DUPLICATE_CST)
> +    {
> +      *base_out = VEC_DUPLICATE_CST_ELT (exp);
> +      *step_out = build_zero_cst (TREE_TYPE (*base_out));
> +      return true;
> +    }
> +  return false;
> +}
> +
>  /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
>     constant.  We assume ARG1 and ARG2 have the same data type, or at least
>     are the same kind of constant and the same machine mode.  Return zero if
> @@ -1457,6 +1494,20 @@ const_binop (enum tree_code code, tree a
>        return build_vector_from_val (TREE_TYPE (arg1), sub);
>      }
>
> +  tree base1, step1, base2, step2;
> +  if ((code == PLUS_EXPR || code == MINUS_EXPR)
> +      && vec_series_equivalent_p (arg1, &base1, &step1)
> +      && vec_series_equivalent_p (arg2, &base2, &step2))
> +    {
> +      tree new_base = const_binop (code, base1, base2);
> +      if (!new_base)
> +       return NULL_TREE;
> +      tree new_step = const_binop (code, step1, step2);
> +      if (!new_step)
> +       return NULL_TREE;
> +      return build_vec_series (TREE_TYPE (arg1), new_base, new_step);
> +    }
> +
>    /* Shifts allow a scalar offset for a vector.  */
>    if (TREE_CODE (arg1) == VECTOR_CST
>        && TREE_CODE (arg2) == INTEGER_CST)
> @@ -1505,6 +1556,12 @@ const_binop (enum tree_code code, tree t
>       result as argument put those cases that need it here.  */
>    switch (code)
>      {
> +    case VEC_SERIES_EXPR:
> +      if (CONSTANT_CLASS_P (arg1)
> +         && CONSTANT_CLASS_P (arg2))
> +       return build_vec_series (type, arg1, arg2);
> +      return NULL_TREE;
> +
>      case COMPLEX_EXPR:
>        if ((TREE_CODE (arg1) == REAL_CST
>            && TREE_CODE (arg2) == REAL_CST)
> @@ -3008,6 +3065,12 @@ operand_equal_p (const_tree arg0, const_
>         return operand_equal_p (VEC_DUPLICATE_CST_ELT (arg0),
>                                 VEC_DUPLICATE_CST_ELT (arg1), flags);
>
> +      case VEC_SERIES_CST:
> +       return (operand_equal_p (VEC_SERIES_CST_BASE (arg0),
> +                                VEC_SERIES_CST_BASE (arg1), flags)
> +               && operand_equal_p (VEC_SERIES_CST_STEP (arg0),
> +                                   VEC_SERIES_CST_STEP (arg1), flags));
> +
>        case COMPLEX_CST:
>         return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
>                                  flags)
> @@ -12020,6 +12083,10 @@ fold_checksum_tree (const_tree expr, str
>         case VEC_DUPLICATE_CST:
>           fold_checksum_tree (VEC_DUPLICATE_CST_ELT (expr), ctx, ht);
>           break;
> +       case VEC_SERIES_CST:
> +         fold_checksum_tree (VEC_SERIES_CST_BASE (expr), ctx, ht);
> +         fold_checksum_tree (VEC_SERIES_CST_STEP (expr), ctx, ht);
> +         break;
>         default:
>           break;
>         }
> @@ -14528,6 +14595,54 @@ test_vec_duplicate_folding ()
>    ASSERT_TRUE (operand_equal_p (dup5_expr, dup5_cst, 0));
>  }
>
> +/* Verify folding of VEC_SERIES_CSTs and VEC_SERIES_EXPRs.  */
> +
> +static void
> +test_vec_series_folding ()
> +{
> +  scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (ssizetype);
> +  machine_mode vec_mode = targetm.vectorize.preferred_simd_mode (int_mode);
> +  unsigned int nunits = GET_MODE_NUNITS (vec_mode);
> +  if (nunits == 1)
> +    nunits = 4;
> +
> +  tree type = build_vector_type (ssizetype, nunits);
> +  tree s5_4 = build_vec_series (type, ssize_int (5), ssize_int (4));
> +  tree s3_9 = build_vec_series (type, ssize_int (3), ssize_int (9));
> +
> +  tree neg_s5_4_a = fold_unary (NEGATE_EXPR, type, s5_4);
> +  tree neg_s5_4_b = build_vec_series (type, ssize_int (-5), ssize_int (-4));
> +  ASSERT_TRUE (operand_equal_p (neg_s5_4_a, neg_s5_4_b, 0));
> +
> +  tree s8_s13_a = fold_binary (PLUS_EXPR, type, s5_4, s3_9);
> +  tree s8_s13_b = build_vec_series (type, ssize_int (8), ssize_int (13));
> +  ASSERT_TRUE (operand_equal_p (s8_s13_a, s8_s13_b, 0));
> +
> +  tree s2_m5_a = fold_binary (MINUS_EXPR, type, s5_4, s3_9);
> +  tree s2_m5_b = build_vec_series (type, ssize_int (2), ssize_int (-5));
> +  ASSERT_TRUE (operand_equal_p (s2_m5_a, s2_m5_b, 0));
> +
> +  tree s11 = build_vector_from_val (type, ssize_int (11));
> +  tree s16_4_a = fold_binary (PLUS_EXPR, type, s5_4, s11);
> +  tree s16_4_b = fold_binary (PLUS_EXPR, type, s11, s5_4);
> +  tree s16_4_c = build_vec_series (type, ssize_int (16), ssize_int (4));
> +  ASSERT_TRUE (operand_equal_p (s16_4_a, s16_4_c, 0));
> +  ASSERT_TRUE (operand_equal_p (s16_4_b, s16_4_c, 0));
> +
> +  tree sm6_4_a = fold_binary (MINUS_EXPR, type, s5_4, s11);
> +  tree sm6_4_b = build_vec_series (type, ssize_int (-6), ssize_int (4));
> +  ASSERT_TRUE (operand_equal_p (sm6_4_a, sm6_4_b, 0));
> +
> +  tree s6_m4_a = fold_binary (MINUS_EXPR, type, s11, s5_4);
> +  tree s6_m4_b = build_vec_series (type, ssize_int (6), ssize_int (-4));
> +  ASSERT_TRUE (operand_equal_p (s6_m4_a, s6_m4_b, 0));
> +
> +  tree s5_4_expr = fold_binary (VEC_SERIES_EXPR, type,
> +                               ssize_int (5), ssize_int (4));
> +  ASSERT_TRUE (operand_equal_p (s5_4_expr, s5_4, 0));
> +  ASSERT_FALSE (operand_equal_p (s5_4_expr, s3_9, 0));
> +}
> +
>  /* Run all of the selftests within this file.  */
>
>  void
> @@ -14536,6 +14651,7 @@ fold_const_c_tests ()
>    test_arithmetic_folding ();
>    test_vector_folding ();
>    test_vec_duplicate_folding ();
> +  test_vec_series_folding ();
>  }
>
>  } // namespace selftest
> Index: gcc/expmed.c
> ===================================================================
> --- gcc/expmed.c        2017-11-06 12:20:31.081564919 +0000
> +++ gcc/expmed.c        2017-11-06 12:21:29.325209826 +0000
> @@ -5252,6 +5252,13 @@ make_tree (tree type, rtx x)
>             tree elt_tree = make_tree (TREE_TYPE (type), XEXP (op, 0));
>             return build_vector_from_val (type, elt_tree);
>           }
> +       if (GET_CODE (op) == VEC_SERIES)
> +         {
> +           tree itype = TREE_TYPE (type);
> +           tree base_tree = make_tree (itype, XEXP (op, 0));
> +           tree step_tree = make_tree (itype, XEXP (op, 1));
> +           return build_vec_series (type, base_tree, step_tree);
> +         }
>         return make_tree (type, op);
>        }
>
> Index: gcc/gimple-pretty-print.c
> ===================================================================
> --- gcc/gimple-pretty-print.c   2017-11-06 12:20:31.087048745 +0000
> +++ gcc/gimple-pretty-print.c   2017-11-06 12:21:29.328209826 +0000
> @@ -431,6 +431,7 @@ dump_binary_rhs (pretty_printer *buffer,
>      case VEC_PACK_FIX_TRUNC_EXPR:
>      case VEC_WIDEN_LSHIFT_HI_EXPR:
>      case VEC_WIDEN_LSHIFT_LO_EXPR:
> +    case VEC_SERIES_EXPR:
>        for (p = get_tree_code_name (code); *p; p++)
>         pp_character (buffer, TOUPPER (*p));
>        pp_string (buffer, " <");
> Index: gcc/tree-inline.c
> ===================================================================
> --- gcc/tree-inline.c   2017-11-06 12:20:31.092532570 +0000
> +++ gcc/tree-inline.c   2017-11-06 12:21:29.332209826 +0000
> @@ -3931,6 +3931,7 @@ estimate_operator_cost (enum tree_code c
>      case VEC_WIDEN_LSHIFT_HI_EXPR:
>      case VEC_WIDEN_LSHIFT_LO_EXPR:
>      case VEC_DUPLICATE_EXPR:
> +    case VEC_SERIES_EXPR:
>
>        return 1;
>
> Index: gcc/expr.c
> ===================================================================
> --- gcc/expr.c  2017-11-06 12:20:31.082478890 +0000
> +++ gcc/expr.c  2017-11-06 12:21:29.326209826 +0000
> @@ -7708,7 +7708,7 @@ expand_operands (tree exp0, tree exp1, r
>
>
>  /* Expand constant vector element ELT, which has mode MODE.  This is used
> -   for members of VECTOR_CST and VEC_DUPLICATE_CST.  */
> +   for members of VECTOR_CST, VEC_DUPLICATE_CST and VEC_SERIES_CST.  */
>
>  static rtx
>  const_vector_element (scalar_mode mode, const_tree elt)
> @@ -9591,6 +9591,10 @@ #define REDUCE_BIT_FIELD(expr)   (reduce_b
>        gcc_assert (target);
>        return target;
>
> +    case VEC_SERIES_EXPR:
> +      expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
> +      return expand_vec_series_expr (mode, op0, op1, target);
> +
>      case BIT_INSERT_EXPR:
>        {
>         unsigned bitpos = tree_to_uhwi (treeop2);
> @@ -10029,6 +10033,13 @@ expand_expr_real_1 (tree exp, rtx target
>                                   VEC_DUPLICATE_CST_ELT (exp));
>        return gen_const_vec_duplicate (mode, op0);
>
> +    case VEC_SERIES_CST:
> +      op0 = const_vector_element (GET_MODE_INNER (mode),
> +                                 VEC_SERIES_CST_BASE (exp));
> +      op1 = const_vector_element (GET_MODE_INNER (mode),
> +                                 VEC_SERIES_CST_STEP (exp));
> +      return gen_const_vec_series (mode, op0, op1);
> +
>      case CONST_DECL:
>        if (modifier == EXPAND_WRITE)
>         {
> Index: gcc/optabs.def
> ===================================================================
> --- gcc/optabs.def      2017-11-06 12:20:31.090704628 +0000
> +++ gcc/optabs.def      2017-11-06 12:21:29.331209826 +0000
> @@ -366,3 +366,4 @@ OPTAB_D (get_thread_pointer_optab, "get_
>  OPTAB_D (set_thread_pointer_optab, "set_thread_pointer$I$a")
>
>  OPTAB_DC (vec_duplicate_optab, "vec_duplicate$a", VEC_DUPLICATE)
> +OPTAB_DC (vec_series_optab, "vec_series$a", VEC_SERIES)
> Index: gcc/optabs.h
> ===================================================================
> --- gcc/optabs.h        2017-11-06 12:20:31.090704628 +0000
> +++ gcc/optabs.h        2017-11-06 12:21:29.331209826 +0000
> @@ -316,6 +316,9 @@ extern rtx expand_vec_cmp_expr (tree, tr
>  /* Generate code for VEC_COND_EXPR.  */
>  extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
>
> +/* Generate code for VEC_SERIES_EXPR.  */
> +extern rtx expand_vec_series_expr (machine_mode, rtx, rtx, rtx);
> +
>  /* Generate code for MULT_HIGHPART_EXPR.  */
>  extern rtx expand_mult_highpart (machine_mode, rtx, rtx, rtx, bool);
>
> Index: gcc/optabs.c
> ===================================================================
> --- gcc/optabs.c        2017-11-06 12:20:31.090704628 +0000
> +++ gcc/optabs.c        2017-11-06 12:21:29.330209826 +0000
> @@ -5703,6 +5703,27 @@ expand_vec_cond_expr (tree vec_cond_type
>    return ops[0].value;
>  }
>
> +/* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
> +   Use TARGET for the result if nonnull and convenient.  */
> +
> +rtx
> +expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
> +{
> +  struct expand_operand ops[3];
> +  enum insn_code icode;
> +  machine_mode emode = GET_MODE_INNER (vmode);
> +
> +  icode = direct_optab_handler (vec_series_optab, vmode);
> +  gcc_assert (icode != CODE_FOR_nothing);
> +
> +  create_output_operand (&ops[0], target, vmode);
> +  create_input_operand (&ops[1], op0, emode);
> +  create_input_operand (&ops[2], op1, emode);
> +
> +  expand_insn (icode, 3, ops);
> +  return ops[0].value;
> +}
> +
>  /* Generate insns for a vector comparison into a mask.  */
>
>  rtx
> Index: gcc/optabs-tree.c
> ===================================================================
> --- gcc/optabs-tree.c   2017-11-06 12:20:31.089790657 +0000
> +++ gcc/optabs-tree.c   2017-11-06 12:21:29.330209826 +0000
> @@ -213,6 +213,9 @@ optab_for_tree_code (enum tree_code code
>      case VEC_DUPLICATE_EXPR:
>        return vec_duplicate_optab;
>
> +    case VEC_SERIES_EXPR:
> +      return vec_series_optab;
> +
>      default:
>        break;
>      }
> Index: gcc/tree-cfg.c
> ===================================================================
> --- gcc/tree-cfg.c      2017-11-06 12:20:31.091618599 +0000
> +++ gcc/tree-cfg.c      2017-11-06 12:21:29.332209826 +0000
> @@ -4114,6 +4114,23 @@ verify_gimple_assign_binary (gassign *st
>        /* Continue with generic binary expression handling.  */
>        break;
>
> +    case VEC_SERIES_EXPR:
> +      if (!useless_type_conversion_p (rhs1_type, rhs2_type))
> +       {
> +         error ("type mismatch in series expression");
> +         debug_generic_expr (rhs1_type);
> +         debug_generic_expr (rhs2_type);
> +         return true;
> +       }
> +      if (TREE_CODE (lhs_type) != VECTOR_TYPE
> +         || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type))
> +       {
> +         error ("vector type expected in series expression");
> +         debug_generic_expr (lhs_type);
> +         return true;
> +       }
> +      return false;
> +
>      default:
>        gcc_unreachable ();
>      }
> @@ -4480,6 +4497,7 @@ verify_gimple_assign_single (gassign *st
>      case COMPLEX_CST:
>      case VECTOR_CST:
>      case VEC_DUPLICATE_CST:
> +    case VEC_SERIES_CST:
>      case STRING_CST:
>        return res;
>
> Index: gcc/tree-vect-generic.c
> ===================================================================
> --- gcc/tree-vect-generic.c     2017-11-06 12:20:31.094360512 +0000
> +++ gcc/tree-vect-generic.c     2017-11-06 12:21:29.334209826 +0000
> @@ -1596,7 +1596,8 @@ expand_vector_operations_1 (gimple_stmt_
>    if (rhs_class == GIMPLE_BINARY_RHS)
>      rhs2 = gimple_assign_rhs2 (stmt);
>
> -  if (TREE_CODE (type) != VECTOR_TYPE)
> +  if (!VECTOR_TYPE_P (type)
> +      || !VECTOR_TYPE_P (TREE_TYPE (rhs1)))
>      return;
>
>    /* If the vector operation is operating on all same vector elements


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]