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

            Bug ID: 106822
           Summary: "Boolean-or" optimization opportunity not consistently
                    used
           Product: gcc
           Version: 12.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: benjamin.meier70 at gmail dot com
  Target Milestone: ---

Hello

Assume the following code is given:

-----------------------------
#include <stdio.h>
#include <stdbool.h>

typedef struct {
    bool a;
    bool b;
} MyStruct;

bool f(const MyStruct *s)
{
    return s->a || s->b;
}

int main()
{
}
-----------------------------

If the code is compiled with -O3 I would assume it does not include any jumps,
because it should be valid to always read s->b (even if s->a is already true).
However, the function compiles into this:

-----------------------------
f:
        movzx   eax, BYTE PTR [rdi]
        test    al, al
        jne     .L1
        movzx   eax, BYTE PTR [rdi+1]
.L1:
        ret
-----------------------------
(see: https://godbolt.org/z/KdnzWb9Wh)


Interestingly, gcc will produce code without any jumps if MyStruct is slightly
modified:

-----------------------------
#include <stdio.h>
#include <stdbool.h>

typedef struct {
    int x;
    bool a;
    bool b;
} MyStruct;

bool f(const MyStruct *s)
{
    return s->a || s ->b;
}

int main()
{
}
-----------------------------

Generated code:

-----------------------------
f:
        cmp     WORD PTR [rdi+4], 0
        setne   al
        ret
-----------------------------
(see: https://godbolt.org/z/P78daxhhe)

It's not a bug, but I think it's a missed optimization opportunity.

Thanks

Reply via email to