From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 27A113858C98; Thu, 21 Mar 2024 19:38:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 27A113858C98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1711049882; bh=E1bQ6n0yu6LtGHhRMaEsZrJ2C/t4Pu9mrZvIZmgm0mE=; h=From:To:Subject:Date:From; b=c1mWLfasBmab9V+bUzkjWSuurhw8O3gshRLk2JM5c7p9leRY5CaaMr5svg/sgrqKt fMAB9laNWq/Hcm+rrPugmD5mPqdKWvjZudbX+WQ4WDe9FSFkYiDVNAUYaDMP4ZZWAb I4eWsw/lyw7vXOZS1q2eqrUTkE2M1RoGFrp0K7H4= From: "earlephilhower at yahoo dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call Date: Thu, 21 Mar 2024 19:37:59 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 12.3.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: earlephilhower at yahoo dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D114421 Bug ID: 114421 Summary: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call Product: gcc Version: 12.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: earlephilhower at yahoo dot com Target Milestone: --- Created attachment 57760 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=3D57760&action=3Dedit sample.ii output of save-temps Running g++ 12.3.0 cross-compiling to arm-none-eabi for armv6s-m/thumb/cortex-m0plus. When the following small C++ code is compiled using no optimization options, the call to the C++ class's isEmpty is properly generated (and returns true forever since head and tail are only ever assigned in the constructor and they're both 0) and an infinite loop happens (as expected). When using -Os= or -O2, g++ completely drops the call to the isEmpty member and the while() lo= op (which should be infinite) isn't there and main() devolves into a simple se= t of printfs. -- sample.cpp #include #include class SimpleFIFO { public: SimpleFIFO() { head =3D 0; tail =3D 0; } public: bool isEmpty() { return( head =3D=3D tail ); } uint16_t head; uint16_t tail; }; static SimpleFIFO fifo; int main(int argc, char **argv) { (void) argc; (void) argv; printf("isEmpty =3D %d\n", fifo.isEmpty() ); while( fifo.isEmpty() ); // -> while( true ) !!! // should *never* come here printf( "NO WAY ! ! !"); } --- Failing compilation G++ -v output (save-temps .i attached) --- $ ../system/arm-none-eabi/bin/arm-none-eabi-g++ -v -save-temps -Os -Wall -Wextra -c sample.cpp=20 Using built-in specs. COLLECT_GCC=3D../system/arm-none-eabi/bin/arm-none-eabi-g++ Target: arm-none-eabi Configured with: /workdir/repo/gcc-gnu/configure --prefix=3D/workdir/arm-none-eabi.x86_64 --build=3Dx86_64-linux-gnu --host=3Dx86_64-linux-gnu --target=3Darm-none-eabi --disable-shared --with-= newlib --enable-threads=3Dno --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --disable-nls --without-python --disable-bootstrap --enable-languages=3Dc,c++ --disable-lto --enable-static=3Dyes --disable-libstdcxx-verbose --disable-decimal-float --with-cpu=3Dcortex-m0p= lus --with-no-thumb-interwork Thread model: single Supported LTO compression algorithms: zlib gcc version 12.3.0 (GCC)=20 COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c' '-mcpu=3Dcortex-m0plus' '-mthumb' '-mlibarch=3Darmv6s-m' '-march=3Darmv6s-m' /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../libexe= c/gcc/arm-none-eabi/12.3.0/cc1plus -E -quiet -v -imultilib thumb -iprefix /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/ -D__USES_INITFINI__ sample.cpp -mcpu=3Dcortex-m0plus -mthumb -mlibarch=3Dar= mv6s-m -march=3Darmv6s-m -Wall -Wextra -Os -fpch-preprocess -o sample.ii ignoring nonexistent directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/sys-include" ignoring duplicate directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++= /12.3.0" ignoring duplicate directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++= /12.3.0/arm-none-eabi/thumb" ignoring duplicate directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++= /12.3.0/backward" ignoring duplicate directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/include" ignoring duplicate directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/include-fixed" ignoring nonexistent directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/sys-include" ignoring duplicate directory "/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/g= cc/../../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include" #include "..." search starts here: #include <...> search starts here: /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++/12.3.0 /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++/12.3.0/arm-non= e-eabi/thumb /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++/12.3.0/backward /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/include /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/include-fixed /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include End of search list. COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c' '-mcpu=3Dcortex-m0plus' '-mthumb' '-mlibarch=3Darmv6s-m' '-march=3Darmv6s-m' /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../libexe= c/gcc/arm-none-eabi/12.3.0/cc1plus -fpreprocessed sample.ii -quiet -dumpbase sample.cpp -dumpbase-ext .cpp -mcpu=3Dcortex-m0plus -mthumb -mlibarch=3Darmv6s-m -march=3Darmv6s-m -Os -W= all -Wextra -version -o sample.s GNU C++17 (GCC) version 12.3.0 (arm-none-eabi) compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 3.= 1.4, MPC version 1.0.3, isl version isl-0.18-GMP GGC heuristics: --param ggc-min-expand=3D100 --param ggc-min-heapsize=3D131= 072 GNU C++17 (GCC) version 12.3.0 (arm-none-eabi) compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 3.= 1.4, MPC version 1.0.3, isl version isl-0.18-GMP GGC heuristics: --param ggc-min-expand=3D100 --param ggc-min-heapsize=3D131= 072 Compiler executable checksum: dc9eae539d88e5656ba12943b9054a3c COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c' '-mcpu=3Dcortex-m0plus' '-mthumb' '-mlibarch=3Darmv6s-m' '-march=3Darmv6s-m' /home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gc= c/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/as -march=3Darmv6s-m -meabi=3D5 -o sample.o sample.s COMPILER_PATH=3D/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-ea= bi/bin/../libexec/gcc/arm-none-eabi/12.3.0/:/home/earle/Arduino/hardware/pi= co/rp2040/system/arm-none-eabi/bin/../libexec/gcc/:/home/earle/Arduino/hard= ware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/.= ./../../../arm-none-eabi/bin/ LIBRARY_PATH=3D/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eab= i/bin/../lib/gcc/arm-none-eabi/12.3.0/thumb/:/home/earle/Arduino/hardware/p= ico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../.= ./../arm-none-eabi/lib/thumb/:/home/earle/Arduino/hardware/pico/rp2040/syst= em/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/:/home/earle/Arduino/h= ardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/:/home/earle/Arduin= o/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12= .3.0/../../../../arm-none-eabi/lib/ COLLECT_GCC_OPTIONS=3D'-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c' '-mcpu=3Dcortex-m0plus' '-mthumb' '-mlibarch=3Darmv6s-m' '-march=3Darmv6s-m' --- When built using the command line "arm-none-eabi-g++ -v -save-temps -Os -Wa= ll -Wextra -c sample.cpp", main disassembles per objdump to just a couple printf()s: --- 00000000
: 0: b510 push {r4, lr} 2: 4b07 ldr r3, [pc, #28] @ (20 ) 4: 4807 ldr r0, [pc, #28] @ (24 ) 6: 8859 ldrh r1, [r3, #2] 8: 881b ldrh r3, [r3, #0] a: 1ac9 subs r1, r1, r3 c: 424b negs r3, r1 e: 4159 adcs r1, r3 10: f7ff fffe bl 0 14: 4804 ldr r0, [pc, #16] @ (28 ) 16: f7ff fffe bl 0 1a: 2000 movs r0, #0 1c: bd10 pop {r4, pc} 1e: 46c0 nop @ (mov r8, r8) ... 28: 0000000e .word 0x0000000e --- But, without any optimization options ("../system/arm-none-eabi/bin/arm-none-eabi-g++ -v -save-temps -Wall -Wextr= a -c sample.cpp") we do see the call to the class function isEmpty (essentially making the while() an infinite loop in this trivial example) --- 00000000
: 0: b580 push {r7, lr} 2: b082 sub sp, #8 4: af00 add r7, sp, #0 6: 6078 str r0, [r7, #4] 8: 6039 str r1, [r7, #0] a: 4b0d ldr r3, [pc, #52] @ (40 ) c: 0018 movs r0, r3 e: f7ff fffe bl 0
12: 0003 movs r3, r0 14: 001a movs r2, r3 16: 4b0b ldr r3, [pc, #44] @ (44 ) 18: 0011 movs r1, r2 1a: 0018 movs r0, r3 1c: f7ff fffe bl 0 20: 46c0 nop @ (mov r8, r8) 22: 4b07 ldr r3, [pc, #28] @ (40 ) 24: 0018 movs r0, r3 26: f7ff fffe bl 0
2a: 1e03 subs r3, r0, #0 2c: d1f9 bne.n 22 2e: 4b06 ldr r3, [pc, #24] @ (48 ) 30: 0018 movs r0, r3 32: f7ff fffe bl 0 36: 2300 movs r3, #0 38: 0018 movs r0, r3 3a: 46bd mov sp, r7 3c: b002 add sp, #8 3e: bd80 pop {r7, pc} ... 48: 00000010 .word 0x00000010 --- Originally spotted by another user and documented here: https://github.com/earlephilhower/arduino-pico/discussions/2062 Apologies in advance if this is a generic C++ undefined behavior, but I can= 't see anything and when run natively on the x86_64 (and -m32 x86) all optimization levels get the expected infinite loop and valgrind shows no warnings. Thanks for any assistance, -EFP3=