[LLVMbugs] [Bug 10816] New: switch statement can cause invalid thumb addresses

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Aug 30 21:37:40 PDT 2011


           Summary: switch statement can cause invalid thumb addresses
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: dwelch at dwelch.com
                CC: llvmbugs at cs.uiuc.edu

Created an attachment (id=7184)
 --> (http://llvm.org/bugs/attachment.cgi?id=7184)
example source code, and all intermediate files as well as makefile to produce
the problem.

both with llvm 2.9 and trunk svn 138852 a simple switch statement like this:

        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).

    .long    .LBB13_2
    .long    .LBB13_3
    .long    .LBB13_4
    .long    .LBB13_5

A very ugly hack would be

    .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).

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list