v6-jumptable-clobber.mir 10.2 KB
# RUN: llc -run-pass=arm-cp-islands -o - %s | FileCheck %s

# Test created by tweaking the register allocation after stopping the IR below
# just before constant islands. We were forwarding the table index to the end of
# the block, even though the LEA clobbered it.

# CHECK-LABEL: name: foo
# CHECK:     tBR_JT
  # This order is important. If the jump-table comes first then the
  # transformation is valid because the LEA can be removed, see second test.
# CHECK:     CONSTPOOL_ENTRY
# CHECK:     JUMPTABLE_ADDRS

# CHECK-LABEL: name: bar
# CHECK: tTBB_JT $pc, killed $r1

--- |
  ; ModuleID = 'simple.ll'
  source_filename = "simple.ll"
  target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
  target triple = "thumbv6m-none--eabi"
  
  define void @foo(i8 %in, i32* %addr) {
    store i32 12345678, i32* %addr
    %1 = call i32 @llvm.arm.space(i32 980, i32 undef)
    %2 = zext i8 %in to i32
    switch i32 %2, label %default [
      i32 0, label %d1
      i32 1, label %d2
      i32 3, label %d3
      i32 4, label %d4
      i32 5, label %d5
      i32 6, label %d6
      i32 7, label %d7
      i32 2, label %d8
      i32 8, label %d9
      i32 9, label %d10
      i32 19, label %d11
      i32 20, label %d12
      i32 21, label %d13
      i32 22, label %d14
      i32 24, label %d15
      i32 25, label %d16
      i32 26, label %d17
    ]
  
  default:                                          ; preds = %0
    unreachable
  
  d1:                                               ; preds = %0
    unreachable
  
  d2:                                               ; preds = %0
    unreachable
  
  d3:                                               ; preds = %0
    unreachable
  
  d4:                                               ; preds = %0
    unreachable
  
  d5:                                               ; preds = %0
    unreachable
  
  d6:                                               ; preds = %0
    unreachable
  
  d7:                                               ; preds = %0
    unreachable
  
  d8:                                               ; preds = %0
    unreachable
  
  d9:                                               ; preds = %0
    unreachable
  
  d10:                                              ; preds = %0
    unreachable
  
  d11:                                              ; preds = %0
    unreachable
  
  d12:                                              ; preds = %0
    unreachable
  
  d13:                                              ; preds = %0
    unreachable
  
  d14:                                              ; preds = %0
    unreachable
  
  d15:                                              ; preds = %0
    unreachable
  
  d16:                                              ; preds = %0
    unreachable
  
  d17:                                              ; preds = %0
    unreachable
  }

  define void @bar(i8 %in, i32* %addr) {
      store i32 12345678, i32* %addr
    %1 = zext i8 %in to i32
    switch i32 %1, label %default [
      i32 0, label %d1
      i32 1, label %d2
      i32 3, label %d3
      i32 4, label %d4
      i32 5, label %d5
      i32 6, label %d6
      i32 7, label %d7
      i32 2, label %d8
      i32 8, label %d9
      i32 9, label %d10
      i32 19, label %d11
      i32 20, label %d12
      i32 21, label %d13
      i32 22, label %d14
      i32 24, label %d15
      i32 25, label %d16
      i32 26, label %d17
    ]
  
  default:                                          ; preds = %0
    unreachable
  
  d1:                                               ; preds = %0
    unreachable
  
  d2:                                               ; preds = %0
    unreachable
  
  d3:                                               ; preds = %0
    unreachable
  
  d4:                                               ; preds = %0
    unreachable
  
  d5:                                               ; preds = %0
    unreachable
  
  d6:                                               ; preds = %0
    unreachable
  
  d7:                                               ; preds = %0
    unreachable
  
  d8:                                               ; preds = %0
    unreachable
  
  d9:                                               ; preds = %0
    unreachable
  
  d10:                                              ; preds = %0
    unreachable
  
  d11:                                              ; preds = %0
    unreachable
  
  d12:                                              ; preds = %0
    unreachable
  
  d13:                                              ; preds = %0
    unreachable
  
  d14:                                              ; preds = %0
    unreachable
  
  d15:                                              ; preds = %0
    unreachable
  
  d16:                                              ; preds = %0
    unreachable
  
  d17:                                              ; preds = %0
    unreachable
  }
  
  ; Function Attrs: nounwind
  declare i32 @llvm.arm.space(i32, i32) #0
  
  ; Function Attrs: nounwind
  declare void @llvm.stackprotector(i8*, i8**) #0
  
  attributes #0 = { nounwind }

