https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83821
Leslie Zhai <lesliezhai at llvm dot org.cn> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |lesliezhai at llvm dot org.cn --- Comment #3 from Leslie Zhai <lesliezhai at llvm dot org.cn> --- (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 () > { > <bb 2> [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; > > <bb 2> [local count: 1073741825]: > b.s = "0123456789"; > b.i = 123; > _1 = __builtin_strlen (&b.s); > if (_1 != 10) > goto <bb 3>; [0.00%] > else > goto <bb 4>; [99.96%] > > <bb 3> [count: 0]: > __builtin_abort (); > > <bb 4> [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; <bb 2> [local count: 1073741825]: a = *.LC0; _1 = __builtin_strlen (&a.s); if (_1 != 10) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [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; <bb 2> [local count: 1073741825]: b = *.LC1; _1 = __builtin_strlen (&b.s); if (_1 != 10) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073312327]: b ={v} {CLOBBER}; return; }