re PR tree-optimization/64715 (__builtin_object_size (..., 1) fails to locate subobject)
PR tree-optimization/64715 * passes.def: Add another instance of pass_object_sizes before ccp1. * tree-object-size.c (pass_object_sizes::execute): In first_pass_instance, only handle __bos (, 1) and __bos (, 3) calls, and keep the call in the IL, as {MIN,MAX}_EXPR of the __bos result and the computed constant. Remove redundant checks, obsoleted by gimple_call_builtin_p test. * gcc.dg/builtin-object-size-15.c: New test. * gcc.dg/pr64715-1.c: New test. * gcc.dg/pr64715-2.c: New test. From-SVN: r221694
This commit is contained in:
parent
d00dce2749
commit
672ff0b6fd
@ -1,5 +1,14 @@
|
||||
2015-03-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/64715
|
||||
* passes.def: Add another instance of pass_object_sizes before
|
||||
ccp1.
|
||||
* tree-object-size.c (pass_object_sizes::execute): In
|
||||
first_pass_instance, only handle __bos (, 1) and __bos (, 3)
|
||||
calls, and keep the call in the IL, as {MIN,MAX}_EXPR of the
|
||||
__bos result and the computed constant. Remove redundant
|
||||
checks, obsoleted by gimple_call_builtin_p test.
|
||||
|
||||
* var-tracking.c (variable_tracking_main_1): Don't track
|
||||
variables for targetm.no_register_allocation targets.
|
||||
|
||||
|
@ -77,6 +77,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
PUSH_INSERT_PASSES_WITHIN (pass_all_early_optimizations)
|
||||
NEXT_PASS (pass_remove_cgraph_callee_edges);
|
||||
NEXT_PASS (pass_rename_ssa_copies);
|
||||
NEXT_PASS (pass_object_sizes);
|
||||
NEXT_PASS (pass_ccp);
|
||||
/* After CCP we rewrite no longer addressed locals into SSA
|
||||
form if possible. */
|
||||
|
@ -1,3 +1,10 @@
|
||||
2015-03-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/64715
|
||||
* gcc.dg/builtin-object-size-15.c: New test.
|
||||
* gcc.dg/pr64715-1.c: New test.
|
||||
* gcc.dg/pr64715-2.c: New test.
|
||||
|
||||
2015-03-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/65519
|
||||
|
27
gcc/testsuite/gcc.dg/builtin-object-size-15.c
Normal file
27
gcc/testsuite/gcc.dg/builtin-object-size-15.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct A { char buf1[9]; char buf2[1]; } a;
|
||||
|
||||
if (__builtin_object_size (a.buf1 + (0 + 4), 1) != 5)
|
||||
abort ();
|
||||
char *p = a.buf1;
|
||||
p += 1;
|
||||
p += 3;
|
||||
if (__builtin_object_size (p, 1) != 5)
|
||||
abort ();
|
||||
p = (char *) &a;
|
||||
char *q = p + 1;
|
||||
char *r = q + 3;
|
||||
char *t = r;
|
||||
if (r != (char *) &a + 4)
|
||||
t = (char *) &a + 1;
|
||||
if (__builtin_object_size (t, 1) != 6)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
23
gcc/testsuite/gcc.dg/pr64715-1.c
Normal file
23
gcc/testsuite/gcc.dg/pr64715-1.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* PR tree-optimization/64715 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
|
||||
extern inline __attribute__ ((always_inline, gnu_inline, artificial, nothrow, leaf)) char *
|
||||
strcpy (char *__restrict dest, const char *__restrict src)
|
||||
{
|
||||
return __builtin___strcpy_chk (dest, src, __builtin_object_size (dest, 2 > 1));
|
||||
}
|
||||
|
||||
const char *str1 = "JIHGFEDCBA";
|
||||
void bar (char *);
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
struct A { char buf1[9]; char buf2[1]; } a;
|
||||
strcpy (a.buf1 + (0 + 4), str1 + 5);
|
||||
bar ((char *) &a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "__builtin___strcpy_chk\[^;\n\r\]*, 5\\\);" "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
19
gcc/testsuite/gcc.dg/pr64715-2.c
Normal file
19
gcc/testsuite/gcc.dg/pr64715-2.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* PR tree-optimization/64715 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
|
||||
void bar (char *, int);
|
||||
|
||||
void
|
||||
foo (int x)
|
||||
{
|
||||
char p[16], *q;
|
||||
q = p;
|
||||
if (x)
|
||||
q = p + 3;
|
||||
__builtin___strcpy_chk (q, "abcdefghijkl", __builtin_object_size (q, 1));
|
||||
bar (p, x);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "__builtin_memcpy \\\(\[^;\n\r\]*, \"abcdefghijkl\", 13\\\);" "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
@ -1268,25 +1268,60 @@ pass_object_sizes::execute (function *fun)
|
||||
continue;
|
||||
|
||||
init_object_sizes ();
|
||||
|
||||
/* In the first pass instance, only attempt to fold
|
||||
__builtin_object_size (x, 1) and __builtin_object_size (x, 3),
|
||||
and rather than folding the builtin to the constant if any,
|
||||
create a MIN_EXPR or MAX_EXPR of the __builtin_object_size
|
||||
call result and the computed constant. */
|
||||
if (first_pass_instance)
|
||||
{
|
||||
tree ost = gimple_call_arg (call, 1);
|
||||
if (tree_fits_uhwi_p (ost))
|
||||
{
|
||||
unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
|
||||
tree ptr = gimple_call_arg (call, 0);
|
||||
tree lhs = gimple_call_lhs (call);
|
||||
if ((object_size_type == 1 || object_size_type == 3)
|
||||
&& (TREE_CODE (ptr) == ADDR_EXPR
|
||||
|| TREE_CODE (ptr) == SSA_NAME)
|
||||
&& lhs)
|
||||
{
|
||||
tree type = TREE_TYPE (lhs);
|
||||
unsigned HOST_WIDE_INT bytes
|
||||
= compute_builtin_object_size (ptr, object_size_type);
|
||||
if (bytes != (unsigned HOST_WIDE_INT) (object_size_type == 1
|
||||
? -1 : 0)
|
||||
&& wi::fits_to_tree_p (bytes, type))
|
||||
{
|
||||
tree tem = make_ssa_name (type);
|
||||
gimple_call_set_lhs (call, tem);
|
||||
enum tree_code code
|
||||
= object_size_type == 1 ? MIN_EXPR : MAX_EXPR;
|
||||
tree cst = build_int_cstu (type, bytes);
|
||||
gimple g = gimple_build_assign (lhs, code, tem, cst);
|
||||
gsi_insert_after (&i, g, GSI_NEW_STMT);
|
||||
update_stmt (call);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
result = fold_call_stmt (as_a <gcall *> (call), false);
|
||||
if (!result)
|
||||
{
|
||||
if (gimple_call_num_args (call) == 2
|
||||
&& POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
|
||||
tree ost = gimple_call_arg (call, 1);
|
||||
|
||||
if (tree_fits_uhwi_p (ost))
|
||||
{
|
||||
tree ost = gimple_call_arg (call, 1);
|
||||
unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
|
||||
|
||||
if (tree_fits_uhwi_p (ost))
|
||||
{
|
||||
unsigned HOST_WIDE_INT object_size_type
|
||||
= tree_to_uhwi (ost);
|
||||
|
||||
if (object_size_type < 2)
|
||||
result = fold_convert (size_type_node,
|
||||
integer_minus_one_node);
|
||||
else if (object_size_type < 4)
|
||||
result = build_zero_cst (size_type_node);
|
||||
}
|
||||
if (object_size_type < 2)
|
||||
result = fold_convert (size_type_node,
|
||||
integer_minus_one_node);
|
||||
else if (object_size_type < 4)
|
||||
result = build_zero_cst (size_type_node);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
|
Loading…
Reference in New Issue
Block a user