ifcvt limitations?

Kyrill Tkachov kyrylo.tkachov@foss.arm.com
Tue Jun 2 15:57:00 GMT 2015


Hi all,

I'm looking at a case on aarch64 that's not if-converted to use conditional moves:


typedef unsigned char uint8_t;
typedef unsigned int uint16_t;

uint8_t foo(const uint8_t byte, const uint16_t generator)
{
   if (byte & 0x80) {
     return (byte << 1) ^ (generator & 0xff);
   } else {
     return byte << 1;
   }
}

For aarch64 we fail to if-convert and generate:
foo:
         uxtb    w2, w0
         lsl     w3, w2, 1
         uxtb    w0, w3
         tbnz    x2, 7, .L5
         ret
         .p2align 3
.L5:
         eor     w0, w3, w1
         uxtb    w0, w0
         ret


whereas on x86 we if convert successfully and use a conditional move/select:
         leal    (%rdi,%rdi), %eax
         xorl    %eax, %esi
         testb   %dil, %dil
         cmovs   %esi, %eax
         ret



After fixing some of the branch costs in aarch64 and a bogus cost calculation in cheap_bb_rtx_cost_p
I'm stuck on noce_process_if_block (in ifcvt.c) and what I think is a restriction that the THEN-block contents have to be only a single set insn. This fails on aarch64 because we get an extra zero_extend.

In particular, the following check in noce_process_if_block triggers:
   insn_a = first_active_insn (then_bb);
   if (! insn_a
       || insn_a != last_active_insn (then_bb, FALSE)
       || (set_a = single_set (insn_a)) == NULL_RTX)
     return FALSE;

Is there any particular reason why the code shouldn't be able to handle arbitrarily large contents
in then_bb (within a sane limit)?

Thanks,
Kyrill



More information about the Gcc mailing list