1# RUN: llc -mtriple=aarch64 -run-pass=machine-outliner -machine-outliner-reruns=1 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix TWO-RUNS
2# RUN: llc -mtriple=aarch64 -run-pass=machine-outliner -machine-outliner-reruns=0 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix ONE-RUN
3# RUN: llc -mtriple=aarch64 -run-pass=machine-outliner -machine-outliner-reruns=3 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix FOUR-RUNS
4
5# Example of Repeated Instruction Sequence - Iterative Machine Outlining
6#
7#; define void @"$s12"(...) {         define i64 @"$s5” (...) {             define void @"$s13"(...) {
8#   ...                                ...                                   ...
9#   %8 = load i1, i1* %7                                                     %8 = load i1, i1* %7
10#   %9 = load i4, i4*, %6              %9 = load i4, i4*, %6                 %9 = load i4, i4*, %6
11#   store i4 %9, i4* %5                store i4 %9, i4* %5                   store i4 %9, i4* %5
12#   ...                                ...                                   ...
13# }                                  }                                     }
14#
15# After machine outliner (1st time)
16#
17# define void @"$s12"(...) {         define i64 @"$s5” (...) {             define void @"$s13"(...) {
18#   ...                                ...                                   ...
19#   %8 = load i1, i1* %7                                                     %8 = load i1, i1* %7
20#   call void @outlined_function_1_1   call void @outlined_function_1_1      call void @outlined_function_1_1
21#   ...                                ...                                   ...
22# }                                  }                                     }
23#
24# After machine outliner (2nd time)
25#
26# define void @"$s12"(...) {         define i64 @"$s5” (...) {             define void @"$s13"(...) {
27#   ...                                ...                                   ...
28#   call void @outlined_function_2_1   call void @outlined_function_1_1      call void @outlined_function_2_1
29#   ...                                ...                                   ...
30# }                                  }                                     }
31#
32# Check whether machine outliner can further find the outlining opportunity after machine
33# outlining has performed.
34#
35--- |
36  declare void @foo() local_unnamed_addr
37
38  declare void @widget() local_unnamed_addr
39
40  ; Function Attrs: minsize noredzone optsize
41  define void @baz.14() #0 {
42    ret void
43  }
44
45  ; Function Attrs: minsize noredzone optsize
46  define void @baz.15() #0 {
47    ret void
48  }
49
50  ; Function Attrs: minsize noredzone optsize
51  define void @baz.16() #0 {
52    ret void
53  }
54
55  attributes #0 = { minsize noredzone optsize }
56...
57---
58name:            baz.14
59tracksRegLiveness: true
60stack:
61  - { id: 0, offset: -8, size: 8 }
62  - { id: 1, offset: -16, size: 8 }
63body:             |
64  bb.0:
65    liveins: $x0, $x19, $lr
66
67    early-clobber $sp = frame-setup STPXpre killed $lr, killed $x19, $sp, -2 :: (store 8 into %stack.1), (store 8 into %stack.0)
68    frame-setup CFI_INSTRUCTION def_cfa_offset 16
69    frame-setup CFI_INSTRUCTION offset $w19, -8
70    frame-setup CFI_INSTRUCTION offset $w30, -16
71    renamable $x19 = COPY $x0
72    renamable $x0 = nuw ADDXri $x0, 48, 0
73    $x1 = ADDXri $sp, 0, 0
74    dead $w2 = MOVi32imm 33, implicit-def $x2
75    $x3 = COPY $xzr
76    BL @foo, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit killed $x1, implicit killed $x2, implicit killed $x3, implicit-def $sp
77    $x0 = COPY killed renamable $x19
78    BL @widget, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
79    early-clobber $sp, $lr, $x19 = frame-destroy LDPXpost $sp, 2 :: (load 8 from %stack.1), (load 8 from %stack.0)
80    RET_ReallyLR
81
82...
83---
84name:            baz.15
85tracksRegLiveness: true
86stack:
87  - { id: 0, offset: -8, size: 8 }
88  - { id: 1, offset: -16, size: 8 }
89body:             |
90  bb.0:
91    liveins: $x0, $x19, $lr
92
93    early-clobber $sp = frame-setup STPXpre killed $lr, killed $x19, $sp, -2 :: (store 8 into %stack.1), (store 8 into %stack.0)
94    frame-setup CFI_INSTRUCTION def_cfa_offset 16
95    frame-setup CFI_INSTRUCTION offset $w19, -8
96    frame-setup CFI_INSTRUCTION offset $w30, -16
97    renamable $x19 = COPY $x0
98    renamable $x0 = nuw ADDXri killed renamable $x0, 16, 0
99    $x1 = ADDXri $sp, 0, 0
100    dead $w2 = MOVi32imm 33, implicit-def $x2
101    $x3 = COPY $xzr
102    BL @foo, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit $x1, implicit killed $x2, implicit killed $x3, implicit-def $sp
103    $x0 = COPY killed renamable $x19
104    BL @widget, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
105    early-clobber $sp, $lr, $x19 = frame-destroy LDPXpost $sp, 2 :: (load 8 from %stack.1), (load 8 from %stack.0)
106    RET_ReallyLR
107
108...
109---
110name:            baz.16
111tracksRegLiveness: true
112stack:
113  - { id: 0, offset: -8, size: 8 }
114  - { id: 1, offset: -16, size: 8 }
115body:             |
116  bb.0:
117    liveins: $x0, $x19, $lr
118
119    early-clobber $sp = frame-setup STPXpre killed $lr, killed $x19, $sp, -2 :: (store 8 into %stack.1), (store 8 into %stack.0)
120    frame-setup CFI_INSTRUCTION def_cfa_offset 16
121    frame-setup CFI_INSTRUCTION offset $w19, -8
122    frame-setup CFI_INSTRUCTION offset $w30, -16
123    renamable $x19 = COPY $x0
124    renamable $x0 = nuw ADDXri $x0, 48, 0
125    $x1 = ADDXri $sp, 0, 0
126    dead $w2 = MOVi32imm 33, implicit-def $x2
127    $x3 = COPY $xzr
128    BL @foo, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit killed $x1, implicit killed $x2, implicit killed $x3, implicit-def $sp
129    $x0 = COPY killed renamable $x19
130    BL @widget, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp
131    early-clobber $sp, $lr, $x19 = frame-destroy LDPXpost $sp, 2 :: (load 8 from %stack.1), (load 8 from %stack.0)
132    RET_ReallyLR
133
134...
135
136# TWO-RUNS: name:            OUTLINED_FUNCTION_2_0
137# TWO-RUNS-DAG: bb.0:
138# TWO-RUNS-DAG: renamable $x19 = COPY $x0
139# TWO-RUNS-NEXT: renamable $x0 = nuw ADDXri $x0, 48, 0
140# TWO-RUNS-NEXT: TCRETURNdi @OUTLINED_FUNCTION_0, 0, implicit $sp
141#
142# The machine outliner is expected to stop at the 1st iteration for case ONE-RUN
143# since machine-outline-runs is specified as 1.
144# ONE-RUN-NOT: [[OUTLINED:OUTLINED_FUNCTION_2_[0-9]+]]
145#
146# The machine outliner is expected to stop at the 3rd iteration for case FOUR-RUNS
147# since the MIR has no change at the 3rd iteration.
148# FOUR-RUNS-NOT: [[OUTLINED:OUTLINED_FUNCTION_3_[0-9]+]]
149# FOUR-RUNS-NOT: [[OUTLINED:OUTLINED_FUNCTION_4_[0-9]+]]
150