Commit 953d0c90 by Richard Sandiford

tree.h (categorize_ctor_elements): Remove comment.

gcc/
	* tree.h (categorize_ctor_elements): Remove comment.  Fix long line.
	(count_type_elements): Delete.
	(complete_ctor_at_level_p): Declare.
	* expr.c (flexible_array_member_p): New function, split out from...
	(count_type_elements): ...here.  Make static.  Replace allow_flexarr
	parameter with for_ctor_p.  When for_ctor_p is true, return the
	number of elements that should appear in the top-level constructor,
	otherwise return an estimate of the number of scalars.
	(categorize_ctor_elements): Replace p_must_clear with p_complete.
	(categorize_ctor_elements_1): Likewise.  Use complete_ctor_at_level_p.
	(complete_ctor_at_level_p): New function, borrowing union logic
	from old categorize_ctor_elements_1.
	(mostly_zeros_p): Return true if the constructor is not complete.
	(all_zeros_p): Update call to categorize_ctor_elements.
	* gimplify.c (gimplify_init_constructor): Update call to
	categorize_ctor_elements.  Don't call count_type_elements.
	Unconditionally prevent clearing for variable-sized types,
	otherwise rely on categorize_ctor_elements to detect
	incomplete initializers.

gcc/cp/
	* typeck2.c (split_nonconstant_init_1): Pass the initializer directly,
	rather than a pointer to it.  Return true if the whole of the value
	was initialized by the generated statements.  Use
	complete_ctor_at_level_p instead of count_type_elements.

gcc/testsuite/
2011-07-12  Chung-Lin Tang  <cltang@codesourcery.com>

	* gcc.target/arm/pr48183.c: New test.

