1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=thumbv7m-eabi %s -o - | FileCheck %s
; Check that each outlining candidate and the outlined function are in agreement
; with regard to whether BTI insertion is enabled or not.
; volatile int a, b, c, d, e, f;
;
; int x(int p) {
; int r = (a + b) / (c + d) * e + f;
; return r + 1;
; }
;
; __attribute__((target("branch-protection=none")))
; int y(int p) {
; int r = (a + b) / (c + d) * e + f;
; return r + 2;
; }
;
; __attribute__((target("branch-protection=bti")))
; int z(int p) {
; int r = (a + b) / (c + d) * e + f;
; return r + 3;
; }
@a = hidden global i32 0, align 4
@b = hidden global i32 0, align 4
@c = hidden global i32 0, align 4
@d = hidden global i32 0, align 4
@e = hidden global i32 0, align 4
@f = hidden global i32 0, align 4
define hidden i32 @x(i32 %p) local_unnamed_addr #0 {
; CHECK-LABEL: x:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: ldr r0, .LCPI0_0
; CHECK-NEXT: .save {lr}
; CHECK-NEXT: str lr, [sp, #-8]!
; CHECK-NEXT: bl OUTLINED_FUNCTION_0
; CHECK-NEXT: ldr lr, [sp], #8
; CHECK-NEXT: adds r0, #1
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.1:
; CHECK-NEXT: .LCPI0_0:
; CHECK-NEXT: .long .L_MergedGlobals
entry:
%0 = load volatile i32, i32* @a, align 4
%1 = load volatile i32, i32* @b, align 4
%add = add nsw i32 %1, %0
%2 = load volatile i32, i32* @c, align 4
%3 = load volatile i32, i32* @d, align 4
%add1 = add nsw i32 %3, %2
%div = sdiv i32 %add, %add1
%4 = load volatile i32, i32* @e, align 4
%mul = mul nsw i32 %4, %div
%5 = load volatile i32, i32* @f, align 4
%add2 = add nsw i32 %mul, %5
%add3 = add nsw i32 %add2, 1
ret i32 %add3
}
define hidden i32 @y(i32 %p) local_unnamed_addr #1 {
; CHECK-LABEL: y:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: ldr r0, .LCPI1_0
; CHECK-NEXT: .save {lr}
; CHECK-NEXT: str lr, [sp, #-8]!
; CHECK-NEXT: bl OUTLINED_FUNCTION_0
; CHECK-NEXT: ldr lr, [sp], #8
; CHECK-NEXT: adds r0, #2
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.1:
; CHECK-NEXT: .LCPI1_0:
; CHECK-NEXT: .long .L_MergedGlobals
entry:
%0 = load volatile i32, i32* @a, align 4
%1 = load volatile i32, i32* @b, align 4
%add = add nsw i32 %1, %0
%2 = load volatile i32, i32* @c, align 4
%3 = load volatile i32, i32* @d, align 4
%add1 = add nsw i32 %3, %2
%div = sdiv i32 %add, %add1
%4 = load volatile i32, i32* @e, align 4
%mul = mul nsw i32 %4, %div
%5 = load volatile i32, i32* @f, align 4
%add2 = add nsw i32 %mul, %5
%add3 = add nsw i32 %add2, 2
ret i32 %add3
}
define hidden i32 @z(i32 %p) local_unnamed_addr #2 {
; CHECK-LABEL: z:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: bti
; CHECK-NEXT: ldr r0, .LCPI2_0
; CHECK-NEXT: ldr r1, [r0]
; CHECK-NEXT: ldr r2, [r0, #4]
; CHECK-NEXT: add r1, r2
; CHECK-NEXT: ldr r2, [r0, #8]
; CHECK-NEXT: ldr r3, [r0, #12]
; CHECK-NEXT: add r2, r3
; CHECK-NEXT: sdiv r1, r1, r2
; CHECK-NEXT: ldr r2, [r0, #16]
; CHECK-NEXT: ldr r0, [r0, #20]
; CHECK-NEXT: mla r0, r2, r1, r0
; CHECK-NEXT: adds r0, #3
; CHECK-NEXT: bx lr
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: @ %bb.1:
; CHECK-NEXT: .LCPI2_0:
; CHECK-NEXT: .long .L_MergedGlobals
entry:
%0 = load volatile i32, i32* @a, align 4
%1 = load volatile i32, i32* @b, align 4
%add = add nsw i32 %1, %0
%2 = load volatile i32, i32* @c, align 4
%3 = load volatile i32, i32* @d, align 4
%add1 = add nsw i32 %3, %2
%div = sdiv i32 %add, %add1
%4 = load volatile i32, i32* @e, align 4
%mul = mul nsw i32 %4, %div
%5 = load volatile i32, i32* @f, align 4
%add2 = add nsw i32 %mul, %5
%add3 = add nsw i32 %add2, 3
ret i32 %add3
}
attributes #0 = { minsize nofree norecurse nounwind optsize }
attributes #1 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement"="false" }
attributes #2 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement"="true" }
!llvm.module.flags = !{!0}
!0 = !{i32 8, !"branch-target-enforcement", i32 0}
|