+2012-06-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/51033
+ * c-typeck.c (c_build_vec_perm_expr): Move to c-family/c-common.c.
+ * c-tree.h (c_build_vec_perm_expr): Move to c-family/c-common.h.
+
2012-06-15 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.c (avr_default_expand_builtin): New function.
+2012-06-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/51033
+ * c-common.h (c_build_vec_perm_expr): Move decl here.
+ * c-common.c (c_build_vec_perm_expr): Move definition
+ here.
+
2012-06-06 Steven Bosscher <steven@gcc.gnu.org>
* c.opt (fconserve-space): Turn into a no-op.
{ "__bases", RID_BASES, D_CXXONLY },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
{ "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY },
- { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, D_CONLY },
+ { "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 },
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
return false;
}
+/* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes
+ and have vector types, V0 has the same type as V1, and the number of
+ elements of V0, V1, MASK is the same.
+
+ In case V1 is a NULL_TREE it is assumed that __builtin_shuffle was
+ called with two arguments. In this case implementation passes the
+ first argument twice in order to share the same tree code. This fact
+ could enable the mask-values being twice the vector length. This is
+ an implementation accident and this semantics is not guaranteed to
+ the user. */
+tree
+c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
+{
+ tree ret;
+ bool wrap = true;
+ bool maybe_const = false;
+ bool two_arguments = false;
+
+ if (v1 == NULL_TREE)
+ {
+ two_arguments = true;
+ v1 = v0;
+ }
+
+ if (v0 == error_mark_node || v1 == error_mark_node
+ || mask == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (TREE_TYPE (mask)) != VECTOR_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (mask))) != INTEGER_TYPE)
+ {
+ error_at (loc, "__builtin_shuffle last argument must "
+ "be an integer vector");
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (v0)) != VECTOR_TYPE
+ || TREE_CODE (TREE_TYPE (v1)) != VECTOR_TYPE)
+ {
+ error_at (loc, "__builtin_shuffle arguments must be vectors");
+ return error_mark_node;
+ }
+
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (v0)) != TYPE_MAIN_VARIANT (TREE_TYPE (v1)))
+ {
+ error_at (loc, "__builtin_shuffle argument vectors must be of "
+ "the same type");
+ return error_mark_node;
+ }
+
+ if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (v0))
+ != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask))
+ && TYPE_VECTOR_SUBPARTS (TREE_TYPE (v1))
+ != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)))
+ {
+ error_at (loc, "__builtin_shuffle number of elements of the "
+ "argument vector(s) and the mask vector should "
+ "be the same");
+ return error_mark_node;
+ }
+
+ if (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0))))
+ != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask)))))
+ {
+ error_at (loc, "__builtin_shuffle argument vector(s) inner type "
+ "must have the same size as inner type of the mask");
+ return error_mark_node;
+ }
+
+ if (!c_dialect_cxx ())
+ {
+ /* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */
+ v0 = c_fully_fold (v0, false, &maybe_const);
+ wrap &= maybe_const;
+
+ if (two_arguments)
+ v1 = v0 = save_expr (v0);
+ else
+ {
+ v1 = c_fully_fold (v1, false, &maybe_const);
+ wrap &= maybe_const;
+ }
+
+ mask = c_fully_fold (mask, false, &maybe_const);
+ wrap &= maybe_const;
+ }
+
+ ret = build3_loc (loc, VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask);
+
+ if (!c_dialect_cxx () && !wrap)
+ ret = c_wrap_maybe_const (ret, true);
+
+ return ret;
+}
+
/* Like tree.c:get_narrower, but retain conversion from C++0x scoped enum
to integral type. */
extern bool vector_targets_convertible_p (const_tree t1, const_tree t2);
extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note);
+extern tree c_build_vec_perm_expr (location_t, tree, tree, tree);
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
extern tree c_finish_omp_clauses (tree);
extern tree c_build_va_arg (location_t, tree, tree);
extern tree c_finish_transaction (location_t, tree, int);
-extern tree c_build_vec_perm_expr (location_t, tree, tree, tree);
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
}
return require_complete_type (result);
}
-
-/* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes
- and have vector types, V0 has the same type as V1, and the number of
- elements of V0, V1, MASK is the same.
-
- In case V1 is a NULL_TREE it is assumed that __builtin_shuffle was
- called with two arguments. In this case implementation passes the
- first argument twice in order to share the same tree code. This fact
- could enable the mask-values being twice the vector length. This is
- an implementation accident and this semantics is not guaranteed to
- the user. */
-tree
-c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
-{
- tree ret;
- bool wrap = true;
- bool maybe_const = false;
- bool two_arguments = false;
-
- if (v1 == NULL_TREE)
- {
- two_arguments = true;
- v1 = v0;
- }
-
- if (v0 == error_mark_node || v1 == error_mark_node
- || mask == error_mark_node)
- return error_mark_node;
-
- if (TREE_CODE (TREE_TYPE (mask)) != VECTOR_TYPE
- || TREE_CODE (TREE_TYPE (TREE_TYPE (mask))) != INTEGER_TYPE)
- {
- error_at (loc, "__builtin_shuffle last argument must "
- "be an integer vector");
- return error_mark_node;
- }
-
- if (TREE_CODE (TREE_TYPE (v0)) != VECTOR_TYPE
- || TREE_CODE (TREE_TYPE (v1)) != VECTOR_TYPE)
- {
- error_at (loc, "__builtin_shuffle arguments must be vectors");
- return error_mark_node;
- }
-
- if (TYPE_MAIN_VARIANT (TREE_TYPE (v0)) != TYPE_MAIN_VARIANT (TREE_TYPE (v1)))
- {
- error_at (loc, "__builtin_shuffle argument vectors must be of "
- "the same type");
- return error_mark_node;
- }
-
- if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (v0))
- != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask))
- && TYPE_VECTOR_SUBPARTS (TREE_TYPE (v1))
- != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)))
- {
- error_at (loc, "__builtin_shuffle number of elements of the "
- "argument vector(s) and the mask vector should "
- "be the same");
- return error_mark_node;
- }
-
- if (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0))))
- != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask)))))
- {
- error_at (loc, "__builtin_shuffle argument vector(s) inner type "
- "must have the same size as inner type of the mask");
- return error_mark_node;
- }
-
- /* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */
- v0 = c_fully_fold (v0, false, &maybe_const);
- wrap &= maybe_const;
-
- if (two_arguments)
- v1 = v0 = save_expr (v0);
- else
- {
- v1 = c_fully_fold (v1, false, &maybe_const);
- wrap &= maybe_const;
- }
-
- mask = c_fully_fold (mask, false, &maybe_const);
- wrap &= maybe_const;
-
- ret = build3_loc (loc, VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask);
-
- if (!wrap)
- ret = c_wrap_maybe_const (ret, true);
-
- return ret;
-}
\f
/* Convert the argument expressions in the vector VALUES
to the types in the list TYPELIST.
+2012-06-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/51033
+ * semantics.c (literal_type_p): Handle VECTOR_TYPE.
+ (potential_constant_expression_1): Handle VEC_PERM_EXPR.
+ * parser.c (cp_parser_postfix_expression): Handle RID_BUILTIN_SHUFFLE.
+
2012-06-09 Jason Merrill <jason@redhat.com>
* pt.c (tsubst_expr) [TAG_DEFN]: Instantiate local class.
}
break;
+ case RID_BUILTIN_SHUFFLE:
+ {
+ VEC(tree,gc)* vec;
+ unsigned int i;
+ tree p;
+ location_t loc = token->location;
+
+ cp_lexer_consume_token (parser->lexer);
+ vec = cp_parser_parenthesized_expression_list (parser, non_attr,
+ /*cast_p=*/false, /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ return error_mark_node;
+
+ FOR_EACH_VEC_ELT (tree, vec, i, p)
+ mark_exp_read (p);
+
+ if (VEC_length (tree, vec) == 2)
+ return
+ c_build_vec_perm_expr
+ (loc, VEC_index (tree, vec, 0),
+ NULL_TREE, VEC_index (tree, vec, 1));
+
+ else if (VEC_length (tree, vec) == 3)
+ return
+ c_build_vec_perm_expr
+ (loc, VEC_index (tree, vec, 0),
+ VEC_index (tree, vec, 1),
+ VEC_index (tree, vec, 2));
+ else
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_shuffle%>");
+ return error_mark_node;
+ }
+ break;
+ }
+
default:
{
tree type;
literal_type_p (tree t)
{
if (SCALAR_TYPE_P (t)
+ || TREE_CODE (t) == VECTOR_TYPE
|| TREE_CODE (t) == REFERENCE_TYPE)
return true;
if (CLASS_TYPE_P (t))
return true;
case FMA_EXPR:
+ case VEC_PERM_EXPR:
for (i = 0; i < 3; ++i)
if (!potential_constant_expression_1 (TREE_OPERAND (t, i),
true, flags))
+2012-06-15 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
+
+ PR c++/51033
+ * c-c++-common/torture/vshuf-16.inc: Move from gcc.c-torture/execute/.
+ * c-c++-common/torture/vshuf-2.inc: Likewise.
+ * c-c++-common/torture/vshuf-4.inc: Likewise.
+ * c-c++-common/torture/vshuf-8.inc: Likewise.
+ * c-c++-common/torture/vshuf-main.inc: Likewise.
+ * c-c++-common/torture/vshuf-v16hi.c: Likewise.
+ * c-c++-common/torture/vshuf-v16qi.c: Likewise.
+ * c-c++-common/torture/vshuf-v2df.c: Likewise.
+ * c-c++-common/torture/vshuf-v2di.c: Likewise.
+ * c-c++-common/torture/vshuf-v2sf.c: Likewise.
+ * c-c++-common/torture/vshuf-v2si.c: Likewise.
+ * c-c++-common/torture/vshuf-v4df.c: Likewise.
+ * c-c++-common/torture/vshuf-v4di.c: Likewise.
+ * c-c++-common/torture/vshuf-v4hi.c: Likewise.
+ * c-c++-common/torture/vshuf-v4sf.c: Likewise.
+ * c-c++-common/torture/vshuf-v4si.c: Likewise.
+ * c-c++-common/torture/vshuf-v8hi.c: Likewise.
+ * c-c++-common/torture/vshuf-v8qi.c: Likewise.
+ * c-c++-common/torture/vshuf-v8si.c: Likewise.
+
2012-06-15 Michael Matz <matz@suse.de>
* gcc.dg/tree-ssa/vector-4.c: New test.