[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 eggert at cs dot ucla.edu changed: What|Removed |Added CC||eggert at cs dot ucla.edu --- Comment #8 from eggert at cs dot ucla.edu --- (In reply to Martin Sebor from comment #7) > Committed in r262522. Unfortunately this commit apparently causes GCC to generate incorrect code when compiling Emacs. See Bug#86528.
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 Martin Sebor changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #7 from Martin Sebor --- Committed in r262522.
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 --- Comment #6 from Martin Sebor --- Author: msebor Date: Mon Jul 9 20:33:48 2018 New Revision: 262522 URL: https://gcc.gnu.org/viewcvs?rev=262522&root=gcc&view=rev Log: PR middle-end/77357 - strlen of constant strings not folded gcc/ChangeLog: PR middle-end/77357 PR middle-end/86428 * builtins.c (c_strlen): Avoid out-of-bounds warnings when accessing implicitly initialized array elements. * expr.c (string_constant): Handle string initializers of character arrays within aggregates. * gimple-fold.c (fold_array_ctor_reference): Add argument. Store element offset. As a special case, handle zero size. (fold_nonarray_ctor_reference): Same. (fold_ctor_reference): Add argument. Store subobject offset. * gimple-fold.h (fold_ctor_reference): Add argument. gcc/testsuite/ChangeLog: PR middle-end/77357 * gcc.dg/strlenopt-49.c: New test. * gcc.dg/strlenopt-50.c: New test. * gcc.dg/strlenopt-51.c: New test. * gcc.dg/strlenopt-52.c: New test. Added: trunk/gcc/testsuite/gcc.dg/strlenopt-49.c trunk/gcc/testsuite/gcc.dg/strlenopt-50.c trunk/gcc/testsuite/gcc.dg/strlenopt-51.c trunk/gcc/testsuite/gcc.dg/strlenopt-52.c Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/expr.c trunk/gcc/fold-const.c trunk/gcc/fold-const.h trunk/gcc/gimple-fold.c trunk/gcc/gimple-fold.h trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.c-torture/execute/builtins/strlen-3.c
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 Martin Sebor changed: What|Removed |Added Keywords||patch --- Comment #5 from Martin Sebor --- Patch: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg00279.html
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 Martin Sebor changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #4 from Martin Sebor --- Working on a patch.
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 --- Comment #3 from Richard Biener --- Ok, I'm less interested in -O0 but even with -O1 we fail for global_struct and local_struct. We can improve things by doing Index: gcc/expr.c === --- gcc/expr.c (revision 239778) +++ gcc/expr.c (working copy) @@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. #include "tree-chkp.h" #include "rtl-chkp.h" #include "ccmp.h" +#include "tree-dfa.h" /* If this is nonzero, we do not bother generating VOLATILE @@ -11098,51 +11081,14 @@ string_constant (tree arg, tree *ptr_off if (TREE_CODE (arg) == ADDR_EXPR) { - if (TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST) - { - *ptr_offset = size_zero_node; - return TREE_OPERAND (arg, 0); - } - else if (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL) - { - array = TREE_OPERAND (arg, 0); - offset = size_zero_node; - } - else if (TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF) - { - array = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); - offset = TREE_OPERAND (TREE_OPERAND (arg, 0), 1); - if (TREE_CODE (array) != STRING_CST - && TREE_CODE (array) != VAR_DECL) - return 0; - - /* Check if the array has a nonzero lower bound. */ - lower_bound = array_ref_low_bound (TREE_OPERAND (arg, 0)); - if (!integer_zerop (lower_bound)) - { - /* If the offset and base aren't both constants, return 0. */ - if (TREE_CODE (lower_bound) != INTEGER_CST) - return 0; - if (TREE_CODE (offset) != INTEGER_CST) - return 0; - /* Adjust offset by the lower bound. */ - offset = size_diffop (fold_convert (sizetype, offset), - fold_convert (sizetype, lower_bound)); - } - } - else if (TREE_CODE (TREE_OPERAND (arg, 0)) == MEM_REF) - { - array = TREE_OPERAND (TREE_OPERAND (arg, 0), 0); - offset = TREE_OPERAND (TREE_OPERAND (arg, 0), 1); - if (TREE_CODE (array) != ADDR_EXPR) - return 0; - array = TREE_OPERAND (array, 0); - if (TREE_CODE (array) != STRING_CST - && TREE_CODE (array) != VAR_DECL) - return 0; - } - else + HOST_WIDE_INT off; + array = get_addr_base_and_unit_offset (TREE_OPERAND (arg, 0), &off); + if (! array + || (TREE_CODE (array) != VAR_DECL + && TREE_CODE (array) != CONST_DECL + && TREE_CODE (array) != STRING_CST)) return 0; + *ptr_offset = size_int (off); } else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR) { but then we only handle STRING_CST ctors and not {.a="abc"} we do have some generic fold-a-ctor-reference-at-offset thing (gimple-fold.c:fold_*ctor_reference) but that hasn't the get-me-the-ctor-element-at-offset part factored out. Or finding the ctor element that the offset is within (we can then adjust offset). So a bit of refactoring is missing here.
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 Martin Sebor changed: What|Removed |Added Status|WAITING |NEW --- Comment #2 from Martin Sebor --- Sorry, wrong test case. Here's the right one: const char a[] = "abc"; const char* const s = "abc"; void global_array (void) { if (__builtin_strlen (a) != 3) __builtin_abort (); } void local_array (void) { static const char a[] = "abc"; if (__builtin_strlen (a) != 3) __builtin_abort (); } void global_pointer (void) { if (__builtin_strlen (s) != 3) __builtin_abort (); } void local_pointer (void) { static const char* const s = "abc"; if (__builtin_strlen (s) != 3) __builtin_abort (); } struct X { char a [4]; }; const struct X x = { "abc" }; void global_struct (void) { if (__builtin_strlen (x.a) != 3) __builtin_abort (); } void local_struct (void) { static const struct X x = { "abc" }; if (__builtin_strlen (x.a) != 3) __builtin_abort (); }
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 Richard Biener changed: What|Removed |Added Status|UNCONFIRMED |WAITING Last reconfirmed||2016-08-24 CC||rguenth at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Richard Biener --- Contents of strlen.c?
[Bug middle-end/77357] strlen of constant strings not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357 Martin Sebor changed: What|Removed |Added Keywords||missed-optimization Severity|normal |enhancement