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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
clang can now produce:
        andl    $-4, %edi
        movl    table+4(%rdi), %eax
        retq

GCC no longer has the sign extend but still not the above:
        shrb    $2, %dil
        addl    $1, %edi
        andl    $127, %edi
        movl    table(,%rdi,4), %eax
        ret


Trying 8, 9, 11 -> 12:
    8: {r90:QI=r95:SI#0 0>>0x2;clobber flags:CC;}
      REG_DEAD r95:SI
      REG_UNUSED flags:CC
    9: {r91:QI=r90:QI+0x1;clobber flags:CC;}
      REG_DEAD r90:QI
      REG_UNUSED flags:CC
   11: {r93:DI=r91:QI#0&0x7f;clobber flags:CC;}
      REG_UNUSED flags:CC
      REG_DEAD r91:QI
   12: r94:SI=[r93:DI*0x4+`table']
      REG_DEAD r93:DI
Failed to match this instruction:
(set (reg:SI 94 [ table[_3] ])
    (mem:SI (plus:DI (and:DI (plus:DI (mult:DI (subreg:DI (lshiftrt:QI
(subreg:QI (reg:SI 95) 0)
                                (const_int 2 [0x2])) 0)
                        (const_int 4 [0x4]))
                    (const_int 4 [0x4]))
                (const_int 508 [0x1fc]))
            (symbol_ref:DI ("table") [flags 0x2]  <var_decl 0x7fa70c191bd0
table>)) [1 table[_3]+0 S4 A32]))

Note I think the -4 is incorrect even because I think the upper 24bits of eax
is undefined when comining into the function.
If we do this:
int func(unsigned long  c)
{
  c&=0xff;
  return table[(c >> 2) + 1];
}
We get the correct code even:
        andl    $252, %edi
        movl    table+4(%rdi), %eax
        ret

Reply via email to