1;; When BTI is enabled, keep the range check for a jump table for hardening, 2;; even with an unreachable default. 3;; 4;; We check with and without the branch-target-enforcement module attribute, 5;; and in each case, try overriding it with the opposite function attribute. 6;; Expect to see a range check whenever there is BTI, and not where there 7;; isn't. 8 9; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB 10; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBB 11; RUN: sed s/SPACE/4/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBB 12; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB 13 14; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH 15; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBH 16; RUN: sed s/SPACE/400/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBH 17; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH 18 19; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV 20; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-MOV 21; RUN: sed s/SPACE/400000/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-MOV 22; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV 23 24declare i32 @llvm.arm.space(i32, i32) 25 26attributes #0 = { norecurse } 27attributes #1 = { norecurse "branch-target-enforcement" } 28 29define ptr @test_jumptable(ptr %src, ptr %dst) { 30entry: 31 %sw = load i32, ptr %src, align 4 32 %src.postinc = getelementptr inbounds i32, ptr %src, i32 1 33 switch i32 %sw, label %default [ 34 i32 0, label %sw.0 35 i32 1, label %sw.1 36 i32 2, label %sw.2 37 i32 3, label %sw.3 38 ] 39 40sw.0: 41 %store.0 = call i32 @llvm.arm.space(i32 SPACE, i32 14142) 42 store i32 %store.0, ptr %dst, align 4 43 br label %exit 44 45sw.1: 46 %store.1 = call i32 @llvm.arm.space(i32 SPACE, i32 31415) 47 %dst.1 = getelementptr inbounds i32, ptr %dst, i32 1 48 store i32 %store.1, ptr %dst.1, align 4 49 br label %exit 50 51sw.2: 52 %store.2 = call i32 @llvm.arm.space(i32 SPACE, i32 27182) 53 %dst.2 = getelementptr inbounds i32, ptr %dst, i32 2 54 store i32 %store.2, ptr %dst.2, align 4 55 br label %exit 56 57sw.3: 58 %store.3 = call i32 @llvm.arm.space(i32 SPACE, i32 16180) 59 %dst.3 = getelementptr inbounds i32, ptr %dst, i32 3 60 store i32 %store.3, ptr %dst.3, align 4 61 br label %exit 62 63default: 64 unreachable 65 66exit: 67 ret ptr %src.postinc 68} 69 70; NOBTI-TBB: test_jumptable: 71; NOBTI-TBB-NEXT: .fnstart 72; NOBTI-TBB-NEXT: @ %bb 73; NOBTI-TBB-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4 74; NOBTI-TBB-NEXT: .LCPI 75; NOBTI-TBB-NEXT: tbb [pc, [[INDEX]]] 76 77; BTI-TBB: test_jumptable: 78; BTI-TBB-NEXT: .fnstart 79; BTI-TBB-NEXT: @ %bb 80; BTI-TBB-NEXT: bti 81; BTI-TBB-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4 82; BTI-TBB-NEXT: cmp [[INDEX]], #3 83; BTI-TBB-NEXT: bhi .LBB 84; BTI-TBB-NEXT: @ %bb 85; BTI-TBB-NEXT: .LCPI 86; BTI-TBB-NEXT: tbb [pc, [[INDEX]]] 87 88; NOBTI-TBH: test_jumptable: 89; NOBTI-TBH-NEXT: .fnstart 90; NOBTI-TBH-NEXT: @ %bb 91; NOBTI-TBH-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4 92; NOBTI-TBH-NEXT: .LCPI 93; NOBTI-TBH-NEXT: tbh [pc, [[INDEX]], lsl #1] 94 95; BTI-TBH: test_jumptable: 96; BTI-TBH-NEXT: .fnstart 97; BTI-TBH-NEXT: @ %bb 98; BTI-TBH-NEXT: bti 99; BTI-TBH-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4 100; BTI-TBH-NEXT: cmp [[INDEX]], #3 101; BTI-TBH-NEXT: bhi.w .LBB 102; BTI-TBH-NEXT: @ %bb 103; BTI-TBH-NEXT: .LCPI 104; BTI-TBH-NEXT: tbh [pc, [[INDEX]], lsl #1] 105 106; NOBTI-MOV: test_jumptable: 107; NOBTI-MOV-NEXT: .fnstart 108; NOBTI-MOV-NEXT: @ %bb 109; NOBTI-MOV-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4 110; NOBTI-MOV-NEXT: adr.w [[ADDR:r[0-9]+]], .LJTI 111; NOBTI-MOV-NEXT: add.w [[ADDR]], [[ADDR]], [[INDEX]], lsl #2 112; NOBTI-MOV-NEXT: mov pc, [[ADDR]] 113 114; BTI-MOV: test_jumptable: 115; BTI-MOV-NEXT: .fnstart 116; BTI-MOV-NEXT: @ %bb 117; BTI-MOV-NEXT: bti 118; BTI-MOV-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4 119; BTI-MOV-NEXT: cmp [[INDEX]], #3 120; BTI-MOV-NEXT: bls .LBB 121; BTI-MOV-NEXT: b.w .LBB 122; BTI-MOV-NEXT: .LBB 123; BTI-MOV-NEXT: adr.w [[ADDR:r[0-9]+]], .LJTI 124; BTI-MOV-NEXT: add.w [[ADDR]], [[ADDR]], [[INDEX]], lsl #2 125; BTI-MOV-NEXT: mov pc, [[ADDR]] 126 127; for-non-bti-build-sed-will-delete-everything-after-this-line 128!llvm.module.flags = !{!0} 129!0 = !{i32 8, !"branch-target-enforcement", i32 1} 130