From: Jakub Jelinek Date: Thu, 26 Mar 2015 13:19:59 +0000 (+0100) Subject: re PR tree-optimization/64715 (__builtin_object_size (..., 1) fails to locate subobject) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=672ff0b6fd7f43aa5415bff60ab212b893b9f474;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34a2048f900..6a1a43fa285 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2015-03-26 Jakub Jelinek + 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. diff --git a/gcc/passes.def b/gcc/passes.def index 2bc5dcd781f..c839b7984ca 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5f78043cb65..a0fb7634d51 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-03-26 Jakub Jelinek + + 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 PR middle-end/65519 diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-15.c b/gcc/testsuite/gcc.dg/builtin-object-size-15.c new file mode 100644 index 00000000000..97018572bf8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-object-size-15.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/pr64715-1.c b/gcc/testsuite/gcc.dg/pr64715-1.c new file mode 100644 index 00000000000..fbb635393fb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64715-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/pr64715-2.c b/gcc/testsuite/gcc.dg/pr64715-2.c new file mode 100644 index 00000000000..4c7b581f60e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64715-2.c @@ -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" } } */ diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 4b2c26716cd..828a3d02dbc 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -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 (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)