-
Notifications
You must be signed in to change notification settings - Fork 15.6k
Description
| Bugzilla Link | 10816 |
| Resolution | FIXED |
| Resolved on | Nov 07, 2018 00:22 |
| Version | trunk |
| OS | Linux |
| Attachments | example source code, and all intermediate files as well as makefile to produce the problem. |
| Reporter | LLVM Bugzilla Contributor |
| CC | @efriedma-quic |
Extended Description
both with llvm 2.9 and trunk svn 138852 a simple switch statement like this:
switch(x)
{
case 0: fun_00(x); break;
case 1: fun_01(x); break;
case 2: fun_02(x); break;
case 3: fun_03(x); break;
case 4: fun_04(x); break;
case 5: fun_05(x); break;
case 6: fun_06(x); break;
case 7: fun_07(x); break;
case 8: fun_08(x); break;
case 9: fun_09(x); break;
default: fun_11(x); break;
}
is turned into a look up table
%x.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
%tmp = load i32* %x.addr, align 4
switch i32 %tmp, label %sw.default [
i32 0, label %sw.bb
i32 1, label %sw.bb2
i32 2, label %sw.bb4
i32 3, label %sw.bb6
i32 4, label %sw.bb8
i32 5, label %sw.bb10
i32 6, label %sw.bb12
i32 7, label %sw.bb14
i32 8, label %sw.bb16
i32 9, label %sw.bb18
]
90: 0080 lsls r0, r0, #2
92: a202 add r2, pc, #8 ; (adr r2, 9c <more_fun+0x18>)
94: 1880 adds r0, r0, r2
96: 6800 ldr r0, [r0, #0]
98: 4687 mov pc, r0
9a: 46c0 nop ; (mov r8, r8)
9c: 000000c4 andeq r0, r0, r4, asr #1
a0: 000000ce andeq r0, r0, lr, asr #1
a4: 000000d8 ldrdeq r0, [r0], -r8
a8: 000000e2 andeq r0, r0, r2, ror #1
ac: 000000ec andeq r0, r0, ip, ror #1
b0: 000000f6 strdeq r0, [r0], -r6
b4: 00000100 andeq r0, r0, r0, lsl #2
b8: 0000010a andeq r0, r0, sl, lsl #2
bc: 00000114 andeq r0, r0, r4, lsl r1
c0: 0000011e andeq r0, r0, lr, lsl r1
The problem is in thumb mode the lsbit of the pc needs to remain set, this is causing an even number to be placed in the program counter. It is interesting that a mov pc,r0 is used and not a bx r0 (which would have made the thing crash much sooner).
.LJTI13_0_0:
.long .LBB13_2
.long .LBB13_3
.long .LBB13_4
.long .LBB13_5
A very ugly hack would be
.LJTI13_0_0:
.long .LBB13_2+1
.long .LBB13_3+1
but it would work (if llc knew that these were lookup table addresses to thumb code, addresses to data would not work with the + 1).