re PR middle-end/60092 (posix_memalign not recognized to derive alias and alignment info)
PR middle-end/60092 * tree-ssa-ccp.c (surely_varying_stmt_p): Don't return true if TYPE_ATTRIBUTES (gimple_call_fntype ()) contain assume_aligned or alloc_align attributes. (bit_value_assume_aligned): Add ATTR, PTRVAL and ALLOC_ALIGN arguments. Handle also assume_aligned and alloc_align attributes. (evaluate_stmt): Adjust bit_value_assume_aligned caller. Handle calls to functions with assume_aligned or alloc_align attributes. * doc/extend.texi: Document assume_aligned and alloc_align attributes. c-family/ * c-common.c (handle_alloc_size_attribute): Use tree_fits_uhwi_p and tree_to_uhwi. (handle_alloc_align_attribute, handle_assume_aligned_attribute): New functions. (c_common_attribute_table): Add alloc_align and assume_aligned attributes. testsuite/ * gcc.dg/attr-alloc_align-1.c: New test. * gcc.dg/attr-alloc_align-2.c: New test. * gcc.dg/attr-alloc_align-3.c: New test. * gcc.dg/attr-assume_aligned-1.c: New test. * gcc.dg/attr-assume_aligned-2.c: New test. * gcc.dg/attr-assume_aligned-3.c: New test. From-SVN: r207628
This commit is contained in:
parent
451bdd2308
commit
8fcbce729d
@ -1,3 +1,17 @@
|
||||
2014-02-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/60092
|
||||
* tree-ssa-ccp.c (surely_varying_stmt_p): Don't return true
|
||||
if TYPE_ATTRIBUTES (gimple_call_fntype ()) contain
|
||||
assume_aligned or alloc_align attributes.
|
||||
(bit_value_assume_aligned): Add ATTR, PTRVAL and ALLOC_ALIGN
|
||||
arguments. Handle also assume_aligned and alloc_align attributes.
|
||||
(evaluate_stmt): Adjust bit_value_assume_aligned caller.
|
||||
Handle calls to functions with assume_aligned or alloc_align
|
||||
attributes.
|
||||
* doc/extend.texi: Document assume_aligned and alloc_align
|
||||
attributes.
|
||||
|
||||
2014-02-08 Terry Guo <terry.guo@arm.com>
|
||||
|
||||
* doc/invoke.texi: Document ARM -march=armv7e-m.
|
||||
|
@ -1,3 +1,13 @@
|
||||
2014-02-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/60092
|
||||
* c-common.c (handle_alloc_size_attribute): Use tree_fits_uhwi_p
|
||||
and tree_to_uhwi.
|
||||
(handle_alloc_align_attribute, handle_assume_aligned_attribute): New
|
||||
functions.
|
||||
(c_common_attribute_table): Add alloc_align and assume_aligned
|
||||
attributes.
|
||||
|
||||
2014-02-06 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c/60087
|
||||
|
@ -366,6 +366,8 @@ static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
|
||||
static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_target_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree ignore_attribute (tree *, tree, tree, int, bool *);
|
||||
@ -766,6 +768,10 @@ const struct attribute_spec c_common_attribute_table[] =
|
||||
handle_omp_declare_simd_attribute, false },
|
||||
{ "omp declare target", 0, 0, true, false, false,
|
||||
handle_omp_declare_target_attribute, false },
|
||||
{ "alloc_align", 1, 1, false, true, true,
|
||||
handle_alloc_align_attribute, false },
|
||||
{ "assume_aligned", 1, 2, false, true, true,
|
||||
handle_assume_aligned_attribute, false },
|
||||
{ NULL, 0, 0, false, false, false, NULL, false }
|
||||
};
|
||||
|
||||
@ -8043,10 +8049,9 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
||||
&& TREE_CODE (position) != FUNCTION_DECL)
|
||||
position = default_conversion (position);
|
||||
|
||||
if (TREE_CODE (position) != INTEGER_CST
|
||||
|| TREE_INT_CST_HIGH (position)
|
||||
|| TREE_INT_CST_LOW (position) < 1
|
||||
|| TREE_INT_CST_LOW (position) > arg_count )
|
||||
if (!tree_fits_uhwi_p (position)
|
||||
|| !arg_count
|
||||
|| !IN_RANGE (tree_to_uhwi (position), 1, arg_count))
|
||||
{
|
||||
warning (OPT_Wattributes,
|
||||
"alloc_size parameter outside range");
|
||||
@ -8057,6 +8062,55 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "alloc_align" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_alloc_align_attribute (tree *node, tree, tree args, int,
|
||||
bool *no_add_attrs)
|
||||
{
|
||||
unsigned arg_count = type_num_arguments (*node);
|
||||
tree position = TREE_VALUE (args);
|
||||
if (position && TREE_CODE (position) != IDENTIFIER_NODE)
|
||||
position = default_conversion (position);
|
||||
|
||||
if (!tree_fits_uhwi_p (position)
|
||||
|| !arg_count
|
||||
|| !IN_RANGE (tree_to_uhwi (position), 1, arg_count))
|
||||
{
|
||||
warning (OPT_Wattributes,
|
||||
"alloc_align parameter outside range");
|
||||
*no_add_attrs = true;
|
||||
return NULL_TREE;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "assume_aligned" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_assume_aligned_attribute (tree *, tree, tree args, int,
|
||||
bool *no_add_attrs)
|
||||
{
|
||||
for (; args; args = TREE_CHAIN (args))
|
||||
{
|
||||
tree position = TREE_VALUE (args);
|
||||
if (position && TREE_CODE (position) != IDENTIFIER_NODE
|
||||
&& TREE_CODE (position) != FUNCTION_DECL)
|
||||
position = default_conversion (position);
|
||||
|
||||
if (TREE_CODE (position) != INTEGER_CST)
|
||||
{
|
||||
warning (OPT_Wattributes,
|
||||
"assume_aligned parameter not integer constant");
|
||||
*no_add_attrs = true;
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "fn spec" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
|
@ -2154,8 +2154,8 @@ The keyword @code{__attribute__} allows you to specify special
|
||||
attributes when making a declaration. This keyword is followed by an
|
||||
attribute specification inside double parentheses. The following
|
||||
attributes are currently defined for functions on all targets:
|
||||
@code{aligned}, @code{alloc_size}, @code{noreturn},
|
||||
@code{returns_twice}, @code{noinline}, @code{noclone},
|
||||
@code{aligned}, @code{alloc_size}, @code{alloc_align}, @code{assume_aligned},
|
||||
@code{noreturn}, @code{returns_twice}, @code{noinline}, @code{noclone},
|
||||
@code{always_inline}, @code{flatten}, @code{pure}, @code{const},
|
||||
@code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
|
||||
@code{no_instrument_function}, @code{no_split_stack},
|
||||
@ -2249,6 +2249,46 @@ declares that @code{my_calloc} returns memory of the size given by
|
||||
the product of parameter 1 and 2 and that @code{my_realloc} returns memory
|
||||
of the size given by parameter 2.
|
||||
|
||||
@item alloc_align
|
||||
@cindex @code{alloc_align} attribute
|
||||
The @code{alloc_align} attribute is used to tell the compiler that the
|
||||
function return value points to memory, where the returned pointer minimum
|
||||
alignment is given by one of the functions parameters. GCC uses this
|
||||
information to improve pointer alignment analysis.
|
||||
|
||||
The function parameter denoting the allocated alignment is specified by
|
||||
one integer argument, whose number is the argument of the attribute.
|
||||
Argument numbering starts at one.
|
||||
|
||||
For instance,
|
||||
|
||||
@smallexample
|
||||
void* my_memalign(size_t, size_t) __attribute__((alloc_align(1)))
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
declares that @code{my_memalign} returns memory with minimum alignment
|
||||
given by parameter 1.
|
||||
|
||||
@item assume_aligned
|
||||
@cindex @code{assume_aligned} attribute
|
||||
The @code{assume_aligned} attribute is used to tell the compiler that the
|
||||
function return value points to memory, where the returned pointer minimum
|
||||
alignment is given by the first argument.
|
||||
If the attribute has two arguments, the second argument is misalignment offset.
|
||||
|
||||
For instance
|
||||
|
||||
@smallexample
|
||||
void* my_alloc1(size_t) __attribute__((assume_aligned(16)))
|
||||
void* my_alloc2(size_t) __attribute__((assume_aligned(32, 8)))
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
declares that @code{my_alloc1} returns 16-byte aligned pointer and
|
||||
that @code{my_alloc2} returns a pointer whose value modulo 32 is equal
|
||||
to 8.
|
||||
|
||||
@item always_inline
|
||||
@cindex @code{always_inline} function attribute
|
||||
Generally, functions are not inlined unless optimization is specified.
|
||||
|
@ -1,3 +1,13 @@
|
||||
2014-02-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/60092
|
||||
* gcc.dg/attr-alloc_align-1.c: New test.
|
||||
* gcc.dg/attr-alloc_align-2.c: New test.
|
||||
* gcc.dg/attr-alloc_align-3.c: New test.
|
||||
* gcc.dg/attr-assume_aligned-1.c: New test.
|
||||
* gcc.dg/attr-assume_aligned-2.c: New test.
|
||||
* gcc.dg/attr-assume_aligned-3.c: New test.
|
||||
|
||||
2014-02-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/60077
|
||||
|
39
gcc/testsuite/gcc.dg/attr-alloc_align-1.c
Normal file
39
gcc/testsuite/gcc.dg/attr-alloc_align-1.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3" } */
|
||||
|
||||
double *my_alloc1 (int len, int align) __attribute__((__alloc_align__ (2)));
|
||||
double *my_alloc2 (int align, int len) __attribute__((alloc_align (1)));
|
||||
|
||||
void
|
||||
test1 (int len, int align)
|
||||
{
|
||||
int i;
|
||||
double *__restrict o1 = my_alloc1 (len, 32);
|
||||
double *__restrict o2 = my_alloc1 (len, 32);
|
||||
double *__restrict o3 = my_alloc1 (len, 32);
|
||||
double *__restrict i1 = my_alloc1 (len, 32);
|
||||
double *__restrict i2 = my_alloc1 (len, align);
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
o1[i] = i1[i] * i2[i];
|
||||
o2[i] = i1[i] + i2[i];
|
||||
o3[i] = i1[i] - i2[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test2 (int len, int align)
|
||||
{
|
||||
int i;
|
||||
double *__restrict o1 = my_alloc2 (32, len);
|
||||
double *__restrict o2 = my_alloc2 (32, len);
|
||||
double *__restrict o3 = my_alloc2 (32, len);
|
||||
double *__restrict i1 = my_alloc2 (32, len);
|
||||
double *__restrict i2 = my_alloc2 (align, len);
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
o1[i] = i1[i] * i2[i];
|
||||
o2[i] = i1[i] + i2[i];
|
||||
o3[i] = i1[i] - i2[i];
|
||||
}
|
||||
}
|
10
gcc/testsuite/gcc.dg/attr-alloc_align-2.c
Normal file
10
gcc/testsuite/gcc.dg/attr-alloc_align-2.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
int i;
|
||||
void *f1 (int) __attribute__((alloc_align (1)));
|
||||
void *f2 (int, int, int) __attribute__((alloc_align (3)));
|
||||
void *f3 (void) __attribute__((alloc_align)); /* { dg-error "wrong number of arguments specified" } */
|
||||
void *f4 (int, int) __attribute__((alloc_align (1, 2))); /* { dg-error "wrong number of arguments specified" } */
|
||||
void *f5 (void) __attribute__((alloc_align (i))); /* { dg-warning "outside range" } */
|
||||
void *f6 (int) __attribute__((alloc_align (0))); /* { dg-warning "outside range" } */
|
||||
void *f7 (int) __attribute__((alloc_align (2))); /* { dg-warning "outside range" } */
|
56
gcc/testsuite/gcc.dg/attr-alloc_align-3.c
Normal file
56
gcc/testsuite/gcc.dg/attr-alloc_align-3.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
|
||||
char *my_alloc1 (int len, int align) __attribute__((__alloc_align__ (2)));
|
||||
char *my_alloc2 (int align, int len) __attribute__((alloc_align (1)));
|
||||
|
||||
int
|
||||
test1 (int len)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc1 (len, 32);
|
||||
return ((__INTPTR_TYPE__) p) & 31;
|
||||
}
|
||||
|
||||
int
|
||||
test2 (int len)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc2 (32, len);
|
||||
return ((__INTPTR_TYPE__) p) & 31;
|
||||
}
|
||||
|
||||
int
|
||||
test3 (int len)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc1 (len, 16);
|
||||
return ((__INTPTR_TYPE__) p) & 15;
|
||||
}
|
||||
|
||||
int
|
||||
test4 (int len)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc2 (16, len);
|
||||
return ((__INTPTR_TYPE__) p) & 15;
|
||||
}
|
||||
|
||||
int
|
||||
test5 (int len, int align)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc1 (len, align);
|
||||
return ((__INTPTR_TYPE__) p) & 15;
|
||||
}
|
||||
|
||||
int
|
||||
test6 (int len, int align)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc2 (align, len);
|
||||
return ((__INTPTR_TYPE__) p) & 15;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "return 0" 4 "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
39
gcc/testsuite/gcc.dg/attr-assume_aligned-1.c
Normal file
39
gcc/testsuite/gcc.dg/attr-assume_aligned-1.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3" } */
|
||||
|
||||
double *my_alloc1 (int len) __attribute__((__assume_aligned__ (16)));
|
||||
double *my_alloc2 (int len) __attribute__((__assume_aligned__ (32, 16)));
|
||||
|
||||
void
|
||||
test1 (int len)
|
||||
{
|
||||
int i;
|
||||
double *__restrict o1 = my_alloc1 (len);
|
||||
double *__restrict o2 = my_alloc1 (len);
|
||||
double *__restrict o3 = my_alloc1 (len);
|
||||
double *__restrict i1 = my_alloc1 (len);
|
||||
double *__restrict i2 = my_alloc1 (len);
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
o1[i] = i1[i] * i2[i];
|
||||
o2[i] = i1[i] + i2[i];
|
||||
o3[i] = i1[i] - i2[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test2 (int len)
|
||||
{
|
||||
int i;
|
||||
double *__restrict o1 = my_alloc2 (len);
|
||||
double *__restrict o2 = my_alloc2 (len);
|
||||
double *__restrict o3 = my_alloc2 (len);
|
||||
double *__restrict i1 = my_alloc2 (len);
|
||||
double *__restrict i2 = my_alloc2 (len);
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
o1[i] = i1[i] * i2[i];
|
||||
o2[i] = i1[i] + i2[i];
|
||||
o3[i] = i1[i] - i2[i];
|
||||
}
|
||||
}
|
8
gcc/testsuite/gcc.dg/attr-assume_aligned-2.c
Normal file
8
gcc/testsuite/gcc.dg/attr-assume_aligned-2.c
Normal file
@ -0,0 +1,8 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
int i;
|
||||
void *f1 (void) __attribute__((assume_aligned (32)));
|
||||
void *f2 (void) __attribute__((assume_aligned (16, 4)));
|
||||
void *f3 (void) __attribute__((assume_aligned)); /* { dg-error "wrong number of arguments specified" } */
|
||||
void *f4 (void) __attribute__((assume_aligned (32, 16, 8))); /* { dg-error "wrong number of arguments specified" } */
|
||||
void *f5 (void) __attribute__((assume_aligned (i))); /* { dg-warning "integer constant" } */
|
24
gcc/testsuite/gcc.dg/attr-assume_aligned-3.c
Normal file
24
gcc/testsuite/gcc.dg/attr-assume_aligned-3.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
|
||||
char *my_alloc1 (int len) __attribute__((__assume_aligned__ (32)));
|
||||
char *my_alloc2 (int len) __attribute__((assume_aligned (32, 4)));
|
||||
|
||||
int
|
||||
test1 (int len)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc1 (len);
|
||||
return ((__INTPTR_TYPE__) p) & 31;
|
||||
}
|
||||
|
||||
int
|
||||
test2 (int len)
|
||||
{
|
||||
int i;
|
||||
char *p = my_alloc2 (len);
|
||||
return (((__INTPTR_TYPE__) p) & 31) != 4;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "return 0" 2 "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
@ -738,13 +738,18 @@ surely_varying_stmt_p (gimple stmt)
|
||||
return true;
|
||||
|
||||
/* If it is a call and does not return a value or is not a
|
||||
builtin and not an indirect call, it is varying. */
|
||||
builtin and not an indirect call or a call to function with
|
||||
assume_aligned/alloc_align attribute, it is varying. */
|
||||
if (is_gimple_call (stmt))
|
||||
{
|
||||
tree fndecl;
|
||||
tree fndecl, fntype = gimple_call_fntype (stmt);
|
||||
if (!gimple_call_lhs (stmt)
|
||||
|| ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
|
||||
&& !DECL_BUILT_IN (fndecl)))
|
||||
&& !DECL_BUILT_IN (fndecl)
|
||||
&& !lookup_attribute ("assume_aligned",
|
||||
TYPE_ATTRIBUTES (fntype))
|
||||
&& !lookup_attribute ("alloc_align",
|
||||
TYPE_ATTRIBUTES (fntype))))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1476,40 +1481,86 @@ bit_value_binop (enum tree_code code, tree type, tree rhs1, tree rhs2)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Return the propagation value when applying __builtin_assume_aligned to
|
||||
its arguments. */
|
||||
/* Return the propagation value for __builtin_assume_aligned
|
||||
and functions with assume_aligned or alloc_aligned attribute.
|
||||
For __builtin_assume_aligned, ATTR is NULL_TREE,
|
||||
for assume_aligned attribute ATTR is non-NULL and ALLOC_ALIGNED
|
||||
is false, for alloc_aligned attribute ATTR is non-NULL and
|
||||
ALLOC_ALIGNED is true. */
|
||||
|
||||
static prop_value_t
|
||||
bit_value_assume_aligned (gimple stmt)
|
||||
bit_value_assume_aligned (gimple stmt, tree attr, prop_value_t ptrval,
|
||||
bool alloc_aligned)
|
||||
{
|
||||
tree ptr = gimple_call_arg (stmt, 0), align, misalign = NULL_TREE;
|
||||
tree type = TREE_TYPE (ptr);
|
||||
tree align, misalign = NULL_TREE, type;
|
||||
unsigned HOST_WIDE_INT aligni, misaligni = 0;
|
||||
prop_value_t ptrval = get_value_for_expr (ptr, true);
|
||||
prop_value_t alignval;
|
||||
double_int value, mask;
|
||||
prop_value_t val;
|
||||
|
||||
if (attr == NULL_TREE)
|
||||
{
|
||||
tree ptr = gimple_call_arg (stmt, 0);
|
||||
type = TREE_TYPE (ptr);
|
||||
ptrval = get_value_for_expr (ptr, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree lhs = gimple_call_lhs (stmt);
|
||||
type = TREE_TYPE (lhs);
|
||||
}
|
||||
|
||||
if (ptrval.lattice_val == UNDEFINED)
|
||||
return ptrval;
|
||||
gcc_assert ((ptrval.lattice_val == CONSTANT
|
||||
&& TREE_CODE (ptrval.value) == INTEGER_CST)
|
||||
|| ptrval.mask.is_minus_one ());
|
||||
align = gimple_call_arg (stmt, 1);
|
||||
if (!tree_fits_uhwi_p (align))
|
||||
return ptrval;
|
||||
aligni = tree_to_uhwi (align);
|
||||
if (aligni <= 1
|
||||
|| (aligni & (aligni - 1)) != 0)
|
||||
return ptrval;
|
||||
if (gimple_call_num_args (stmt) > 2)
|
||||
if (attr == NULL_TREE)
|
||||
{
|
||||
misalign = gimple_call_arg (stmt, 2);
|
||||
if (!tree_fits_uhwi_p (misalign))
|
||||
return ptrval;
|
||||
misaligni = tree_to_uhwi (misalign);
|
||||
if (misaligni >= aligni)
|
||||
/* Get aligni and misaligni from __builtin_assume_aligned. */
|
||||
align = gimple_call_arg (stmt, 1);
|
||||
if (!tree_fits_uhwi_p (align))
|
||||
return ptrval;
|
||||
aligni = tree_to_uhwi (align);
|
||||
if (gimple_call_num_args (stmt) > 2)
|
||||
{
|
||||
misalign = gimple_call_arg (stmt, 2);
|
||||
if (!tree_fits_uhwi_p (misalign))
|
||||
return ptrval;
|
||||
misaligni = tree_to_uhwi (misalign);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get aligni and misaligni from assume_aligned or
|
||||
alloc_align attributes. */
|
||||
if (TREE_VALUE (attr) == NULL_TREE)
|
||||
return ptrval;
|
||||
attr = TREE_VALUE (attr);
|
||||
align = TREE_VALUE (attr);
|
||||
if (!tree_fits_uhwi_p (align))
|
||||
return ptrval;
|
||||
aligni = tree_to_uhwi (align);
|
||||
if (alloc_aligned)
|
||||
{
|
||||
if (aligni == 0 || aligni > gimple_call_num_args (stmt))
|
||||
return ptrval;
|
||||
align = gimple_call_arg (stmt, aligni - 1);
|
||||
if (!tree_fits_uhwi_p (align))
|
||||
return ptrval;
|
||||
aligni = tree_to_uhwi (align);
|
||||
}
|
||||
else if (TREE_CHAIN (attr) && TREE_VALUE (TREE_CHAIN (attr)))
|
||||
{
|
||||
misalign = TREE_VALUE (TREE_CHAIN (attr));
|
||||
if (!tree_fits_uhwi_p (misalign))
|
||||
return ptrval;
|
||||
misaligni = tree_to_uhwi (misalign);
|
||||
}
|
||||
}
|
||||
if (aligni <= 1 || (aligni & (aligni - 1)) != 0 || misaligni >= aligni)
|
||||
return ptrval;
|
||||
|
||||
align = build_int_cst_type (type, -aligni);
|
||||
alignval = get_value_for_expr (align, true);
|
||||
bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask,
|
||||
@ -1708,12 +1759,27 @@ evaluate_stmt (gimple stmt)
|
||||
break;
|
||||
|
||||
case BUILT_IN_ASSUME_ALIGNED:
|
||||
val = bit_value_assume_aligned (stmt);
|
||||
val = bit_value_assume_aligned (stmt, NULL_TREE, val, false);
|
||||
break;
|
||||
|
||||
default:;
|
||||
}
|
||||
}
|
||||
if (is_gimple_call (stmt) && gimple_call_lhs (stmt))
|
||||
{
|
||||
tree fntype = gimple_call_fntype (stmt);
|
||||
if (fntype)
|
||||
{
|
||||
tree attrs = lookup_attribute ("assume_aligned",
|
||||
TYPE_ATTRIBUTES (fntype));
|
||||
if (attrs)
|
||||
val = bit_value_assume_aligned (stmt, attrs, val, false);
|
||||
attrs = lookup_attribute ("alloc_align",
|
||||
TYPE_ATTRIBUTES (fntype));
|
||||
if (attrs)
|
||||
val = bit_value_assume_aligned (stmt, attrs, val, true);
|
||||
}
|
||||
}
|
||||
is_constant = (val.lattice_val == CONSTANT);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user