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