public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value
@ 2020-06-29 16:19 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 16:20 ` [Bug other/95971] " 0xe2.0x9a.0x9b at gmail dot com
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 16:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

            Bug ID: 95971
           Summary: [10 regression] Optimizer converts a false boolean
                    value into a true boolean value
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 0xe2.0x9a.0x9b at gmail dot com
  Target Milestone: ---

Hello. I have found an optimization issue that is triggered by the -O2
optimization option in GCC 10.1.0.

The source code (see below) contains an infinite while(cond){} loop. The loop
condition is expected to always evaluate to true. The optimizer incorrectly
derives that the loop condition evaluates to false and removes the loop. It is
possible that the issue is related to optimizations of the delete operator in
C++.

Reproducibility:

  g++ 10.1.0 -O0: not reproducible
  g++ 10.1.0 -O1: not reproducible
  g++ 10.1.0 -O2: REPRODUCIBLE
  g++ 10.1.0 -O3: not reproducible
  g++ 9.3.0  -O2: not reproducible
  clang++ 10 -O2: not reproducible

Full source code:

$ cat a.cc
void xbool(bool value);

struct A {
        char *a = (char*)1;
        ~A() { delete a; }
        bool isZero() { return a == (void*)0; }
};

int main() {
        A a;
        xbool(a.isZero());
        while(!a.isZero());
        xbool(a.isZero()); // This line isn't required to trigger the issue
        return 0;
}

$ cat b.cc
void xbool(bool value) {}

$ cat Makefile 
test:
        g++ -c -O2 a.cc
        g++ -c b.cc
        g++ -o a a.o b.o
        time ./a

Dump of assembler code for function main:

   push   %rbp
   xor    %edi,%edi // %rdi := false
   sub    $0x10,%rsp
   movq   $0x1,0x8(%rsp)
   callq  xbool(bool)
   mov    $0x1,%edi // %rdi := true
   callq  xbool(bool)
   lea    0x8(%rsp),%rdi
   callq  A::~A()
   add    $0x10,%rsp
   xor    %eax,%eax
   pop    %rbp
   retq   
   mov    %rax,%rbp
   jmpq   main.cold

In the assembler code: The compiler correctly passes zero (false) in the 1st
call to function xbool(bool), then incorrectly passes one (true) in the 2nd
call to function xbool(bool).

The source code initializes A::a to (char*)1 in order to keep the code as small
as possible to trigger the issue. A::a could have been initialized to a valid
delete-able heap address, but this would unnecessarily enlarge the source code.

The GCC version string on my machine is "g++ (Gentoo 10.1.0-r1 p2) 10.1.0".


Please confirm the reproducibility of this issue.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 16:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #1 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
Created attachment 48804
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48804&action=edit
a.cc

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 16:20 ` [Bug other/95971] " 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 16:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #2 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
Created attachment 48805
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48805&action=edit
b.cc

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 16:20 ` [Bug other/95971] " 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 17:43 ` marxin at gcc dot gnu.org
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 16:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #3 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
Created attachment 48806
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48806&action=edit
Makefile

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (2 preceding siblings ...)
  2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 17:43 ` marxin at gcc dot gnu.org
  2020-06-29 18:05 ` 0xe2.0x9a.0x9b at gmail dot com
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: marxin at gcc dot gnu.org @ 2020-06-29 17:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |WAITING
                 CC|                            |marxin at gcc dot gnu.org
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2020-06-29

--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> ---
> The source code initializes A::a to (char*)1 in order to keep the code as
> small as possible to trigger the issue. A::a could have been initialized to
> a valid delete-able heap address, but this would unnecessarily enlarge the
> source code.

Thank you for the report. Please extend the example in order to not contain
undefined behavior.
delete 1 crashes for me.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (3 preceding siblings ...)
  2020-06-29 17:43 ` marxin at gcc dot gnu.org
@ 2020-06-29 18:05 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 18:27 ` marxin at gcc dot gnu.org
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 18:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #48804|0                           |1
        is obsolete|                            |

--- Comment #5 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
Created attachment 48808
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48808&action=edit
a.cc

Initialize A::a to a valid heap pointer, instead of initializing it to
(char*)1.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (4 preceding siblings ...)
  2020-06-29 18:05 ` 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 18:27 ` marxin at gcc dot gnu.org
  2020-06-29 18:44 ` 0xe2.0x9a.0x9b at gmail dot com
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: marxin at gcc dot gnu.org @ 2020-06-29 18:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|WAITING                     |RESOLVED

--- Comment #6 from Martin Liška <marxin at gcc dot gnu.org> ---
All right, so it's caused by cdde1:

Assume loop 1 to be finite: it has an exit and -ffinite-loops is on.

       -ffinite-loops
           Assume that a loop with an exit will eventually take the exit and
not loop indefinitely.  This allows the compiler to remove loops that otherwise
have no side-effects, not considering eventual endless looping as such.

           This option is enabled by default at -O2 for C++ with -std=c++11 or
higher.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (5 preceding siblings ...)
  2020-06-29 18:27 ` marxin at gcc dot gnu.org
