As observed at http://blog.regehr.org/archives/320 (example 7)
int crud (unsigned char c)
return (((((((((((int) c <= 32 || (int) c == 46) || (int) c == 44)
|| (int) c == 58) || (int) c == 59) || (int) c == 60)
|| (int) c == 62) || (int) c == 34) || (int) c == 92)
|| (int) c == 39) != 0);
Can be compiled using shift and mask test operation as:
movzbl %dil, %edi
cmpl $32, %edi
addl $-34, %edi
cmpl $64, %edi
movl $1, %eax
movl %edi, %ecx
shlq %cl, %rax
movq $0x400000017001421, %rdx
testq %rdx, %rax
movl $1, %eax
xorl %eax, %eax
Probably switch conversion pass could be responsible for this.
Note that both llvm and ICC support this optimization and it was requested by kernel folks for a while (they do so by hand)
We probably don't want to do such transformation into GIMPLE_SWITCH always, only if the number of comparisons of the same SSA_NAME is big enough and the range isn't too big.
expand_switch_using_bit_tests_p can be used if we want to limit it just to the bittest cases.
I would do the conversion always when we can turn more than one if into signle switch. Doing so reduces the amount of IL and makes program easier to analyze&opotimize. We should rely on switch expansion code doing the right thing producing back the ifs when profitable.
I know Tom de Vries is working on this problem and has a prototype patch. He'll be posting his work for 4.7.
> I know Tom de Vries is working on this problem and has a prototype patch.
> He'll be posting his work for 4.7.
Related bug: PR 14799.