[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 Andrew Pinski changed: What|Removed |Added Severity|normal |enhancement Last reconfirmed|2018-02-20 00:00:00 |2021-12-26
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 --- Comment #9 from Martin Sebor --- Author: msebor Date: Tue Oct 29 16:14:18 2019 New Revision: 277576 URL: https://gcc.gnu.org/viewcvs?rev=277576=gcc=rev Log: gcc/testsuite/ChangeLog: PR testsuite/92144 * c-c++-common/Warray-bounds-4.c: Disable test to avoid failures due to PR 83543. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/c-c++-common/Warray-bounds-4.c
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 --- Comment #8 from Martin Sebor --- The test committed for the solution for pr83821 is disabled for all targets except LP64 x86_64 to get around this limitation. Once this is implemented across all targets the test should be enabled everywhere.
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 --- Comment #7 from Martin Sebor --- Author: msebor Date: Tue Aug 27 23:31:44 2019 New Revision: 274976 URL: https://gcc.gnu.org/viewcvs?rev=274976=gcc=rev Log: PR tree-optimization/91567 - Spurious -Wformat-overflow warnings building glibc (32-bit only) gcc/ChangeLog: PR tree-optimization/91567 * gimple-ssa-sprintf.c (get_string_length): Handle more forms of lengths of unknown strings. * vr-values.c (vr_values::extract_range_basic): Set strlen upper bound to PTRDIFF_MAX - 2. gcc/testsuite/ChangeLog: PR tree-optimization/91567 * gcc.dg/tree-ssa/builtin-snprintf-6.c: Xfail a subset of assertions on targets other than x86_64 to work around PR 83543. * gcc.dg/tree-ssa/builtin-sprintf-warn-22.c: New test. Added: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c Modified: trunk/gcc/ChangeLog trunk/gcc/gimple-ssa-sprintf.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c trunk/gcc/vr-values.c
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 --- Comment #6 from Martin Sebor --- (In reply to Martin Sebor from comment #5) The cutoff between (a) and (b) also depends on whether or not a function is being optimized for speed or for size, so at -Os, the x86_64 target also uses (b) for all sizes. Here's a test case and its output with an x86_64 compiler: $ cat t.c && gcc -S -Wall -fdump-tree-optimized=/dev/stdout t.c #pragma GCC optimize ("O2") int f (void) { struct A { char a[4]; } a = { "123" }; return __builtin_strlen (a.a); } #pragma GCC optimize ("Os") int g (void) { struct B { char b[4]; } b = { "123" }; return __builtin_strlen (b.b); } ;; Function f (f, funcdef_no=0, decl_uid=1957, cgraph_uid=0, symbol_order=0) __attribute__((optimize ("O2"))) f () { [local count: 1073741825]: return 3; } ;; Function g (g, funcdef_no=1, decl_uid=1963, cgraph_uid=1, symbol_order=1) __attribute__((optimize ("O2", "Os"))) g () { struct B b; long unsigned int _1; int _4; [local count: 1073741825]: b.b = "123"; _1 = __builtin_strlen (); _4 = (int) _1; b ={v} {CLOBBER}; return _4; }
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 --- Comment #5 from Martin Sebor --- (In reply to Ramana Radhakrishnan from comment #4) Setting -march=armv7-a doesn't make a difference. The root cause is that initializers of locally defined aggregates such as struct { char a[N]; } S s = { "12345" }; are represented in one of two ways in GIMPLE: a) as an assignment of the string to s.a, or b) as a copy from a label (e.g., 's = *.LC0') and the strlen pass only knows how to deal with (a) but not (b). AFAICS, whether form (a) or form (b) is chosen depends on the size of the size of the aggregate. Some targets use a lower threshold for (b) than others. As far as I can see, x86_64 appears to cut over at 257 bytes, while arm-none-eabi always uses (b).
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 Ramana Radhakrishnan changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2018-02-20 CC||ramana at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #4 from Ramana Radhakrishnan --- (In reply to Martin Sebor from comment #0) > Bug 83462 reports (among others) a failure in the new > c-c++-common/Warray-bounds-4.c test on powerpc64le. The failure is due to a > strlen optimization that's for some reason not working on this target (and > on some others, including arm-none-eabi) but that works fine on > x86_64-linux. The test case below shows the difference in cross-compiler > output between these three architectures. Is this because arm-none-eabi by default is a STRICT_ALIGNMENT target ? What happens if for instance you try this with -march=armv7-a where we allow some limited misaligned access ? Ramana > > $ (set -x && cat z.c && for arch in '' arm-none-eabi powerpc64le-linux; do > /ssd/build/$arch/gcc-git/gcc/xgcc -B /ssd/build/$arch/gcc-git/gcc -O2 -S > -Wall -fdump-tree-optimized=/dev/stdout z.c; done) > + cat z.c > struct S { char a[7]; }; > > void f (void) > { > struct S s = { "12345" }; > if (__builtin_strlen (s.a) != 5) > __builtin_abort (); > } > + for arch in ''\'''\''' arm-none-eabi powerpc64le-linux > + /ssd/build//gcc-git/gcc/xgcc -B /ssd/build//gcc-git/gcc -O2 -S -Wall > -fdump-tree-optimized=/dev/stdout z.c > > ;; Function f (f, funcdef_no=0, decl_uid=1894, cgraph_uid=0, symbol_order=0) > > f () > { >[local count: 1073741825]: > return; > > } > > > + for arch in ''\'''\''' arm-none-eabi powerpc64le-linux > + /ssd/build/arm-none-eabi/gcc-git/gcc/xgcc -B > /ssd/build/arm-none-eabi/gcc-git/gcc -O2 -S -Wall > -fdump-tree-optimized=/dev/stdout z.c > > ;; Function f (f, funcdef_no=0, decl_uid=4155, cgraph_uid=0, symbol_order=0) > > f () > { > struct S s; > unsigned int _1; > >[local count: 1073741825]: > s = *.LC0; > _1 = __builtin_strlen (); > if (_1 != 5) > goto ; [0.00%] > else > goto ; [99.96%] > >[count: 0]: > __builtin_abort (); > >[local count: 1073312327]: > s ={v} {CLOBBER}; > return; > > } > > > + for arch in ''\'''\''' arm-none-eabi powerpc64le-linux > + /ssd/build/powerpc64le-linux/gcc-git/gcc/xgcc -B > /ssd/build/powerpc64le-linux/gcc-git/gcc -O2 -S -Wall > -fdump-tree-optimized=/dev/stdout z.c > > ;; Function f (f, funcdef_no=0, decl_uid=2784, cgraph_uid=0, symbol_order=0) > > f () > { > struct S s; > long unsigned int _1; > >[local count: 1073741825]: > s = *.LC0; > _1 = __builtin_strlen (); > if (_1 != 5) > goto ; [0.00%] > else > goto ; [99.96%] > >[count: 0]: > __builtin_abort (); > >[local count: 1073312327]: > s ={v} {CLOBBER}; > return; > > }
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 Martin Sebor changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=83821 --- Comment #3 from Martin Sebor --- See also bug 83821 for similar limitation that's target-independent.
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 Martin Sebor changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=83501 --- Comment #2 from Martin Sebor --- See also pr83501 for a related optimization opportunity that strlen could take advantage of.
[Bug tree-optimization/83543] strlen of a local array member not optimized on some targets
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83543 Martin Sebor changed: What|Removed |Added Keywords||missed-optimization --- Comment #1 from Martin Sebor --- On powerpc64le the root cause of the failure to optimize the code is in the strlen pass not handling the struct initialization struct S s = { "12345" }; represented as struct assignment (s = *.LC0 below). The pass only handles assignment to individual struct members (which is how the initialization is represented on x86_64). f () { struct S s; long unsigned int _1; [local count: 1073741825]: s = *.LC0; ... To enable the optimization in this case the pass needs to be extended to handle the assignment from a constant VAR_DECL with an initial value (a CONSTRUCTOR).