@ 2020-06-29 18:44 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 18:50 ` marxin at gcc dot gnu.org
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 18:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #7 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
(In reply to Martin Liška from comment #6)
> All right, so it's caused by cdde1:
> 
> Assume loop 1 to be finite: it has an exit and -ffinite-loops is on.
> 
>        -ffinite-loops
>            Assume that a loop with an exit will eventually take the exit and
> not loop indefinitely.  This allows the compiler to remove loops that
> otherwise have no side-effects, not considering eventual endless looping as
> such.
> 
>            This option is enabled by default at -O2 for C++ with -std=c++11
> or higher.

Thank you for the explanation.

Your mindset is forcing me to stop using g++ over time because of reliability
concerns during application development.

Sincerely
Jan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (6 preceding siblings ...)
  2020-06-29 18:44 ` 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 18:50 ` marxin at gcc dot gnu.org
  2020-06-29 19:15 ` 0xe2.0x9a.0x9b at gmail dot com
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: marxin at gcc dot gnu.org @ 2020-06-29 18:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #8 from Martin Liška <marxin at gcc dot gnu.org> ---
Or you can use -fno-finite-loops option.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (7 preceding siblings ...)
  2020-06-29 18:50 ` marxin at gcc dot gnu.org
@ 2020-06-29 19:15 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 20:50 ` 0xe2.0x9a.0x9b at gmail dot com
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 19:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #9 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
(In reply to Martin Liška from comment #8)
> Or you can use -fno-finite-loops option.

I am sorry, but I cannot trust this compiler not to force me again spending
several hours of time just to learn that -O2 is semantically different from -O1
and -O3.

The meaning of "semantically equivalent" in my mind is different from the
meaning of "semantically equivalent" in your mind. Infinite loopiness is in my
opinion semantically significant, so the compiler should have printed a warning
that would inform me about the fact that the compiler is changing the semantics
of the code in question.

With -O3, the assembly code is:

Dump of assembler code for function main:
   <+0>:        sub    $0x8,%rsp
   <+4>:        xor    %edi,%edi
   <+6>:        callq  xbool(bool)
   <+11>:       jmp    main+11

"11: jmp 11" is a prime example of what -ffinite-loops is supposed to prevent
from being generated.

Assuming that -O3 actually does include -ffinite-loops, which I am unable to
verify because "g++ --help=optimizers -Q" doesn't accept the -std=gnu++11
option.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (8 preceding siblings ...)
  2020-06-29 19:15 ` 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 20:50 ` 0xe2.0x9a.0x9b at gmail dot com
  2020-06-29 21:30 ` glisse at gcc dot gnu.org
  2020-06-29 21:43 ` 0xe2.0x9a.0x9b at gmail dot com
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 20:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #10 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
I hope you do realize that the code I posted previously is equivalent, or very
close to being equivalent, to the following code:

  struct President {
    const bool dead = false;
    bool isDead() { return dead; }
  } president;

  while(!president.isDead());
  if(president.isDead()) {
    launch_retaliation_nukes();
  }

With -ffinite-loops enabled, the nukes are going to be launched because the
only way that the while-loop can terminate is for President::dead to be true
and thus the "const bool dead" can be assumed to be true when execution reaches
the if-statement after skipping the deleted infinite while loop.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (9 preceding siblings ...)
  2020-06-29 20:50 ` 0xe2.0x9a.0x9b at gmail dot com
@ 2020-06-29 21:30 ` glisse at gcc dot gnu.org
  2020-06-29 21:43 ` 0xe2.0x9a.0x9b at gmail dot com
  11 siblings, 0 replies; 13+ messages in thread
From: glisse at gcc dot gnu.org @ 2020-06-29 21:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #11 from Marc Glisse <glisse at gcc dot gnu.org> ---
        while(!a.isZero());

that doesn't look like something you would find in real code. Are you waiting
for a different thread to modify a? Then you should use an atomic operation.
Are you waiting for the hardware to change something? Use volatile. Do you
really want an infinite loop? Spell it out if(!a.isZero())for(;;);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug other/95971] [10 regression] Optimizer converts a false boolean value into a true boolean value
  2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
                   ` (10 preceding siblings ...)
  2020-06-29 21:30 ` glisse at gcc dot gnu.org
@ 2020-06-29 21:43 ` 0xe2.0x9a.0x9b at gmail dot com
  11 siblings, 0 replies; 13+ messages in thread
From: 0xe2.0x9a.0x9b at gmail dot com @ 2020-06-29 21:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95971

--- Comment #12 from Jan Ziak (http://atom-symbol.net) <0xe2.0x9a.0x9b at gmail dot com> ---
(In reply to Marc Glisse from comment #11)
> 	while(!a.isZero());
> 
> that doesn't look like something you would find in real code. Are you
> waiting for a different thread to modify a? Then you should use an atomic
> operation. Are you waiting for the hardware to change something? Use
> volatile. Do you really want an infinite loop? Spell it out
> if(!a.isZero())for(;;);

The code I sent is a downsized version of a larger code, which means that the
posted code isn't the real code.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-06-29 21:43 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-29 16:19 [Bug other/95971] New: [10 regression] Optimizer converts a false boolean value into a true boolean value 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 16:20 ` [Bug other/95971] " 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 16:20 ` 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 17:43 ` marxin at gcc dot gnu.org
2020-06-29 18:05 ` 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 18:27 ` marxin at gcc dot gnu.org
2020-06-29 18:44 ` 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 18:50 ` marxin at gcc dot gnu.org
2020-06-29 19:15 ` 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 20:50 ` 0xe2.0x9a.0x9b at gmail dot com
2020-06-29 21:30 ` glisse at gcc dot gnu.org
2020-06-29 21:43 ` 0xe2.0x9a.0x9b at gmail dot com

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).