public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
@ 2024-03-21 19:37 earlephilhower at yahoo dot com
2024-03-21 19:43 ` [Bug c++/114421] " pinskia at gcc dot gnu.org
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: earlephilhower at yahoo dot com @ 2024-03-21 19:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
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=57760&action=edit
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() loop
(which should be infinite) isn't there and main() devolves into a simple set of
printfs.
-- sample.cpp
#include <stdio.h>
#include <stdint.h>
class SimpleFIFO {
public:
SimpleFIFO() { head = 0; tail = 0; }
public:
bool isEmpty() { return( head == tail ); }
uint16_t head;
uint16_t tail;
};
static SimpleFIFO fifo;
int main(int argc, char **argv) {
(void) argc;
(void) argv;
printf("isEmpty = %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
Using built-in specs.
COLLECT_GCC=../system/arm-none-eabi/bin/arm-none-eabi-g++
Target: arm-none-eabi
Configured with: /workdir/repo/gcc-gnu/configure
--prefix=/workdir/arm-none-eabi.x86_64 --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=arm-none-eabi --disable-shared --with-newlib
--enable-threads=no --disable-__cxa_atexit --disable-libgomp
--disable-libmudflap --disable-nls --without-python --disable-bootstrap
--enable-languages=c,c++ --disable-lto --enable-static=yes
--disable-libstdcxx-verbose --disable-decimal-float --with-cpu=cortex-m0plus
--with-no-thumb-interwork
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 12.3.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c'
'-mcpu=cortex-m0plus' '-mthumb' '-mlibarch=armv6s-m' '-march=armv6s-m'
/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../libexec/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/gcc/arm-none-eabi/12.3.0/
-D__USES_INITFINI__ sample.cpp -mcpu=cortex-m0plus -mthumb -mlibarch=armv6s-m
-march=armv6s-m -Wall -Wextra -Os -fpch-preprocess -o sample.ii
ignoring nonexistent directory
"/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../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/gcc/../../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/gcc/../../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/gcc/../../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/gcc/../../lib/gcc/arm-none-eabi/12.3.0/include"
ignoring duplicate directory
"/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/../../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/gcc/../../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/gcc/../../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/gcc/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/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include/c++/12.3.0/arm-none-eabi/thumb
/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/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/gcc/arm-none-eabi/12.3.0/include
/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/include-fixed
/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c'
'-mcpu=cortex-m0plus' '-mthumb' '-mlibarch=armv6s-m' '-march=armv6s-m'
/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../libexec/gcc/arm-none-eabi/12.3.0/cc1plus
-fpreprocessed sample.ii -quiet -dumpbase sample.cpp -dumpbase-ext .cpp
-mcpu=cortex-m0plus -mthumb -mlibarch=armv6s-m -march=armv6s-m -Os -Wall
-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=100 --param ggc-min-heapsize=131072
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=100 --param ggc-min-heapsize=131072
Compiler executable checksum: dc9eae539d88e5656ba12943b9054a3c
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c'
'-mcpu=cortex-m0plus' '-mthumb' '-mlibarch=armv6s-m' '-march=armv6s-m'
/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/as
-march=armv6s-m -meabi=5 -o sample.o sample.s
COMPILER_PATH=/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../libexec/gcc/arm-none-eabi/12.3.0/:/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../libexec/gcc/:/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/
LIBRARY_PATH=/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/thumb/:/home/earle/Arduino/hardware/pico/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/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/:/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/:/home/earle/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Os' '-Wall' '-Wextra' '-c'
'-mcpu=cortex-m0plus' '-mthumb' '-mlibarch=armv6s-m' '-march=armv6s-m'
---
When built using the command line "arm-none-eabi-g++ -v -save-temps -Os -Wall
-Wextra -c sample.cpp", main disassembles per objdump to just a couple
printf()s:
---
00000000 <main>:
0: b510 push {r4, lr}
2: 4b07 ldr r3, [pc, #28] @ (20 <main+0x20>)
4: 4807 ldr r0, [pc, #28] @ (24 <main+0x24>)
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 <printf>
14: 4804 ldr r0, [pc, #16] @ (28 <main+0x28>)
16: f7ff fffe bl 0 <printf>
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 -Wextra -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 <main>:
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 <main+0x40>)
c: 0018 movs r0, r3
e: f7ff fffe bl 0 <main>
12: 0003 movs r3, r0
14: 001a movs r2, r3
16: 4b0b ldr r3, [pc, #44] @ (44 <main+0x44>)
18: 0011 movs r1, r2
1a: 0018 movs r0, r3
1c: f7ff fffe bl 0 <printf>
20: 46c0 nop @ (mov r8, r8)
22: 4b07 ldr r3, [pc, #28] @ (40 <main+0x40>)
24: 0018 movs r0, r3
26: f7ff fffe bl 0 <main>
2a: 1e03 subs r3, r0, #0
2c: d1f9 bne.n 22 <main+0x22>
2e: 4b06 ldr r3, [pc, #24] @ (48 <main+0x48>)
30: 0018 movs r0, r3
32: f7ff fffe bl 0 <printf>
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
@ 2024-03-21 19:43 ` pinskia at gcc dot gnu.org
2024-03-21 19:53 ` earlephilhower at yahoo dot com
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-21 19:43 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution|--- |INVALID
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
It is undefined in c++ if you don't have forward progress so gcc is removing
the loop.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
2024-03-21 19:43 ` [Bug c++/114421] " pinskia at gcc dot gnu.org
@ 2024-03-21 19:53 ` earlephilhower at yahoo dot com
2024-03-21 20:01 ` xry111 at gcc dot gnu.org
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: earlephilhower at yahoo dot com @ 2024-03-21 19:53 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
--- Comment #2 from Earle F. Philhower, III <earlephilhower at yahoo dot com> ---
Thanks very much for the fast explanation. For reference of others who might
hit this, I see references to C11 6.8.5 pp 6 online (but of course it's an ISO
document so not freely available).
"An iteration statement whose controlling expression is not a constant
expression, that performs no input/output operations, does not access volatile
objects, and performs no synchronization or atomic operations in its body,
controlling expression, or (in the case of a for statement) its expression-3,
may be assumed by the implementation to terminate."
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
2024-03-21 19:43 ` [Bug c++/114421] " pinskia at gcc dot gnu.org
2024-03-21 19:53 ` earlephilhower at yahoo dot com
@ 2024-03-21 20:01 ` xry111 at gcc dot gnu.org
2024-03-21 21:40 ` pinskia at gcc dot gnu.org
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: xry111 at gcc dot gnu.org @ 2024-03-21 20:01 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
Xi Ruoyao <xry111 at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |xry111 at gcc dot gnu.org
--- Comment #3 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
(In reply to Earle F. Philhower, III from comment #2)
> Thanks very much for the fast explanation. For reference of others who
> might hit this, I see references to C11 6.8.5 pp 6 online (but of course
> it's an ISO document so not freely available).
>
> "An iteration statement whose controlling expression is not a constant
> expression, that performs no input/output operations, does not access
> volatile objects, and performs no synchronization or atomic operations in
> its body, controlling expression, or (in the case of a for statement) its
> expression-3, may be assumed by the implementation to terminate."
For this topic C++ is actually more strict than C so referring the C standard
may be still misleading.
In C++ there is no "the controlling expression is a constant expression"
exempt, so even while (true); can be optimized out. AFAIK GCC does not
optimize away while (true); in C++, but Clang is actively doing this. There is
a WG21 paper to add the constant expression exemption for C++ like C (I cannot
remember its Nxxxx ID though).
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
` (2 preceding siblings ...)
2024-03-21 20:01 ` xry111 at gcc dot gnu.org
@ 2024-03-21 21:40 ` pinskia at gcc dot gnu.org
2024-03-21 21:46 ` pinskia at gcc dot gnu.org
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-21 21:40 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>I can't see anything and when run natively on the x86_64 (and -m32 x86)
The behavior changed in GCC 10+, so if you are testing using anything before
GCC 9, you would see the difference. Because on x86_64 with GCC 10 (11, 12, 13
and the trunk) all show the same behavior you are see on arm with GCC 13.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
` (3 preceding siblings ...)
2024-03-21 21:40 ` pinskia at gcc dot gnu.org
@ 2024-03-21 21:46 ` pinskia at gcc dot gnu.org
2024-03-21 21:47 ` pinskia at gcc dot gnu.org
2024-03-21 21:48 ` pinskia at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-21 21:46 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
https://en.cppreference.com/w/cpp/language/memory_model#Forward_progress is a
decent reference when it comes to what it means by forward progress in C++.
Note C and C++ have slightly different requirements. And C++17 has different
from previous versions of C++ also.
(In reply to Xi Ruoyao from comment #3)
> In C++ there is no "the controlling expression is a constant expression"
> exempt, so even while (true); can be optimized out. AFAIK GCC does not
> optimize away while (true); in C++, but Clang is actively doing this. There
> is a WG21 paper to add the constant expression exemption for C++ like C (I
> cannot remember its Nxxxx ID though).
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2809r0.html is the
paper about C++'s `while(true);`
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
` (4 preceding siblings ...)
2024-03-21 21:46 ` pinskia at gcc dot gnu.org
@ 2024-03-21 21:47 ` pinskia at gcc dot gnu.org
2024-03-21 21:48 ` pinskia at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-21 21:47 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|INVALID |DUPLICATE
--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Also the current draft of the C++ standard is free for anyone :
https://eel.is/c++draft/intro.progress#1
*** This bug has been marked as a duplicate of bug 96196 ***
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug c++/114421] arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
` (5 preceding siblings ...)
2024-03-21 21:47 ` pinskia at gcc dot gnu.org
@ 2024-03-21 21:48 ` pinskia at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-21 21:48 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114421
--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** This bug has been marked as a duplicate of bug 93041 ***
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-03-21 21:48 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-21 19:37 [Bug c++/114421] New: arm-none-eabi thumb -Os (and -O2) incorrectly optimizes out needed class member call earlephilhower at yahoo dot com
2024-03-21 19:43 ` [Bug c++/114421] " pinskia at gcc dot gnu.org
2024-03-21 19:53 ` earlephilhower at yahoo dot com
2024-03-21 20:01 ` xry111 at gcc dot gnu.org
2024-03-21 21:40 ` pinskia at gcc dot gnu.org
2024-03-21 21:46 ` pinskia at gcc dot gnu.org
2024-03-21 21:47 ` pinskia at gcc dot gnu.org
2024-03-21 21:48 ` pinskia at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).