...
---
name:            foo
alignment:       2
exposesReturnsTwice: false
legalized:       false
regBankSelected: false
selected:        false
tracksRegLiveness: true
liveins:         
  - { reg: '$r0' }
  - { reg: '$r1' }
frameInfo:       
  isFrameAddressTaken: false
  isReturnAddressTaken: false
  hasStackMap:     false
  hasPatchPoint:   false
  stackSize:       0
  offsetAdjustment: 0
  maxAlignment:    0
  adjustsStack:    false
  hasCalls:        false
  maxCallFrameSize: 0
  hasOpaqueSPAdjustment: false
  hasVAStart:      false
  hasMustTailInVarArgFunc: false
constants:       
  - id:              0
    value:           i32 12345678
    alignment:       4
jumpTable:       
  kind:            inline
  entries:         
    - id:              0
      blocks:          [ '%bb.3.d2', '%bb.9.d8', '%bb.4.d3', '%bb.5.d4', 
                         '%bb.6.d5', '%bb.7.d6', '%bb.8.d7', '%bb.10.d9', 
                         '%bb.11.d10', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', 
                         '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', 
                         '%bb.2.d1', '%bb.2.d1', '%bb.12.d11', '%bb.13.d12', 
                         '%bb.14.d13', '%bb.15.d14', '%bb.2.d1', '%bb.16.d15', 
                         '%bb.17.d16', '%bb.18.d17' ]
body:             |
  bb.0 (%ir-block.0):
    successors: %bb.2.d1(0x03c3c3c4), %bb.1(0x7c3c3c3c)
    liveins: $r0, $r1
  
    $r2 = tLDRpci %const.0, 14, $noreg
    tSTRi killed $r2, killed $r1, 0, 14, $noreg :: (store 4 into %ir.addr)
    dead $r1 = SPACE 980, undef $r0
    $r0 = tUXTB killed $r0, 14, $noreg
    $r1, dead $cpsr = tSUBi3 killed $r0, 1, 14, $noreg
    tCMPi8 $r1, 25, 14, $noreg, implicit-def $cpsr
    tBcc %bb.2.d1, 8, killed $cpsr
  
  bb.1 (%ir-block.0):
    successors: %bb.3.d2(0x07c549d2), %bb.9.d8(0x07c549d2), %bb.4.d3(0x07c549d2), %bb.5.d4(0x07c549d2), %bb.6.d5(0x07c549d2), %bb.7.d6(0x07c549d2), %bb.8.d7(0x07c549d2), %bb.10.d9(0x07c549d2), %bb.11.d10(0x07c549d2), %bb.2.d1(0x03ab62db), %bb.12.d11(0x07c549d2), %bb.13.d12(0x07c549d2), %bb.14.d13(0x07c549d2), %bb.15.d14(0x07c549d2), %bb.16.d15(0x07c549d2), %bb.17.d16(0x07c549d2), %bb.18.d17(0x07c549d2)
    liveins: $r1
  
    $r0, dead $cpsr = tLSLri killed $r1, 2, 14, $noreg
    $r1 = tLEApcrelJT %jump-table.0, 14, $noreg
    $r0 = tLDRr killed $r1, killed $r0, 14, $noreg :: (load 4 from jump-table)
    tBR_JTr killed $r0, %jump-table.0
  
  bb.3.d2:
  
  bb.9.d8:
  
  bb.4.d3:
  
  bb.5.d4:
  
  bb.6.d5:
  
  bb.7.d6:
  
  bb.8.d7:
  
  bb.10.d9:
  
  bb.11.d10:
  
  bb.2.d1:
  
  bb.12.d11:
  
  bb.13.d12:
  
  bb.14.d13:
  
  bb.15.d14:
  
  bb.16.d15:
  
  bb.17.d16:
  
  bb.18.d17:

