https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116459
Bug ID: 116459 Summary: gcc 12.0 optimized out functions which has observable side affect Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: xiaohuba2021 at 163 dot com Target Milestone: --- The following code: #include <iostream> #include <cstring> using namespace std; struct Matrix { long long mat[2][2]; Matrix() { memset(mat, 0, sizeof(mat)); } Matrix operator*(Matrix b) { Matrix ans; ans.mat[0][0] = (mat[0][0] * b.mat[0][0] + mat[0][1] * b.mat[1][0]); ans.mat[1][0] = (mat[1][0] * b.mat[0][0] + mat[1][1] * b.mat[1][0]); ans.mat[0][1] = (mat[0][0] * b.mat[0][1] + mat[0][1] * b.mat[1][1]); ans.mat[1][1] = (mat[1][0] * b.mat[0][1] + mat[1][1] * b.mat[1][1]); return ans; } }; Matrix st, res; volatile bool mask = 0; void qpw(long long k) { mask = 1; while (k) { if (k & 1) st = st * res; res = res * res, k >>= 1; } } int main() { st.mat[0][0] = st.mat[0][1] = 1; res.mat[0][0] = 6; res.mat[1][0] = -2, res.mat[1][1] = 2; qpw(2); cout << st.mat[0][0] << '\n'; return 0; } seems to produce wrong output(1) with -O2 or -O1 enabled, while the correct answer is 20. Uncomment line 20 (mask = 1) or explicitly add operator= for struct Matrix solves this problem. By looking at the assemble code, I found that the compiler did compile function qpw, however didn't call it. So it's most likely a compiler bug, as the compiler thought qpw did not have any side affects and optimized it out. Is it caused by the default copy assignment of a struct containing only 2D array? Compiler info: Using built-in specs. COLLECT_GCC=/opt/compiler-explorer/gcc-12.2.0/bin/g++ COLLECT_LTO_WRAPPER=/opt/compiler-explorer/gcc-12.2.0/bin/../libexec/gcc/x86_64-linux-gnu/12.2.0/lto-wrapper Target: x86_64-linux-gnu Configured with: ../gcc-12.2.0/configure --prefix=/opt/compiler-explorer/gcc-build/staging --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap --enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --enable-clocale=gnu --enable-languages=c,c++,fortran,ada,objc,obj-c++,go,d --enable-ld=yes --enable-gold=yes --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix --with-pkgversion=Compiler-Explorer-Build-gcc--binutils-2.38 --enable-libstdcxx-backtrace=yes Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.2.0 (Compiler-Explorer-Build-gcc--binutils-2.38)