I’m dealing with the jumpTable of control flow of my backend, and I found something very strange.
here’s my test case:
int test_JumpTable()
{
unsigned char flag[4] = {0x21, 0x22, 0x23, 0x24};
int Result = 0;
switch (flag[0])
{
case 0x21:
Result = 1;
break;
case 0x22:
Result = 2;
break;
case 0x23:
Result = 3;
break;
}
return Result;
}
My backend can generate .s file from this test case’s .ll file by llc command, like that:
test_JumpTable:
...
# %bb.0:
...
beq $r4, $r5, $BB0_3
b $BB0_1
$BB0_1:
addi.w $r5, $r0, 34
beq $r4, $r5, $BB0_4
b $BB0_2
$BB0_2:
...
$BB0_3:
...
$BB0_4:
...
$BB0_5:
...
$BB0_6:
ld.w $r4, $r3, 8
addi.w $r3, $r3, 16
jr $r1
$func_end0:
But ! if I add one more case in the switch statement, the llc command would fail, it says:
target does not provide no preserved mask
UNREACHABLE executed at /home/dyy/llvm-project-llvmorg-10.0.0/llvm/include/llvm/CodeGen/TargetRegisterInfo.h:447!
Stack dump:
0. Program arguments: ./llc -march=loongarch -relocation-model=pic -mcpu=loongarch32 -filetype=asm test.ll -o -
1. Running pass 'Function Pass Manager' on module 'test.ll'.
2. Running pass 'Live Interval Analysis' on function '@test_JumpTable'
I also tried many other test cases, such as
3 case + 1 default - it’s ok !
2 case - it’s ok !
5 case - no ok!
it seems like My backend can’t support switch with more than 3 case. Why? Comparing the two .ll files generated from 3case and 4case , the only difference is 4case has one more label than 3case. One more label won’t exceed the address limit, I have 16-bit for BasicBlock address.
Does any one have any idea what this bug might be about ? Thank you !