xref: /llvm-project/llvm/test/CodeGen/AArch64/machine-outliner-patchable.ll (revision 6b62166b4cf8ec69f40a81d143fa1d623b4b0d0c)
1; RUN: llc < %s -verify-machineinstrs -enable-machine-outliner | FileCheck %s
2
3target triple = "aarch64-unknown-linux-gnu"
4
5declare void @foo(i32, i32, i32, i32) minsize
6
7;; TargetOpcode::FENTRY_CALL at the start of the function expands to a __fentry__
8;; call which must be present. Don't outline it.
9define void @fentry0(i1 %a) nounwind "fentry-call"="true" {
10; CHECK-LABEL: fentry0:
11; CHECK-NEXT:  // %bb.0:
12; CHECK-NEXT:    # FEntry call
13; CHECK:       // %bb.1:
14; CHECK-NEXT:    bl [[OUTLINED_FUNCTION:OUTLINED_FUNCTION_[0-9]+]]
15entry:
16  br i1 %a, label %if.then, label %if.end
17if.then:
18  call void @foo(i32 1, i32 2, i32 3, i32 4)
19  br label %if.end
20if.end:
21  call void @foo(i32 5, i32 6, i32 7, i32 8)
22  ret void
23}
24
25define void @fentry1(i1 %a) nounwind "fentry-call"="true" {
26; CHECK-LABEL: fentry1:
27; CHECK-NEXT:  // %bb.0:
28; CHECK-NEXT:    # FEntry call
29; CHECK:       // %bb.1:
30; CHECK-NEXT:    bl [[OUTLINED_FUNCTION]]
31entry:
32  br i1 %a, label %if.then, label %if.end
33if.then:
34  call void @foo(i32 1, i32 2, i32 3, i32 4)
35  br label %if.end
36if.end:
37  call void @foo(i32 5, i32 6, i32 7, i32 8)
38  ret void
39}
40
41;; TargetOpcode::PATCHABLE_FUNCTION_ENTER at the start of the function expands to
42;; NOPs which must be present. Don't outline them.
43define void @patchable0(i1 %a) nounwind "patchable-function-entry"="2" {
44; CHECK-LABEL: patchable0:
45; CHECK-NEXT:  .Lfunc_begin0:
46; CHECK-NEXT:  // %bb.0:
47; CHECK-NEXT:    nop
48; CHECK-NEXT:    nop
49; CHECK:       // %bb.1:
50; CHECK-NEXT:    bl [[OUTLINED_FUNCTION]]
51entry:
52  br i1 %a, label %if.then, label %if.end
53if.then:
54  call void @foo(i32 1, i32 2, i32 3, i32 4)
55  br label %if.end
56if.end:
57  call void @foo(i32 5, i32 6, i32 7, i32 8)
58  ret void
59}
60
61define void @patchable1(i1 %a) nounwind "patchable-function-entry"="2" {
62; CHECK-LABEL: patchable1:
63; CHECK-NEXT:  .Lfunc_begin1:
64; CHECK-NEXT:  // %bb.0:
65; CHECK-NEXT:    nop
66; CHECK-NEXT:    nop
67; CHECK:       // %bb.1:
68; CHECK-NEXT:    bl [[OUTLINED_FUNCTION]]
69entry:
70  br i1 %a, label %if.then, label %if.end
71if.then:
72  call void @foo(i32 1, i32 2, i32 3, i32 4)
73  br label %if.end
74if.end:
75  call void @foo(i32 5, i32 6, i32 7, i32 8)
76  ret void
77}
78
79;; Similar to "patchable-function-entry".
80define void @xray0(i1 %a) nounwind "function-instrument"="xray-always" {
81; CHECK-LABEL: xray0:
82; CHECK-NEXT:  .Lfunc_begin2:
83; CHECK-NEXT:  // %bb.0:
84; CHECK-NEXT:  .p2align 2
85; CHECK-NEXT:  .Lxray_sled_0:
86; CHECK:       // %bb.1:
87; CHECK-NEXT:    bl [[OUTLINED_FUNCTION]]
88entry:
89  br i1 %a, label %if.then, label %if.end
90if.then:
91  call void @foo(i32 1, i32 2, i32 3, i32 4)
92  br label %if.end
93if.end:
94  call void @foo(i32 5, i32 6, i32 7, i32 8)
95  ret void
96}
97
98define void @xray1(i1 %a) nounwind "function-instrument"="xray-always" {
99; CHECK-LABEL: xray1:
100; CHECK-NEXT:  .Lfunc_begin3:
101; CHECK-NEXT:  // %bb.0:
102; CHECK-NEXT:  .p2align 2
103; CHECK-NEXT:  .Lxray_sled_2:
104; CHECK:       // %bb.1:
105; CHECK-NEXT:    bl [[OUTLINED_FUNCTION]]
106entry:
107  br i1 %a, label %if.then, label %if.end
108if.then:
109  call void @foo(i32 1, i32 2, i32 3, i32 4)
110  br label %if.end
111if.end:
112  call void @foo(i32 5, i32 6, i32 7, i32 8)
113  ret void
114}
115
116;; Make sure that OUTLINED_FUNCTION contains the right instructions
117; CHECK: [[OUTLINED_FUNCTION]]:
118; CHECK-NEXT:  // %bb.0:
119; CHECK-NEXT:    mov     w0, #1
120; CHECK-NEXT:    mov     w1, #2
121; CHECK-NEXT:    mov     w2, #3
122; CHECK-NEXT:    mov     w3, #4
123; CHECK-NEXT:    b       foo
124