1 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 ; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s
3 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel -global-isel-abort=1 | FileCheck %s
4 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel -global-isel-abort=1 -stop-after=irtranslator | FileCheck %s --check-prefix=GISEL-MIR
6 %struct.A = type { i8 }
7 %struct.B = type { i32 }
8 %struct.C = type { %struct.B }
9 %struct.D = type { %struct.B }
10 %struct.E = type { %struct.B, %struct.B }
12 declare %struct.A* @A_ctor_base(%struct.A* returned)
13 declare %struct.B* @B_ctor_base(%struct.B* returned, i32)
14 declare %struct.B* @B_ctor_complete(%struct.B* returned, i32)
16 declare %struct.A* @A_ctor_base_nothisret(%struct.A*)
17 declare %struct.B* @B_ctor_base_nothisret(%struct.B*, i32)
18 declare %struct.B* @B_ctor_complete_nothisret(%struct.B*, i32)
20 define %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x) {
21 ; GISEL-MIR-LABEL: name: C_ctor_base
22 ; GISEL-MIR: bb.1.entry:
23 ; GISEL-MIR: liveins: $w1, $x0
24 ; GISEL-MIR: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
25 ; GISEL-MIR: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
26 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
27 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
28 ; GISEL-MIR: BL @A_ctor_base, csr_aarch64_aapcs_thisreturn, implicit-def $lr, implicit $sp, implicit $x0
29 ; GISEL-MIR: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
30 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
31 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
32 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
33 ; GISEL-MIR: TCRETURNdi @B_ctor_base, 0, csr_aarch64_aapcs, implicit $sp, implicit $x0, implicit $w1
35 ; CHECK-LABEL: C_ctor_base:
36 ; CHECK-NOT: mov {{x[0-9]+}}, x0
37 ; CHECK: bl {{_?A_ctor_base}}
38 ; CHECK-NOT: mov x0, {{x[0-9]+}}
39 ; CHECK: b {{_?B_ctor_base}}
40 %0 = bitcast %struct.C* %this to %struct.A*
41 %call = tail call %struct.A* @A_ctor_base(%struct.A* returned %0)
42 %1 = getelementptr inbounds %struct.C, %struct.C* %this, i32 0, i32 0
43 %call2 = tail call %struct.B* @B_ctor_base(%struct.B* returned %1, i32 %x)
47 define %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x) {
48 ; GISEL-MIR-LABEL: name: C_ctor_base_nothisret
49 ; GISEL-MIR: bb.1.entry:
50 ; GISEL-MIR: liveins: $w1, $x0
51 ; GISEL-MIR: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
52 ; GISEL-MIR: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
53 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
54 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
55 ; GISEL-MIR: BL @A_ctor_base_nothisret, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit-def $x0
56 ; GISEL-MIR: [[COPY2:%[0-9]+]]:_(p0) = COPY $x0
57 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
58 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
59 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
60 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
61 ; GISEL-MIR: BL @B_ctor_base_nothisret, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1, implicit-def $x0
62 ; GISEL-MIR: [[COPY3:%[0-9]+]]:_(p0) = COPY $x0
63 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
64 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
65 ; GISEL-MIR: RET_ReallyLR implicit $x0
67 ; CHECK-LABEL: C_ctor_base_nothisret:
68 ; CHECK: mov [[SAVETHIS:x[0-9]+]], x0
69 ; CHECK: bl {{_?A_ctor_base_nothisret}}
70 ; CHECK: mov x0, [[SAVETHIS]]
71 ; CHECK-NOT: b {{_?B_ctor_base_nothisret}}
72 %0 = bitcast %struct.C* %this to %struct.A*
73 %call = tail call %struct.A* @A_ctor_base_nothisret(%struct.A* %0)
74 %1 = getelementptr inbounds %struct.C, %struct.C* %this, i32 0, i32 0
75 %call2 = tail call %struct.B* @B_ctor_base_nothisret(%struct.B* %1, i32 %x)
79 define %struct.C* @C_ctor_complete(%struct.C* %this, i32 %x) {
80 ; GISEL-MIR-LABEL: name: C_ctor_complete
81 ; GISEL-MIR: bb.1.entry:
82 ; GISEL-MIR: liveins: $w1, $x0
83 ; GISEL-MIR: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
84 ; GISEL-MIR: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
85 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
86 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
87 ; GISEL-MIR: TCRETURNdi @C_ctor_base, 0, csr_aarch64_aapcs, implicit $sp, implicit $x0, implicit $w1
89 ; CHECK-LABEL: C_ctor_complete:
90 ; CHECK: b {{_?C_ctor_base}}
91 %call = tail call %struct.C* @C_ctor_base(%struct.C* returned %this, i32 %x)
95 define %struct.C* @C_ctor_complete_nothisret(%struct.C* %this, i32 %x) {
96 ; GISEL-MIR-LABEL: name: C_ctor_complete_nothisret
97 ; GISEL-MIR: bb.1.entry:
98 ; GISEL-MIR: liveins: $w1, $x0
99 ; GISEL-MIR: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
100 ; GISEL-MIR: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
101 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
102 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
103 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
104 ; GISEL-MIR: BL @C_ctor_base_nothisret, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1, implicit-def $x0
105 ; GISEL-MIR: [[COPY2:%[0-9]+]]:_(p0) = COPY $x0
106 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
107 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
108 ; GISEL-MIR: RET_ReallyLR implicit $x0
110 ; CHECK-LABEL: C_ctor_complete_nothisret:
111 ; CHECK-NOT: b {{_?C_ctor_base_nothisret}}
112 %call = tail call %struct.C* @C_ctor_base_nothisret(%struct.C* %this, i32 %x)
116 define %struct.D* @D_ctor_base(%struct.D* %this, i32 %x) {
117 ; GISEL-MIR-LABEL: name: D_ctor_base
118 ; GISEL-MIR: bb.1.entry:
119 ; GISEL-MIR: liveins: $w1, $x0
120 ; GISEL-MIR: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
121 ; GISEL-MIR: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
122 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
123 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
124 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
125 ; GISEL-MIR: BL @B_ctor_complete, csr_aarch64_aapcs_thisreturn, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1
126 ; GISEL-MIR: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
127 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
128 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
129 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
130 ; GISEL-MIR: TCRETURNdi @B_ctor_complete, 0, csr_aarch64_aapcs, implicit $sp, implicit $x0, implicit $w1
132 ; CHECK-LABEL: D_ctor_base:
133 ; CHECK-NOT: mov {{x[0-9]+}}, x0
134 ; CHECK: bl {{_?B_ctor_complete}}
135 ; CHECK-NOT: mov x0, {{x[0-9]+}}
136 ; CHECK: b {{_?B_ctor_complete}}
137 %b = getelementptr inbounds %struct.D, %struct.D* %this, i32 0, i32 0
138 %call = tail call %struct.B* @B_ctor_complete(%struct.B* returned %b, i32 %x)
139 %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* returned %b, i32 %x)
143 define %struct.E* @E_ctor_base(%struct.E* %this, i32 %x) {
144 ; GISEL-MIR-LABEL: name: E_ctor_base
145 ; GISEL-MIR: bb.1.entry:
146 ; GISEL-MIR: liveins: $w1, $x0
147 ; GISEL-MIR: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
148 ; GISEL-MIR: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
149 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
150 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
151 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
152 ; GISEL-MIR: BL @B_ctor_complete, csr_aarch64_aapcs_thisreturn, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1
153 ; GISEL-MIR: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
154 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
155 ; GISEL-MIR: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
156 ; GISEL-MIR: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](s64)
157 ; GISEL-MIR: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
158 ; GISEL-MIR: $x0 = COPY [[PTR_ADD]](p0)
159 ; GISEL-MIR: $w1 = COPY [[COPY1]](s32)
160 ; GISEL-MIR: BL @B_ctor_complete, csr_aarch64_aapcs_thisreturn, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1
161 ; GISEL-MIR: [[COPY3:%[0-9]+]]:_(p0) = COPY [[PTR_ADD]](p0)
162 ; GISEL-MIR: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
163 ; GISEL-MIR: $x0 = COPY [[COPY]](p0)
164 ; GISEL-MIR: RET_ReallyLR implicit $x0
166 ; CHECK-LABEL: E_ctor_base:
167 ; CHECK-NOT: b {{_?B_ctor_complete}}
168 %b = getelementptr inbounds %struct.E, %struct.E* %this, i32 0, i32 0
169 %call = tail call %struct.B* @B_ctor_complete(%struct.B* returned %b, i32 %x)
170 %b2 = getelementptr inbounds %struct.E, %struct.E* %this, i32 0, i32 1
171 %call2 = tail call %struct.B* @B_ctor_complete(%struct.B* returned %b2, i32 %x)