...

---
name:            bar
alignment:       2
exposesReturnsTwice: false
legalized:       false
regBankSelected: false
selected:        false
tracksRegLiveness: true
liveins:         
  - { reg: '$r0' }
  - { reg: '$r1' }
frameInfo:       
  isFrameAddressTaken: false
  isReturnAddressTaken: false
  hasStackMap:     false
  hasPatchPoint:   false
  stackSize:       0
  offsetAdjustment: 0
  maxAlignment:    0
  adjustsStack:    false
  hasCalls:        false
  maxCallFrameSize: 0
  hasOpaqueSPAdjustment: false
  hasVAStart:      false
  hasMustTailInVarArgFunc: false
constants:       
  - id:              0
    value:           i32 12345678
    alignment:       4
jumpTable:       
  kind:            inline
  entries:         
    - id:              0
      blocks:          [ '%bb.3.d2', '%bb.9.d8', '%bb.4.d3', '%bb.5.d4', 
                         '%bb.6.d5', '%bb.7.d6', '%bb.8.d7', '%bb.10.d9', 
                         '%bb.11.d10', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', 
                         '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', 
                         '%bb.2.d1', '%bb.2.d1', '%bb.12.d11', '%bb.13.d12', 
                         '%bb.14.d13', '%bb.15.d14', '%bb.2.d1', '%bb.16.d15', 
                         '%bb.17.d16', '%bb.18.d17' ]
body:             |
  bb.0 (%ir-block.0):
    successors: %bb.2.d1(0x03c3c3c4), %bb.1(0x7c3c3c3c)
    liveins: $r0, $r1
  
    $r2 = tLDRpci %const.0, 14, $noreg
    tSTRi killed $r2, killed $r1, 0, 14, $noreg :: (store 4 into %ir.addr)
    $r0 = tUXTB killed $r0, 14, $noreg
    $r1, dead $cpsr = tSUBi3 killed $r0, 1, 14, $noreg
    tCMPi8 $r1, 25, 14, $noreg, implicit-def $cpsr
    tBcc %bb.2.d1, 8, killed $cpsr
  
  bb.1 (%ir-block.0):
    successors: %bb.3.d2(0x07c549d2), %bb.9.d8(0x07c549d2), %bb.4.d3(0x07c549d2), %bb.5.d4(0x07c549d2), %bb.6.d5(0x07c549d2), %bb.7.d6(0x07c549d2), %bb.8.d7(0x07c549d2), %bb.10.d9(0x07c549d2), %bb.11.d10(0x07c549d2), %bb.2.d1(0x03ab62db), %bb.12.d11(0x07c549d2), %bb.13.d12(0x07c549d2), %bb.14.d13(0x07c549d2), %bb.15.d14(0x07c549d2), %bb.16.d15(0x07c549d2), %bb.17.d16(0x07c549d2), %bb.18.d17(0x07c549d2)
    liveins: $r1
  
    $r0, dead $cpsr = tLSLri killed $r1, 2, 14, $noreg
    $r1 = tLEApcrelJT %jump-table.0, 14, $noreg
    $r0 = tLDRr killed $r1, killed $r0, 14, $noreg :: (load 4 from jump-table)
    tBR_JTr killed $r0, %jump-table.0
  
  bb.3.d2:
  
  bb.9.d8:
  
  bb.4.d3:
  
  bb.5.d4:
  
  bb.6.d5:
  
  bb.7.d6:
  
  bb.8.d7:
  
  bb.10.d9:
  
  bb.11.d10:
  
  bb.2.d1:
  
  bb.12.d11:
  
  bb.13.d12:
  
  bb.14.d13:
  
  bb.15.d14:
  
  bb.16.d15:
  
  bb.17.d16:
  
  bb.18.d17:

...