This is the mail archive of the gcc@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]

Re: x86 branches vs conditional moves


On Sat, Jul 8, 2017 at 12:30 AM, Michael Clark <michaeljclark@mac.com> wrote:
> Hi,
>
> Curious about this codegen:
>
> - https://godbolt.org/g/5XxP5S
>
> Why does gcc branch on _Bool, but emits a conditional move for an integer? can it emit cmovne instead of branching? also curious where one would change this to learn about GCC internals.

Seems to be caused by a limitation in ifconvert pass which can not
handle slightly more complex code in select_bool.

Return there contains implicit != operations on a and b which clobbers
 CC register:
  (insn 8 7 9 3 (set (reg:CCZ 17 flags)
        (compare:CCZ (mem/c:SI (symbol_ref:DI ("a"))
            (const_int 0 [0]))))
  (insn 9 8 13 3 (set (reg:QI 90 [ <retval> ])
        (ne:QI (reg:CCZ 17 flags)
            (const_int 0 [0]))))
(RTL filtered for brevity). This aborts if-conversion in
noce_process_if_block here
  if (!bb_valid_for_noce_process_p (then_bb, cond, &then_cost,
                                    &if_info->then_simple))
    return false;
because insn_valid_noce_process_p returns false for the first insn above.

> It’s not a bug, but it is a performance issue (*1).

Well, it a performance bug then.

> I was just curious under which conditions the ternary operator is lowered to cmov on x86 and found this difference in lowering.
>
> Michael
>
> [1] https://github.com/xiadz/cmov
>
>
> #include <stdbool.h>
>
> extern int a;
> extern int b;
> extern int c;
> extern _Bool C;
>
> int select_int()
> {
>         return c ? a : b;
> }
>
> _Bool select_bool()
> {
>         return C ? a : b;
> }
>
> _Bool a_bool()
> {
>         return 2;
> }
>
> select_int():
>         mov     eax, DWORD PTR c[rip]
>         test    eax, eax
>         mov     eax, DWORD PTR a[rip]
>         cmove   eax, DWORD PTR b[rip]
>         ret
> select_bool():
>         cmp     BYTE PTR C[rip], 0
>         jne     .L8
>         mov     eax, DWORD PTR b[rip]
>         test    eax, eax
>         setne   al
>         ret
> .L8:
>         mov     edx, DWORD PTR a[rip]
>         test    edx, edx
>         setne   al
>         ret
> a_bool():
>         mov     eax, 1
>         ret


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