From-SVN: r176228
parent 9111c715
2011-07-13 Richard Sandiford <richard.sandiford@linaro.org>
* tree.h (categorize_ctor_elements): Remove comment. Fix long line.
(count_type_elements): Delete.
(complete_ctor_at_level_p): Declare.
* expr.c (flexible_array_member_p): New function, split out from...
(count_type_elements): ...here. Make static. Replace allow_flexarr
parameter with for_ctor_p. When for_ctor_p is true, return the
number of elements that should appear in the top-level constructor,
otherwise return an estimate of the number of scalars.
(categorize_ctor_elements): Replace p_must_clear with p_complete.
(categorize_ctor_elements_1): Likewise. Use complete_ctor_at_level_p.
(complete_ctor_at_level_p): New function, borrowing union logic
from old categorize_ctor_elements_1.
(mostly_zeros_p): Return true if the constructor is not complete.
(all_zeros_p): Update call to categorize_ctor_elements.
* gimplify.c (gimplify_init_constructor): Update call to
categorize_ctor_elements. Don't call count_type_elements.
Unconditionally prevent clearing for variable-sized types,
otherwise rely on categorize_ctor_elements to detect
incomplete initializers.
2011-07-13 Richard Guenther <rguenther@suse.de>
* tree-vrp.c (simplify_conversion_using_ranges): Make sure
......
2011-07-13 Richard Sandiford <richard.sandiford@linaro.org>
* typeck2.c (split_nonconstant_init_1): Pass the initializer directly,
rather than a pointer to it. Return true if the whole of the value
was initialized by the generated statements. Use
complete_ctor_at_level_p instead of count_type_elements.
2011-07-12 Diego Novillo <dnovillo@google.com>
* name-lookup.h (cp_binding_level): Rename from cxx_scope.
......
......@@ -481,18 +481,20 @@ cxx_incomplete_type_error (const_tree value, const_tree type)
/* The recursive part of split_nonconstant_init. DEST is an lvalue
expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */
expression to which INIT should be assigned. INIT is a CONSTRUCTOR.
Return true if the whole of the value was initialized by the
generated statements. */
static void
split_nonconstant_init_1 (tree dest, tree *initp)
static bool
split_nonconstant_init_1 (tree dest, tree init)
{
unsigned HOST_WIDE_INT idx;
tree init = *initp;
tree field_index, value;
tree type = TREE_TYPE (dest);
tree inner_type = NULL;
bool array_type_p = false;
HOST_WIDE_INT num_type_elements, num_initialized_elements;
bool complete_p = true;
HOST_WIDE_INT num_split_elts = 0;
switch (TREE_CODE (type))
{
......@@ -504,7 +506,6 @@ split_nonconstant_init_1 (tree dest, tree *initp)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
num_initialized_elements = 0;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
field_index, value)
{
......@@ -527,13 +528,14 @@ split_nonconstant_init_1 (tree dest, tree *initp)
sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE);
split_nonconstant_init_1 (sub, &value);
if (!split_nonconstant_init_1 (sub, value))
complete_p = false;
num_split_elts++;
}
else if (!initializer_constant_valid_p (value, inner_type))
{
tree code;
tree sub;
HOST_WIDE_INT inner_elements;
/* FIXME: Ordered removal is O(1) so the whole function is
worst-case quadratic. This could be fixed using an aside
......@@ -557,21 +559,9 @@ split_nonconstant_init_1 (tree dest, tree *initp)
code = build_stmt (input_location, EXPR_STMT, code);
add_stmt (code);
inner_elements = count_type_elements (inner_type, true);
if (inner_elements < 0)
num_initialized_elements = -1;
else if (num_initialized_elements >= 0)
num_initialized_elements += inner_elements;
continue;
num_split_elts++;
}
}
num_type_elements = count_type_elements (type, true);
/* If all elements of the initializer are non-constant and
have been split out, we don't need the empty CONSTRUCTOR. */
if (num_type_elements > 0
&& num_type_elements == num_initialized_elements)
*initp = NULL;
break;
case VECTOR_TYPE:
......@@ -583,6 +573,7 @@ split_nonconstant_init_1 (tree dest, tree *initp)
code = build2 (MODIFY_EXPR, type, dest, cons);
code = build_stmt (input_location, EXPR_STMT, code);
add_stmt (code);
num_split_elts += CONSTRUCTOR_NELTS (init);
}
break;
......@@ -592,6 +583,8 @@ split_nonconstant_init_1 (tree dest, tree *initp)
/* The rest of the initializer is now a constant. */
TREE_CONSTANT (init) = 1;
return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
num_split_elts, inner_type);
}
/* A subroutine of store_init_value. Splits non-constant static
......@@ -607,7 +600,8 @@ split_nonconstant_init (tree dest, tree init)
if (TREE_CODE (init) == CONSTRUCTOR)
{
code = push_stmt_list ();
split_nonconstant_init_1 (dest, &init);
if (split_nonconstant_init_1 (dest, init))
init = NULL_TREE;
code = pop_stmt_list (code);
DECL_INITIAL (dest) = init;
TREE_READONLY (dest) = 0;
......
......@@ -4846,16 +4846,136 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
return NULL_RTX;
}
/* Return true if field F of structure TYPE is a flexible array. */
static bool
flexible_array_member_p (const_tree f, const_tree type)
{
const_tree tf;
tf = TREE_TYPE (f);
return (DECL_CHAIN (f) == NULL
&& TREE_CODE (tf) == ARRAY_TYPE
&& TYPE_DOMAIN (tf)
&& TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
&& integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
&& !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
&& int_size_in_bytes (type) >= 0);
}
/* If FOR_CTOR_P, return the number of top-level elements that a constructor
must have in order for it to completely initialize a value of type TYPE.
Return -1 if the number isn't known.
If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */
static HOST_WIDE_INT
count_type_elements (const_tree type, bool for_ctor_p)
{
switch (TREE_CODE (type))
{
case ARRAY_TYPE:
{
tree nelts;
nelts = array_type_nelts (type);
if (nelts && host_integerp (nelts, 1))
{
unsigned HOST_WIDE_INT n;
n = tree_low_cst (nelts, 1) + 1;
if (n == 0 || for_ctor_p)
return n;
else
return n * count_type_elements (TREE_TYPE (type), false);
}
return for_ctor_p ? -1 : 1;
}
case RECORD_TYPE:
{
unsigned HOST_WIDE_INT n;
tree f;
n = 0;
for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
if (TREE_CODE (f) == FIELD_DECL)
{
if (!for_ctor_p)
n += count_type_elements (TREE_TYPE (f), false);
else if (!flexible_array_member_p (f, type))
/* Don't count flexible arrays, which are not supposed
to be initialized. */
n += 1;
}
return n;
}
case UNION_TYPE:
case QUAL_UNION_TYPE:
{
tree f;
HOST_WIDE_INT n, m;
gcc_assert (!for_ctor_p);
/* Estimate the number of scalars in each field and pick the
maximum. Other estimates would do instead; the idea is simply
to make sure that the estimate is not sensitive to the ordering
of the fields. */
n = 1;
for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
if (TREE_CODE (f) == FIELD_DECL)
{
m = count_type_elements (TREE_TYPE (f), false);
/* If the field doesn't span the whole union, add an extra
scalar for the rest. */
if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
TYPE_SIZE (type)) != 1)
m++;
if (n < m)
n = m;
}
return n;
}
case COMPLEX_TYPE:
return 2;
case VECTOR_TYPE:
return TYPE_VECTOR_SUBPARTS (type);
case INTEGER_TYPE:
case REAL_TYPE:
case FIXED_POINT_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
case POINTER_TYPE:
case OFFSET_TYPE:
case REFERENCE_TYPE:
return 1;
case ERROR_MARK:
return 0;
case VOID_TYPE:
case METHOD_TYPE:
case FUNCTION_TYPE:
case LANG_TYPE:
default:
gcc_unreachable ();
}
}
/* Helper for categorize_ctor_elements. Identical interface. */
static bool
categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
HOST_WIDE_INT *p_elt_count,
bool *p_must_clear)
HOST_WIDE_INT *p_init_elts, bool *p_complete)
{
unsigned HOST_WIDE_INT idx;
HOST_WIDE_INT nz_elts, elt_count;
tree value, purpose;
HOST_WIDE_INT nz_elts, init_elts, num_fields;
tree value, purpose, elt_type;
/* Whether CTOR is a valid constant initializer, in accordance with what
initializer_constant_valid_p does. If inferred from the constructor
......@@ -4864,7 +4984,9 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
nz_elts = 0;
elt_count = 0;
init_elts = 0;
num_fields = 0;
elt_type = NULL_TREE;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
{
......@@ -4879,6 +5001,8 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
mult = (tree_low_cst (hi_index, 1)
- tree_low_cst (lo_index, 1) + 1);
}
num_fields += mult;
elt_type = TREE_TYPE (value);
switch (TREE_CODE (value))
{
......@@ -4886,11 +5010,11 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
{
HOST_WIDE_INT nz = 0, ic = 0;
bool const_elt_p
= categorize_ctor_elements_1 (value, &nz, &ic, p_must_clear);
bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &ic,
p_complete);
nz_elts += mult * nz;
elt_count += mult * ic;
init_elts += mult * ic;
if (const_from_elts_p && const_p)
const_p = const_elt_p;
......@@ -4902,12 +5026,12 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
case FIXED_CST:
if (!initializer_zerop (value))
nz_elts += mult;
elt_count += mult;
init_elts += mult;
break;
case STRING_CST:
nz_elts += mult * TREE_STRING_LENGTH (value);
elt_count += mult * TREE_STRING_LENGTH (value);
init_elts += mult * TREE_STRING_LENGTH (value);
break;
case COMPLEX_CST:
......@@ -4915,7 +5039,7 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
nz_elts += mult;
if (!initializer_zerop (TREE_IMAGPART (value)))
nz_elts += mult;
elt_count += mult;
init_elts += mult;
break;
case VECTOR_CST:
......@@ -4925,65 +5049,31 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
{
if (!initializer_zerop (TREE_VALUE (v)))
nz_elts += mult;
elt_count += mult;
init_elts += mult;
}
}
break;
default:
{
HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true);
if (tc < 1)
tc = 1;
HOST_WIDE_INT tc = count_type_elements (elt_type, false);
nz_elts += mult * tc;
elt_count += mult * tc;
init_elts += mult * tc;
if (const_from_elts_p && const_p)
const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
const_p = initializer_constant_valid_p (value, elt_type)
!= NULL_TREE;
}
break;
}
}
if (!*p_must_clear
&& (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
|| TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE))
{
tree init_sub_type;
bool clear_this = true;
if (!VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (ctor)))
{
/* We don't expect more than one element of the union to be
initialized. Not sure what we should do otherwise... */
gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (ctor))
== 1);
init_sub_type = TREE_TYPE (VEC_index (constructor_elt,
CONSTRUCTOR_ELTS (ctor),
0)->value);
/* ??? We could look at each element of the union, and find the
largest element. Which would avoid comparing the size of the
initialized element against any tail padding in the union.
Doesn't seem worth the effort... */
if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
TYPE_SIZE (init_sub_type)) == 1)
{
/* And now we have to find out if the element itself is fully
constructed. E.g. for union { struct { int a, b; } s; } u
= { .s = { .a = 1 } }. */
if (elt_count == count_type_elements (init_sub_type, false))
clear_this = false;
}
}
*p_must_clear = clear_this;
}
if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor),
num_fields, elt_type))
*p_complete = false;
*p_nz_elts += nz_elts;
*p_elt_count += elt_count;
*p_init_elts += init_elts;
return const_p;
}
......@@ -4993,111 +5083,50 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
and place it in *P_NZ_ELTS;
* how many scalar fields in total are in CTOR,
and place it in *P_ELT_COUNT.
* if a type is a union, and the initializer from the constructor
is not the largest element in the union, then set *p_must_clear.
* whether the constructor is complete -- in the sense that every
meaningful byte is explicitly given a value --
and place it in *P_COMPLETE.
Return whether or not CTOR is a valid static constant initializer, the same
as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
bool
categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
HOST_WIDE_INT *p_elt_count,
bool *p_must_clear)
HOST_WIDE_INT *p_init_elts, bool *p_complete)
{
*p_nz_elts = 0;
*p_elt_count = 0;
*p_must_clear = false;
*p_init_elts = 0;
*p_complete = true;
return
categorize_ctor_elements_1 (ctor, p_nz_elts, p_elt_count, p_must_clear);
return categorize_ctor_elements_1 (ctor, p_nz_elts, p_init_elts, p_complete);
}
/* Count the number of scalars in TYPE. Return -1 on overflow or
variable-sized. If ALLOW_FLEXARR is true, don't count flexible
array member at the end of the structure. */
/* TYPE is initialized by a constructor with NUM_ELTS elements, the last
of which had type LAST_TYPE. Each element was itself a complete
initializer, in the sense that every meaningful byte was explicitly
given a value. Return true if the same is true for the constructor
as a whole. */
HOST_WIDE_INT
count_type_elements (const_tree type, bool allow_flexarr)
bool
complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
const_tree last_type)
{
const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1));
switch (TREE_CODE (type))
if (TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
{
case ARRAY_TYPE:
{
tree telts = array_type_nelts (type);
if (telts && host_integerp (telts, 1))
{
HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1;
HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type), false);
if (n == 0)
return 0;
else if (max / n > m)
return n * m;
}
return -1;
}
case RECORD_TYPE:
{
HOST_WIDE_INT n = 0, t;
tree f;
for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
if (TREE_CODE (f) == FIELD_DECL)
{
t = count_type_elements (TREE_TYPE (f), false);
if (t < 0)
{
/* Check for structures with flexible array member. */
tree tf = TREE_TYPE (f);
if (allow_flexarr
&& DECL_CHAIN (f) == NULL
&& TREE_CODE (tf) == ARRAY_TYPE
&& TYPE_DOMAIN (tf)
&& TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
&& integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
&& !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
&& int_size_in_bytes (type) >= 0)
break;
return -1;
}
n += t;
}
return n;
}
case UNION_TYPE:
case QUAL_UNION_TYPE:
return -1;
case COMPLEX_TYPE:
return 2;
case VECTOR_TYPE:
return TYPE_VECTOR_SUBPARTS (type);
case INTEGER_TYPE:
case REAL_TYPE:
case FIXED_POINT_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
case POINTER_TYPE:
case OFFSET_TYPE:
case REFERENCE_TYPE:
return 1;
if (num_elts == 0)
return false;
case ERROR_MARK:
return 0;
gcc_assert (num_elts == 1 && last_type);
case VOID_TYPE:
case METHOD_TYPE:
case FUNCTION_TYPE:
case LANG_TYPE:
default:
gcc_unreachable ();
/* ??? We could look at each element of the union, and find the
largest element. Which would avoid comparing the size of the
initialized element against any tail padding in the union.
Doesn't seem worth the effort... */
return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
}
return count_type_elements (type, true) == num_elts;
}
/* Return 1 if EXP contains mostly (3/4) zeros. */
......@@ -5106,18 +5135,12 @@ static int
mostly_zeros_p (const_tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
{
HOST_WIDE_INT nz_elts, count, elts;
bool must_clear;
categorize_ctor_elements (exp, &nz_elts, &count, &must_clear);
if (must_clear)
return 1;
HOST_WIDE_INT nz_elts, init_elts;
bool complete_p;
elts = count_type_elements (TREE_TYPE (exp), false);
return nz_elts < elts / 4;
categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p);
return !complete_p || nz_elts < init_elts / 4;
}
return initializer_zerop (exp);
......@@ -5129,13 +5152,12 @@ static int
all_zeros_p (const_tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
{
HOST_WIDE_INT nz_elts, count;
bool must_clear;
HOST_WIDE_INT nz_elts, init_elts;
bool complete_p;
categorize_ctor_elements (exp, &nz_elts, &count, &must_clear);
return nz_elts == 0;
categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p);
return nz_elts == init_elts;
}
return initializer_zerop (exp);
......
......@@ -3731,9 +3731,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case ARRAY_TYPE:
{
struct gimplify_init_ctor_preeval_data preeval_data;
HOST_WIDE_INT num_type_elements, num_ctor_elements;
HOST_WIDE_INT num_nonzero_elements;
bool cleared, valid_const_initializer;
HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
bool cleared, complete_p, valid_const_initializer;
/* Aggregate types must lower constructors to initialization of
individual elements. The exception is that a CONSTRUCTOR node
......@@ -3750,7 +3749,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
can only do so if it known to be a valid constant initializer. */
valid_const_initializer
= categorize_ctor_elements (ctor, &num_nonzero_elements,
&num_ctor_elements, &cleared);
&num_ctor_elements, &complete_p);
/* If a const aggregate variable is being initialized, then it
should never be a lose to promote the variable to be static. */
......@@ -3788,26 +3787,29 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
parts in, then generate code for the non-constant parts. */
/* TODO. There's code in cp/typeck.c to do this. */
num_type_elements = count_type_elements (type, true);
/* If count_type_elements could not determine number of type elements
for a constant-sized object, assume clearing is needed.
Don't do this for variable-sized objects, as store_constructor
will ignore the clearing of variable-sized objects. */
if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
/* store_constructor will ignore the clearing of variable-sized
objects. Initializers for such objects must explicitly set
every field that needs to be set. */
cleared = false;
else if (!complete_p)
/* If the constructor isn't complete, clear the whole object
beforehand.
??? This ought not to be needed. For any element not present
in the initializer, we should simply set them to zero. Except
we'd need to *find* the elements that are not present, and that
requires trickery to avoid quadratic compile-time behavior in
large cases or excessive memory use in small cases. */
cleared = true;
/* If there are "lots" of zeros, then block clear the object first. */
else if (num_type_elements - num_nonzero_elements
else if (num_ctor_elements - num_nonzero_elements
> CLEAR_RATIO (optimize_function_for_speed_p (cfun))
&& num_nonzero_elements < num_type_elements/4)
cleared = true;
/* ??? This bit ought not be needed. For any element not present
in the initializer, we should simply set them to zero. Except
we'd need to *find* the elements that are not present, and that
requires trickery to avoid quadratic compile-time behavior in
large cases or excessive memory use in small cases. */
else if (num_ctor_elements < num_type_elements)
&& num_nonzero_elements < num_ctor_elements / 4)
/* If there are "lots" of zeros, it's more efficient to clear
the memory and then set the nonzero elements. */
cleared = true;
else
cleared = false;
/* If there are "lots" of initialized elements, and all of them
are valid address constants, then the entire initializer can
......
2011-07-13 Chung-Lin Tang <cltang@codesourcery.com>
* gcc.target/arm/pr48183.c: New test.
2011-07-13 Richard Guenther <rguenther@suse.de>
* gcc.dg/torture/20110713-1.c: New testcase.
......
/* testsuite/gcc.target/arm/pr48183.c */
/* { dg-do compile } */
/* { dg-require-effective-target arm_neon_ok } */
/* { dg-options "-O -g" } */
/* { dg-add-options arm_neon } */
#include <arm_neon.h>
void move_16bit_to_32bit (int32_t *dst, const short *src, unsigned n)
{
unsigned i;
int16x4x2_t input;
int32x4x2_t mid;
int32x4x2_t output;
for (i = 0; i < n/2; i += 8) {
input = vld2_s16(src + i);
mid.val[0] = vmovl_s16(input.val[0]);
mid.val[1] = vmovl_s16(input.val[1]);
output.val[0] = vshlq_n_s32(mid.val[0], 8);
output.val[1] = vshlq_n_s32(mid.val[1], 8);
vst2q_s32((int32_t *)dst + i, output);
}
}
......@@ -4804,21 +4804,10 @@ extern bool initializer_zerop (const_tree);
extern VEC(tree,gc) *ctor_to_vec (tree);
/* Examine CTOR to discover:
* how many scalar fields are set to nonzero values,
and place it in *P_NZ_ELTS;
* how many scalar fields in total are in CTOR,
and place it in *P_ELT_COUNT.
* if a type is a union, and the initializer from the constructor
is not the largest element in the union, then set *p_must_clear.
extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, bool *);
Return whether or not CTOR is a valid static constant initializer, the same
as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
bool *);
extern HOST_WIDE_INT count_type_elements (const_tree, bool);
extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment