[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / irtranslator-inline-asm.ll
blob8cdb0696f7acc5149deb3f638f3bbc071a93e01d
1 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 ; RUN: llc -mtriple=aarch64-darwin-ios13 -O0 -global-isel -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s
4 define void @asm_simple_memory_clobber() {
5   ; CHECK-LABEL: name: asm_simple_memory_clobber
6   ; CHECK: bb.1 (%ir-block.0):
7   ; CHECK-NEXT:   INLINEASM &"", 25 /* sideeffect mayload maystore attdialect */, !0
8   ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, !0
9   ; CHECK-NEXT:   RET_ReallyLR
10   call void asm sideeffect "", "~{memory}"(), !srcloc !0
11   call void asm sideeffect "", ""(), !srcloc !0
12   ret void
15 !0 = !{i32 70}
17 define void @asm_simple_register_clobber() {
18   ; CHECK-LABEL: name: asm_simple_register_clobber
19   ; CHECK: bb.1 (%ir-block.0):
20   ; CHECK-NEXT:   INLINEASM &"mov x0, 7", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def early-clobber $x0, !0
21   ; CHECK-NEXT:   RET_ReallyLR
22   call void asm sideeffect "mov x0, 7", "~{x0}"(), !srcloc !0
23   ret void
26 define i64 @asm_register_early_clobber() {
27   ; CHECK-LABEL: name: asm_register_early_clobber
28   ; CHECK: bb.1 (%ir-block.0):
29   ; CHECK-NEXT:   INLINEASM &"mov $0, 7; mov $1, 7", 1 /* sideeffect attdialect */, 2555915 /* regdef-ec:GPR64common */, def early-clobber %0, 2555915 /* regdef-ec:GPR64common */, def early-clobber %1, !0
30   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY %0
31   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY %1
32   ; CHECK-NEXT:   [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
33   ; CHECK-NEXT:   $x0 = COPY [[ADD]](s64)
34   ; CHECK-NEXT:   RET_ReallyLR implicit $x0
35   call { i64, i64 } asm sideeffect "mov $0, 7; mov $1, 7", "=&r,=&r"(), !srcloc !0
36   %asmresult = extractvalue { i64, i64 } %1, 0
37   %asmresult1 = extractvalue { i64, i64 } %1, 1
38   %add = add i64 %asmresult, %asmresult1
39   ret i64 %add
42 define i32 @test_specific_register_output() nounwind ssp {
43   ; CHECK-LABEL: name: test_specific_register_output
44   ; CHECK: bb.1.entry:
45   ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $w0
46   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
47   ; CHECK-NEXT:   $w0 = COPY [[COPY]](s32)
48   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
49 entry:
50   %0 = tail call i32 asm "mov ${0:w}, 7", "={w0}"() nounwind
51   ret i32 %0
54 define i32 @test_single_register_output() nounwind ssp {
55   ; CHECK-LABEL: name: test_single_register_output
56   ; CHECK: bb.1.entry:
57   ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1507338 /* regdef:GPR32common */, def %0
58   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
59   ; CHECK-NEXT:   $w0 = COPY [[COPY]](s32)
60   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
61 entry:
62   %0 = tail call i32 asm "mov ${0:w}, 7", "=r"() nounwind
63   ret i32 %0
66 define i64 @test_single_register_output_s64() nounwind ssp {
67   ; CHECK-LABEL: name: test_single_register_output_s64
68   ; CHECK: bb.1.entry:
69   ; CHECK-NEXT:   INLINEASM &"mov $0, 7", 0 /* attdialect */, 2555914 /* regdef:GPR64common */, def %0
70   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY %0
71   ; CHECK-NEXT:   $x0 = COPY [[COPY]](s64)
72   ; CHECK-NEXT:   RET_ReallyLR implicit $x0
73 entry:
74   %0 = tail call i64 asm "mov $0, 7", "=r"() nounwind
75   ret i64 %0
78 ; Check support for returning several floats
79 define float @test_multiple_register_outputs_same() #0 {
80   ; CHECK-LABEL: name: test_multiple_register_outputs_same
81   ; CHECK: bb.1 (%ir-block.0):
82   ; CHECK-NEXT:   INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1507338 /* regdef:GPR32common */, def %0, 1507338 /* regdef:GPR32common */, def %1
83   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
84   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
85   ; CHECK-NEXT:   [[FADD:%[0-9]+]]:_(s32) = G_FADD [[COPY]], [[COPY1]]
86   ; CHECK-NEXT:   $s0 = COPY [[FADD]](s32)
87   ; CHECK-NEXT:   RET_ReallyLR implicit $s0
88   %1 = call { float, float } asm "mov $0, #0; mov $1, #0", "=r,=r"()
89   %asmresult = extractvalue { float, float } %1, 0
90   %asmresult1 = extractvalue { float, float } %1, 1
91   %add = fadd float %asmresult, %asmresult1
92   ret float %add
95 ; Check support for returning several floats
96 define double @test_multiple_register_outputs_mixed() #0 {
97   ; CHECK-LABEL: name: test_multiple_register_outputs_mixed
98   ; CHECK: bb.1 (%ir-block.0):
99   ; CHECK-NEXT:   INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1507338 /* regdef:GPR32common */, def %0, 2359306 /* regdef:FPR64 */, def %1
100   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY %0
101   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY %1
102   ; CHECK-NEXT:   $d0 = COPY [[COPY1]](s64)
103   ; CHECK-NEXT:   RET_ReallyLR implicit $d0
104   %1 = call { float, double } asm "mov $0, #0; mov $1, #0", "=r,=w"()
105   %asmresult = extractvalue { float, double } %1, 1
106   ret double %asmresult
109 define i32 @test_specific_register_output_trunc() nounwind ssp {
110   ; CHECK-LABEL: name: test_specific_register_output_trunc
111   ; CHECK: bb.1.entry:
112   ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 10 /* regdef */, implicit-def $x0
113   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x0
114   ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
115   ; CHECK-NEXT:   $w0 = COPY [[TRUNC]](s32)
116   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
117 entry:
118   %0 = tail call i32 asm "mov ${0:w}, 7", "={x0}"() nounwind
119   ret i32 %0
122 define zeroext i8 @test_register_output_trunc(ptr %src) nounwind {
123   ;
124   ; CHECK-LABEL: name: test_register_output_trunc
125   ; CHECK: bb.1.entry:
126   ; CHECK-NEXT:   liveins: $x0
127   ; CHECK-NEXT: {{  $}}
128   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
129   ; CHECK-NEXT:   INLINEASM &"mov ${0:w}, 32", 0 /* attdialect */, 1507338 /* regdef:GPR32common */, def %1
130   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
131   ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
132   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
133   ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](s32)
134   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
135 entry:
136   %0 = tail call i8 asm "mov ${0:w}, 32", "=r"() nounwind
137   ret i8 %0
140 define float @test_vector_output() nounwind {
141   ; CHECK-LABEL: name: test_vector_output
142   ; CHECK: bb.1 (%ir-block.0):
143   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
144   ; CHECK-NEXT:   INLINEASM &"fmov ${0}.2s, #1.0", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $d14
145   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d14
146   ; CHECK-NEXT:   [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](s64)
147   ; CHECK-NEXT:   $s0 = COPY [[EVEC]](s32)
148   ; CHECK-NEXT:   RET_ReallyLR implicit $s0
149   %1 = tail call <2 x float> asm sideeffect "fmov ${0}.2s, #1.0", "={v14}"() nounwind
150   %2 = extractelement <2 x float> %1, i32 0
151   ret float %2
154 define void @test_input_register_imm() {
155   ; CHECK-LABEL: name: test_input_register_imm
156   ; CHECK: bb.1 (%ir-block.0):
157   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 42
158   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr64common = COPY [[C]](s64)
159   ; CHECK-NEXT:   INLINEASM &"mov x0, $0", 1 /* sideeffect attdialect */, 2555913 /* reguse:GPR64common */, [[COPY]]
160   ; CHECK-NEXT:   RET_ReallyLR
161   call void asm sideeffect "mov x0, $0", "r"(i64 42)
162   ret void
165 ; Make sure that boolean immediates are properly (zero) extended.
166 define i32 @test_boolean_imm_ext() {
167   ; CHECK-LABEL: name: test_boolean_imm_ext
168   ; CHECK: bb.1.entry:
169   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
170   ; CHECK-NEXT:   INLINEASM &"#TEST 42 + ${0:c} - .\0A\09", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 1
171   ; CHECK-NEXT:   $w0 = COPY [[C]](s32)
172   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
173 entry:
174   tail call void asm sideeffect "#TEST 42 + ${0:c} - .\0A\09", "i"(i1 true)
175   ret i32 1
178 define void @test_input_imm() {
179   ; CHECK-LABEL: name: test_input_imm
180   ; CHECK: bb.1 (%ir-block.0):
181   ; CHECK-NEXT:   INLINEASM &"mov x0, $0", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 42
182   ; CHECK-NEXT:   RET_ReallyLR
183   call void asm sideeffect "mov x0, $0", "i"(i64 42)
184   ret void
187 define zeroext i8 @test_input_register(ptr %src) nounwind {
188   ; CHECK-LABEL: name: test_input_register
189   ; CHECK: bb.1.entry:
190   ; CHECK-NEXT:   liveins: $x0
191   ; CHECK-NEXT: {{  $}}
192   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
193   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr64common = COPY [[COPY]](p0)
194   ; CHECK-NEXT:   INLINEASM &"ldtrb ${0:w}, [$1]", 0 /* attdialect */, 1507338 /* regdef:GPR32common */, def %1, 2555913 /* reguse:GPR64common */, [[COPY1]]
195   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY %1
196   ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY2]](s32)
197   ; CHECK-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
198   ; CHECK-NEXT:   $w0 = COPY [[ZEXT]](s32)
199   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
200 entry:
201   %0 = tail call i8 asm "ldtrb ${0:w}, [$1]", "=r,r"(ptr %src) nounwind
202   ret i8 %0
205 define i32 @test_memory_constraint(ptr %a) nounwind {
206   ; CHECK-LABEL: name: test_memory_constraint
207   ; CHECK: bb.1 (%ir-block.0):
208   ; CHECK-NEXT:   liveins: $x0
209   ; CHECK-NEXT: {{  $}}
210   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
211   ; CHECK-NEXT:   INLINEASM &"ldr $0, $1", 8 /* mayload attdialect */, 1507338 /* regdef:GPR32common */, def %1, 262158 /* mem:m */, [[COPY]](p0)
212   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %1
213   ; CHECK-NEXT:   $w0 = COPY [[COPY1]](s32)
214   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
215   %1 = tail call i32 asm "ldr $0, $1", "=r,*m"(ptr elementtype(i32) %a)
216   ret i32 %1
219 define i16 @test_anyext_input() {
220   ; CHECK-LABEL: name: test_anyext_input
221   ; CHECK: bb.1 (%ir-block.0):
222   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
223   ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
224   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
225   ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 1507338 /* regdef:GPR32common */, def %0, 1507337 /* reguse:GPR32common */, [[COPY]]
226   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
227   ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
228   ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
229   ; CHECK-NEXT:   $w0 = COPY [[ANYEXT1]](s32)
230   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
231   %1 = call i16 asm sideeffect "", "=r,r"(i16 1)
232   ret i16 %1
235 define i16 @test_anyext_input_with_matching_constraint() {
236   ; CHECK-LABEL: name: test_anyext_input_with_matching_constraint
237   ; CHECK: bb.1 (%ir-block.0):
238   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
239   ; CHECK-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16)
240   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32)
241   ; CHECK-NEXT:   INLINEASM &"", 1 /* sideeffect attdialect */, 1507338 /* regdef:GPR32common */, def %0, 2147483657 /* reguse tiedto:$0 */, [[COPY]](tied-def 3)
242   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY %0
243   ; CHECK-NEXT:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
244   ; CHECK-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
245   ; CHECK-NEXT:   $w0 = COPY [[ANYEXT1]](s32)
246   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
247   %1 = call i16 asm sideeffect "", "=r,0"(i16 1)
248   ret i16 %1
251 define i64 @test_input_with_matching_constraint_to_physical_register() {
252   ; CHECK-LABEL: name: test_input_with_matching_constraint_to_physical_register
253   ; CHECK: bb.1 (%ir-block.0):
254   ; CHECK-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
255   ; CHECK-NEXT:   INLINEASM &"", 0 /* attdialect */, 10 /* regdef */, implicit-def $x2, 2147483657 /* reguse tiedto:$0 */, [[C]](tied-def 3)(s64)
256   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x2
257   ; CHECK-NEXT:   $x0 = COPY [[COPY]](s64)
258   ; CHECK-NEXT:   RET_ReallyLR implicit $x0
259   %1 = tail call i64 asm "", "={x2},0"(i64 0)
260   ret i64 %1