https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83821
Leslie Zhai changed:
What|Removed |Added
CC||lesliezhai at llvm dot org.cn
--- Comment #3 from Leslie Zhai ---
(In reply to Martin Sebor from comment #0)
> For the test case below, GCC optimizes the strlen call in f() but fails to
> do the same in g(). It appears because the maybe_invalidate() function in
> the pass considers the initialization of/assignment to b.i as possibly
> clobbering the value of b.s, not realizing that there is no way for the two
> members to alias.
>
> $ cat z.c && gcc -O2 -S -fdump-tree-optimized=/dev/stdout z.c
> #define STR "0123456789"
>
> struct A
> {
> char s[sizeof STR];
> };
>
> void f (void)
> {
> struct A a = { STR };
> if (__builtin_strlen (a.s) != sizeof STR - 1) // folded
> __builtin_abort (); // eliminated
> }
>
> struct B
> {
> char s[sizeof STR];
> int i;
> };
>
> void g (void)
> {
> struct B b = { STR, 123 };
> if (__builtin_strlen (b.s) != sizeof STR - 1) // not folded
> __builtin_abort (); // not eliminated
> }
>
>
> ;; Function f (f, funcdef_no=0, decl_uid=1952, cgraph_uid=0, symbol_order=0)
>
> f ()
> {
>[local count: 1073741825]:
> return;
>
> }
>
>
>
> ;; Function g (g, funcdef_no=1, decl_uid=1959, cgraph_uid=1, symbol_order=1)
>
> g ()
> {
> struct B b;
> long unsigned int _1;
>
>[local count: 1073741825]:
> b.s = "0123456789";
> b.i = 123;
> _1 = __builtin_strlen (&b.s);
> if (_1 != 10)
> goto ; [0.00%]
> else
> goto ; [99.96%]
>
>[count: 0]:
> __builtin_abort ();
>
>[local count: 1073312327]:
> b ={v} {CLOBBER};
> return;
>
> }
$ /opt/mips-gnu-git/bin/mips64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=/opt/mips-gnu-git/bin/mips64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/mips-gnu-git/libexec/gcc/mips64-linux-gnu/8.0.1/lto-wrapper
Target: mips64-linux-gnu
Configured with: ../configure --prefix=/opt/mips-gnu-git
--build=x86_64-redhat-linux-gnu --disable-decimal-float
--disable-dependency-tracking --disable-gold --disable-libgcj --disable-libgomp
--disable-libmpx --disable-libquadmath --disable-libssp
--disable-libunwind-exceptions --disable-shared --disable-silent-rules
--disable-sjlj-exceptions --disable-threads
--with-ld=/usr/bin/mips64-linux-gnu-ld --enable-__cxa_atexit
--enable-checking=release --enable-gnu-unique-object --enable-initfini-array
--enable-languages=c,c++ --enable-linker-build-id --enable-lto --enable-nls
--enable-obsolete --enable-plugin --enable-targets=all
--host=x86_64-redhat-linux-gnu --target=mips64-linux-gnu --with-newlib
--with-plugin-ld=/usr/bin/mips64-linux-gnu-ld --with-system-libunwind
--with-system-zlib --without-headers --with-arch=mips64r2 --with-abi=64
--with-arch_32=mips32r2 --with-fp-32=xx --enable-gnu-indirect-function
Thread model: single
gcc version 8.0.1 20180123 (experimental) (GCC)
But GCC also failed to optimize the strlen call in f() after applied your patch
$ /opt/mips-gnu-git/bin/mips64-linux-gnu-gcc -O2 -S
-fdump-tree-optimized=/dev/stdout z.c
;; Function f (f, funcdef_no=0, decl_uid=1584, cgraph_uid=0, symbol_order=0)
f ()
{
struct A a;
long unsigned int _1;
[local count: 1073741825]:
a = *.LC0;
_1 = __builtin_strlen (&a.s);
if (_1 != 10)
goto ; [0.00%]
else
goto ; [99.96%]
[count: 0]:
__builtin_abort ();
[local count: 1073312327]:
a ={v} {CLOBBER};
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1591, cgraph_uid=1, symbol_order=1)
g ()
{
struct B b;
long unsigned int _1;
[local count: 1073741825]:
b = *.LC1;
_1 = __builtin_strlen (&b.s);
if (_1 != 10)
goto ; [0.00%]
else
goto ; [99.96%]
[count: 0]:
__builtin_abort ();
[local count: 1073312327]:
b ={v} {CLOBBER};
return;
}