This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/84982] New: logically inverting bools into local array results in bitwise negation


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

            Bug ID: 84982
           Summary: logically inverting bools into local array results in
                    bitwise negation
           Product: gcc
           Version: 8.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gcc at basnieuwenhuizen dot nl
  Target Milestone: ---

Example program:
#include <stdbool.h>

struct T {
  bool a;
  bool b;
};

extern void t_dummy(bool *flags);

void t(struct T *t) {
  bool flags[2];

  // These two logical nots get combined and converted to a single bitwise not.
  // of course a bitwise not does not give the expected results.
  flags[0] = !t->a;
  flags[1] = !t->b;

  t_dummy(flags);
}

output with gcc -v -save-temps -c -o /tmp/test.o /tmp/test.c -O3:
0000000000000000 <t>:
   0:   48 83 ec 18             sub    $0x18,%rsp
   4:   0f b7 07                movzwl (%rdi),%eax
   7:   48 8d 7c 24 0e          lea    0xe(%rsp),%rdi
   c:   f7 d0                   not    %eax
   e:   66 89 44 24 0e          mov    %ax,0xe(%rsp)
  13:   e8 00 00 00 00          callq  18 <t+0x18>
  18:   48 83 c4 18             add    $0x18,%rsp
  1c:   c3                      retq   


The logical negation gets turned into a bitwise negation during optimization.
As a result if the input contains 1 the output contains 254 instead of zero.
GCC seems to assume values of {0,1} otherwise, as the non-merged not is a xor
with 1.

This happens on svn trunk as of today (8.0.1 20180319 (experimental)), the 8.0
provided by fedora (8.0.1 20180222 (Red Hat 8.0.1-0.16)), but does not happen
on the arch gcc version (7.3.1 20180312). If I figure out how to bisect with
SVN I might have time to bisect this later this week.

It seems that if I make the flags array an argument instead of a local + a
function call using it, the merging goes away and with it the problem.

Apologies if this the wrong component. I have no idea which optimization layer
of GCC would cause this, and hence no idea where to route it to.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]