microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cesarzc/ssa-panic

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_codegen/src/qir_base/tests.rs

1657lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::too_many_lines)]
5#![allow(clippy::needless_raw_string_hashes)]
6
7use std::sync::Arc;
8
9use expect_test::{expect, Expect};
10use indoc::indoc;
11use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags};
12use qsc_frontend::compile::{self, compile, PackageStore, SourceMap};
13use qsc_passes::{run_core_passes, run_default_passes, PackageType};
14
15use crate::qir_base::generate_qir;
16
17fn check(program: &str, expr: Option<&str>, expect: &Expect) {
18 let mut core = compile::core();
19 assert!(run_core_passes(&mut core).is_empty());
20 let mut store = PackageStore::new(core);
21 let mut std = compile::std(&store, TargetCapabilityFlags::empty());
22 assert!(run_default_passes(
23 store.core(),
24 &mut std,
25 PackageType::Lib,
26 TargetCapabilityFlags::empty()
27 )
28 .is_empty());
29 let std = store.insert(std);
30
31 let expr_as_arc: Option<Arc<str>> = expr.map(|s| Arc::from(s.to_string()));
32 let sources = SourceMap::new([("test".into(), program.into())], expr_as_arc);
33
34 let mut unit = compile(
35 &store,
36 &[std],
37 sources,
38 TargetCapabilityFlags::empty(),
39 LanguageFeatures::default(),
40 );
41 assert!(unit.errors.is_empty(), "{:?}", unit.errors);
42 assert!(run_default_passes(
43 store.core(),
44 &mut unit,
45 PackageType::Exe,
46 TargetCapabilityFlags::empty()
47 )
48 .is_empty());
49 let package = store.insert(unit);
50
51 let qir = generate_qir(&store, package);
52 match qir {
53 Ok(qir) => expect.assert_eq(&qir),
54 Err((err, _)) => expect.assert_debug_eq(&err),
55 }
56}
57
58#[test]
59fn simple_entry_program_is_valid() {
60 check(
61 indoc! {r#"
62 namespace Sample {
63 @EntryPoint()
64 operation Entry() : Result
65 {
66 use q = Qubit();
67 H(q);
68 M(q)
69 }
70 }
71 "#},
72 None,
73 &expect![[r#"
74 %Result = type opaque
75 %Qubit = type opaque
76
77 define void @ENTRYPOINT__main() #0 {
78 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
79 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
80 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
81 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
82 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
83 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
84 ret void
85 }
86
87 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
88 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
89 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
90 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
91 declare void @__quantum__qis__rx__body(double, %Qubit*)
92 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
93 declare void @__quantum__qis__ry__body(double, %Qubit*)
94 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
95 declare void @__quantum__qis__rz__body(double, %Qubit*)
96 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
97 declare void @__quantum__qis__h__body(%Qubit*)
98 declare void @__quantum__qis__s__body(%Qubit*)
99 declare void @__quantum__qis__s__adj(%Qubit*)
100 declare void @__quantum__qis__t__body(%Qubit*)
101 declare void @__quantum__qis__t__adj(%Qubit*)
102 declare void @__quantum__qis__x__body(%Qubit*)
103 declare void @__quantum__qis__y__body(%Qubit*)
104 declare void @__quantum__qis__z__body(%Qubit*)
105 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
106 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
107 declare void @__quantum__rt__result_record_output(%Result*, i8*)
108 declare void @__quantum__rt__array_record_output(i64, i8*)
109 declare void @__quantum__rt__tuple_record_output(i64, i8*)
110
111 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
112 attributes #1 = { "irreversible" }
113
114 ; module flags
115
116 !llvm.module.flags = !{!0, !1, !2, !3}
117
118 !0 = !{i32 1, !"qir_major_version", i32 1}
119 !1 = !{i32 7, !"qir_minor_version", i32 0}
120 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
121 !3 = !{i32 1, !"dynamic_result_management", i1 false}
122 "#]],
123 );
124}
125
126#[test]
127fn simple_program_is_valid() {
128 check(
129 "",
130 Some(indoc! {r#"
131 {
132 use q = Qubit();
133 H(q);
134 M(q)
135 }
136 "#}),
137 &expect![[r#"
138 %Result = type opaque
139 %Qubit = type opaque
140
141 define void @ENTRYPOINT__main() #0 {
142 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
143 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
144 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
145 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
146 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
147 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
148 ret void
149 }
150
151 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
152 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
153 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
154 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
155 declare void @__quantum__qis__rx__body(double, %Qubit*)
156 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
157 declare void @__quantum__qis__ry__body(double, %Qubit*)
158 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
159 declare void @__quantum__qis__rz__body(double, %Qubit*)
160 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
161 declare void @__quantum__qis__h__body(%Qubit*)
162 declare void @__quantum__qis__s__body(%Qubit*)
163 declare void @__quantum__qis__s__adj(%Qubit*)
164 declare void @__quantum__qis__t__body(%Qubit*)
165 declare void @__quantum__qis__t__adj(%Qubit*)
166 declare void @__quantum__qis__x__body(%Qubit*)
167 declare void @__quantum__qis__y__body(%Qubit*)
168 declare void @__quantum__qis__z__body(%Qubit*)
169 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
170 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
171 declare void @__quantum__rt__result_record_output(%Result*, i8*)
172 declare void @__quantum__rt__array_record_output(i64, i8*)
173 declare void @__quantum__rt__tuple_record_output(i64, i8*)
174
175 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="1" }
176 attributes #1 = { "irreversible" }
177
178 ; module flags
179
180 !llvm.module.flags = !{!0, !1, !2, !3}
181
182 !0 = !{i32 1, !"qir_major_version", i32 1}
183 !1 = !{i32 7, !"qir_minor_version", i32 0}
184 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
185 !3 = !{i32 1, !"dynamic_result_management", i1 false}
186 "#]],
187 );
188}
189
190#[test]
191fn output_recording_array() {
192 check(
193 "",
194 Some(indoc! {"{use q = Qubit(); [M(q), M(q)]}"}),
195 &expect![[r#"
196 %Result = type opaque
197 %Qubit = type opaque
198
199 define void @ENTRYPOINT__main() #0 {
200 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
201 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
202 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
203 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
204 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
205 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
206 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
207 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
208 call void @__quantum__rt__array_record_output(i64 2, i8* null)
209 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
210 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
211 ret void
212 }
213
214 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
215 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
216 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
217 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
218 declare void @__quantum__qis__rx__body(double, %Qubit*)
219 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
220 declare void @__quantum__qis__ry__body(double, %Qubit*)
221 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
222 declare void @__quantum__qis__rz__body(double, %Qubit*)
223 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
224 declare void @__quantum__qis__h__body(%Qubit*)
225 declare void @__quantum__qis__s__body(%Qubit*)
226 declare void @__quantum__qis__s__adj(%Qubit*)
227 declare void @__quantum__qis__t__body(%Qubit*)
228 declare void @__quantum__qis__t__adj(%Qubit*)
229 declare void @__quantum__qis__x__body(%Qubit*)
230 declare void @__quantum__qis__y__body(%Qubit*)
231 declare void @__quantum__qis__z__body(%Qubit*)
232 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
233 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
234 declare void @__quantum__rt__result_record_output(%Result*, i8*)
235 declare void @__quantum__rt__array_record_output(i64, i8*)
236 declare void @__quantum__rt__tuple_record_output(i64, i8*)
237
238 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="3" "required_num_results"="2" }
239 attributes #1 = { "irreversible" }
240
241 ; module flags
242
243 !llvm.module.flags = !{!0, !1, !2, !3}
244
245 !0 = !{i32 1, !"qir_major_version", i32 1}
246 !1 = !{i32 7, !"qir_minor_version", i32 0}
247 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
248 !3 = !{i32 1, !"dynamic_result_management", i1 false}
249 "#]],
250 );
251}
252
253#[test]
254fn output_recording_tuple() {
255 check(
256 "",
257 Some(indoc! {"{use q = Qubit(); (M(q), M(q))}"}),
258 &expect![[r#"
259 %Result = type opaque
260 %Qubit = type opaque
261
262 define void @ENTRYPOINT__main() #0 {
263 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
264 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
265 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
266 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
267 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
268 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
269 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
270 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
271 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
272 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
273 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
274 ret void
275 }
276
277 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
278 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
279 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
280 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
281 declare void @__quantum__qis__rx__body(double, %Qubit*)
282 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
283 declare void @__quantum__qis__ry__body(double, %Qubit*)
284 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
285 declare void @__quantum__qis__rz__body(double, %Qubit*)
286 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
287 declare void @__quantum__qis__h__body(%Qubit*)
288 declare void @__quantum__qis__s__body(%Qubit*)
289 declare void @__quantum__qis__s__adj(%Qubit*)
290 declare void @__quantum__qis__t__body(%Qubit*)
291 declare void @__quantum__qis__t__adj(%Qubit*)
292 declare void @__quantum__qis__x__body(%Qubit*)
293 declare void @__quantum__qis__y__body(%Qubit*)
294 declare void @__quantum__qis__z__body(%Qubit*)
295 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
296 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
297 declare void @__quantum__rt__result_record_output(%Result*, i8*)
298 declare void @__quantum__rt__array_record_output(i64, i8*)
299 declare void @__quantum__rt__tuple_record_output(i64, i8*)
300
301 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="3" "required_num_results"="2" }
302 attributes #1 = { "irreversible" }
303
304 ; module flags
305
306 !llvm.module.flags = !{!0, !1, !2, !3}
307
308 !0 = !{i32 1, !"qir_major_version", i32 1}
309 !1 = !{i32 7, !"qir_minor_version", i32 0}
310 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
311 !3 = !{i32 1, !"dynamic_result_management", i1 false}
312 "#]],
313 );
314}
315
316#[test]
317fn reset_allocates_new_qubit_id() {
318 check(
319 "",
320 Some(indoc! {"{use q = Qubit(); H(q); Reset(q); H(q); M(q)}"}),
321 &expect![[r#"
322 %Result = type opaque
323 %Qubit = type opaque
324
325 define void @ENTRYPOINT__main() #0 {
326 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
327 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
328 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
329 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
330 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
331 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
332 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
333 ret void
334 }
335
336 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
337 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
338 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
339 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
340 declare void @__quantum__qis__rx__body(double, %Qubit*)
341 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
342 declare void @__quantum__qis__ry__body(double, %Qubit*)
343 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
344 declare void @__quantum__qis__rz__body(double, %Qubit*)
345 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
346 declare void @__quantum__qis__h__body(%Qubit*)
347 declare void @__quantum__qis__s__body(%Qubit*)
348 declare void @__quantum__qis__s__adj(%Qubit*)
349 declare void @__quantum__qis__t__body(%Qubit*)
350 declare void @__quantum__qis__t__adj(%Qubit*)
351 declare void @__quantum__qis__x__body(%Qubit*)
352 declare void @__quantum__qis__y__body(%Qubit*)
353 declare void @__quantum__qis__z__body(%Qubit*)
354 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
355 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
356 declare void @__quantum__rt__result_record_output(%Result*, i8*)
357 declare void @__quantum__rt__array_record_output(i64, i8*)
358 declare void @__quantum__rt__tuple_record_output(i64, i8*)
359
360 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="3" "required_num_results"="1" }
361 attributes #1 = { "irreversible" }
362
363 ; module flags
364
365 !llvm.module.flags = !{!0, !1, !2, !3}
366
367 !0 = !{i32 1, !"qir_major_version", i32 1}
368 !1 = !{i32 7, !"qir_minor_version", i32 0}
369 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
370 !3 = !{i32 1, !"dynamic_result_management", i1 false}
371 "#]],
372 );
373}
374
375#[test]
376fn reuse_after_measurement_uses_fresh_aux_qubit_id() {
377 check(
378 "",
379 Some(indoc! {"{use q = Qubit(); H(q); M(q); H(q); M(q)}"}),
380 &expect![[r#"
381 %Result = type opaque
382 %Qubit = type opaque
383
384 define void @ENTRYPOINT__main() #0 {
385 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
386 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
387 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
388 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 1 to %Qubit*))
389 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
390 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
391 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
392 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
393 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
394 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
395 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
396 ret void
397 }
398
399 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
400 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
401 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
402 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
403 declare void @__quantum__qis__rx__body(double, %Qubit*)
404 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
405 declare void @__quantum__qis__ry__body(double, %Qubit*)
406 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
407 declare void @__quantum__qis__rz__body(double, %Qubit*)
408 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
409 declare void @__quantum__qis__h__body(%Qubit*)
410 declare void @__quantum__qis__s__body(%Qubit*)
411 declare void @__quantum__qis__s__adj(%Qubit*)
412 declare void @__quantum__qis__t__body(%Qubit*)
413 declare void @__quantum__qis__t__adj(%Qubit*)
414 declare void @__quantum__qis__x__body(%Qubit*)
415 declare void @__quantum__qis__y__body(%Qubit*)
416 declare void @__quantum__qis__z__body(%Qubit*)
417 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
418 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
419 declare void @__quantum__rt__result_record_output(%Result*, i8*)
420 declare void @__quantum__rt__array_record_output(i64, i8*)
421 declare void @__quantum__rt__tuple_record_output(i64, i8*)
422
423 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="3" "required_num_results"="2" }
424 attributes #1 = { "irreversible" }
425
426 ; module flags
427
428 !llvm.module.flags = !{!0, !1, !2, !3}
429
430 !0 = !{i32 1, !"qir_major_version", i32 1}
431 !1 = !{i32 7, !"qir_minor_version", i32 0}
432 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
433 !3 = !{i32 1, !"dynamic_result_management", i1 false}
434 "#]],
435 );
436}
437
438#[test]
439fn qubit_allocation_allows_reuse_of_unmeasured_qubits() {
440 check(
441 "",
442 Some(indoc! {"{
443 { use (c, q) = (Qubit(), Qubit()); CNOT(c, q); MResetZ(q); }
444 { use (c, q) = (Qubit(), Qubit()); CNOT(c, q); MResetZ(q) }
445 }"}),
446 &expect![[r#"
447 %Result = type opaque
448 %Qubit = type opaque
449
450 define void @ENTRYPOINT__main() #0 {
451 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
452 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
453 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
454 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
455 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
456 ret void
457 }
458
459 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
460 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
461 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
462 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
463 declare void @__quantum__qis__rx__body(double, %Qubit*)
464 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
465 declare void @__quantum__qis__ry__body(double, %Qubit*)
466 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
467 declare void @__quantum__qis__rz__body(double, %Qubit*)
468 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
469 declare void @__quantum__qis__h__body(%Qubit*)
470 declare void @__quantum__qis__s__body(%Qubit*)
471 declare void @__quantum__qis__s__adj(%Qubit*)
472 declare void @__quantum__qis__t__body(%Qubit*)
473 declare void @__quantum__qis__t__adj(%Qubit*)
474 declare void @__quantum__qis__x__body(%Qubit*)
475 declare void @__quantum__qis__y__body(%Qubit*)
476 declare void @__quantum__qis__z__body(%Qubit*)
477 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
478 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
479 declare void @__quantum__rt__result_record_output(%Result*, i8*)
480 declare void @__quantum__rt__array_record_output(i64, i8*)
481 declare void @__quantum__rt__tuple_record_output(i64, i8*)
482
483 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="3" "required_num_results"="2" }
484 attributes #1 = { "irreversible" }
485
486 ; module flags
487
488 !llvm.module.flags = !{!0, !1, !2, !3}
489
490 !0 = !{i32 1, !"qir_major_version", i32 1}
491 !1 = !{i32 7, !"qir_minor_version", i32 0}
492 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
493 !3 = !{i32 1, !"dynamic_result_management", i1 false}
494 "#]],
495 );
496}
497
498#[test]
499fn verify_all_intrinsics() {
500 check(
501 "",
502 Some(indoc! {"{
503 use (q1, q2, q3) = (Qubit(), Qubit(), Qubit());
504 CCNOT(q1, q2, q3);
505 CX(q1, q2);
506 CY(q1, q2);
507 CZ(q1, q2);
508 Rx(0.0, q1);
509 Rxx(0.0, q1, q2);
510 Ry(0.0, q1);
511 Ryy(0.0, q1, q2);
512 Rz(0.0, q1);
513 Rzz(0.0, q1, q2);
514 H(q1);
515 S(q1);
516 Adjoint S(q1);
517 T(q1);
518 Adjoint T(q1);
519 X(q1);
520 Y(q1);
521 Z(q1);
522 SWAP(q1, q2);
523 Reset(q1);
524 (M(q1),
525 Microsoft.Quantum.Measurement.MResetZ(q1))
526 }"}),
527 &expect![[r#"
528 %Result = type opaque
529 %Qubit = type opaque
530
531 define void @ENTRYPOINT__main() #0 {
532 call void @__quantum__qis__ccx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
533 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
534 call void @__quantum__qis__cy__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
535 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
536 call void @__quantum__qis__rx__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
537 call void @__quantum__qis__rxx__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
538 call void @__quantum__qis__ry__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
539 call void @__quantum__qis__ryy__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
540 call void @__quantum__qis__rz__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*))
541 call void @__quantum__qis__rzz__body(double 0.0, %Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
542 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
543 call void @__quantum__qis__s__body(%Qubit* inttoptr (i64 0 to %Qubit*))
544 call void @__quantum__qis__s__adj(%Qubit* inttoptr (i64 0 to %Qubit*))
545 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 0 to %Qubit*))
546 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 0 to %Qubit*))
547 call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 0 to %Qubit*))
548 call void @__quantum__qis__y__body(%Qubit* inttoptr (i64 0 to %Qubit*))
549 call void @__quantum__qis__z__body(%Qubit* inttoptr (i64 0 to %Qubit*))
550 call void @__quantum__qis__swap__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
551 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 3 to %Qubit*))
552 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
553 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 3 to %Qubit*))
554 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
555 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 4 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
556 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
557 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
558 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
559 ret void
560 }
561
562 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
563 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
564 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
565 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
566 declare void @__quantum__qis__rx__body(double, %Qubit*)
567 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
568 declare void @__quantum__qis__ry__body(double, %Qubit*)
569 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
570 declare void @__quantum__qis__rz__body(double, %Qubit*)
571 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
572 declare void @__quantum__qis__h__body(%Qubit*)
573 declare void @__quantum__qis__s__body(%Qubit*)
574 declare void @__quantum__qis__s__adj(%Qubit*)
575 declare void @__quantum__qis__t__body(%Qubit*)
576 declare void @__quantum__qis__t__adj(%Qubit*)
577 declare void @__quantum__qis__x__body(%Qubit*)
578 declare void @__quantum__qis__y__body(%Qubit*)
579 declare void @__quantum__qis__z__body(%Qubit*)
580 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
581 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
582 declare void @__quantum__rt__result_record_output(%Result*, i8*)
583 declare void @__quantum__rt__array_record_output(i64, i8*)
584 declare void @__quantum__rt__tuple_record_output(i64, i8*)
585
586 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="5" "required_num_results"="2" }
587 attributes #1 = { "irreversible" }
588
589 ; module flags
590
591 !llvm.module.flags = !{!0, !1, !2, !3}
592
593 !0 = !{i32 1, !"qir_major_version", i32 1}
594 !1 = !{i32 7, !"qir_minor_version", i32 0}
595 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
596 !3 = !{i32 1, !"dynamic_result_management", i1 false}
597 "#]],
598 );
599}
600
601#[test]
602fn complex_program_is_valid() {
603 check(
604 "",
605 Some(indoc! {"{
606 open Microsoft.Quantum.Math;
607
608 operation SWAPfromExp(q1 : Qubit, q2 : Qubit) : Unit is Ctl + Adj {
609 let theta = PI() / 4.0;
610 Exp([PauliX, PauliX], theta, [q1, q2]);
611 Exp([PauliY, PauliY], theta, [q1, q2]);
612 Exp([PauliZ, PauliZ], theta, [q1, q2]);
613 }
614
615 use (aux, ctls, qs) = (Qubit(), Qubit[3], Qubit[2]);
616 within {
617 H(aux);
618 ApplyToEachA(CNOT(aux, _), ctls + qs);
619 }
620 apply {
621 Controlled SWAPfromExp(ctls, (qs[0], qs[1]));
622
623 Controlled Adjoint SWAP(ctls, (qs[0], qs[1]));
624 }
625
626 MResetEachZ([aux] + ctls + qs)
627 }"}),
628 &expect![[r#"
629 %Result = type opaque
630 %Qubit = type opaque
631
632 define void @ENTRYPOINT__main() #0 {
633 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
634 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
635 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
636 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
637 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
638 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
639 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
640 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
641 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
642 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
643 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
644 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
645 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
646 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
647 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
648 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
649 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
650 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
651 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
652 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
653 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
654 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 3 to %Qubit*))
655 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 7 to %Qubit*))
656 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
657 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
658 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
659 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
660 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
661 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
662 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 4 to %Qubit*))
663 call void @__quantum__qis__rz__body(double -0.7853981633974483, %Qubit* inttoptr (i64 4 to %Qubit*))
664 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
665 call void @__quantum__qis__rz__body(double 0.7853981633974483, %Qubit* inttoptr (i64 4 to %Qubit*))
666 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
667 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 4 to %Qubit*))
668 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
669 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
670 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
671 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
672 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
673 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
674 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 7 to %Qubit*))
675 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 3 to %Qubit*))
676 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
677 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
678 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
679 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
680 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
681 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
682 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
683 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
684 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
685 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
686 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 1 to %Qubit*))
687 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
688 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
689 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
690 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
691 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
692 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
693 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
694 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
695 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
696 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
697 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
698 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
699 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
700 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
701 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
702 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
703 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
704 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
705 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
706 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 3 to %Qubit*))
707 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 7 to %Qubit*))
708 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
709 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
710 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
711 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
712 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
713 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
714 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 4 to %Qubit*))
715 call void @__quantum__qis__s__body(%Qubit* inttoptr (i64 4 to %Qubit*))
716 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 4 to %Qubit*))
717 call void @__quantum__qis__rz__body(double -0.7853981633974483, %Qubit* inttoptr (i64 4 to %Qubit*))
718 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
719 call void @__quantum__qis__rz__body(double 0.7853981633974483, %Qubit* inttoptr (i64 4 to %Qubit*))
720 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
721 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 4 to %Qubit*))
722 call void @__quantum__qis__s__adj(%Qubit* inttoptr (i64 4 to %Qubit*))
723 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 4 to %Qubit*))
724 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
725 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
726 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
727 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
728 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
729 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
730 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 7 to %Qubit*))
731 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 3 to %Qubit*))
732 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
733 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
734 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
735 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
736 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
737 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
738 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
739 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
740 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
741 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
742 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 1 to %Qubit*))
743 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
744 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
745 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
746 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
747 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
748 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
749 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
750 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
751 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
752 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
753 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
754 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
755 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
756 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
757 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
758 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
759 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
760 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
761 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
762 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 3 to %Qubit*))
763 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 7 to %Qubit*))
764 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
765 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
766 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
767 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
768 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
769 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
770 call void @__quantum__qis__rz__body(double -0.7853981633974483, %Qubit* inttoptr (i64 4 to %Qubit*))
771 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
772 call void @__quantum__qis__rz__body(double 0.7853981633974483, %Qubit* inttoptr (i64 4 to %Qubit*))
773 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
774 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
775 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
776 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
777 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
778 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
779 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
780 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 7 to %Qubit*))
781 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 3 to %Qubit*))
782 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
783 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*))
784 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
785 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
786 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
787 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
788 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
789 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
790 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
791 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
792 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 1 to %Qubit*))
793 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
794 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
795 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
796 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
797 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 4 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
798 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
799 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
800 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
801 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
802 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 1 to %Qubit*))
803 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 6 to %Qubit*))
804 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
805 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
806 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
807 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
808 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
809 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
810 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
811 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
812 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 5 to %Qubit*))
813 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 3 to %Qubit*))
814 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 7 to %Qubit*))
815 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
816 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
817 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 5 to %Qubit*))
818 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
819 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
820 call void @__quantum__qis__ccx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
821 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
822 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
823 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 5 to %Qubit*))
824 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
825 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
826 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 7 to %Qubit*))
827 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 3 to %Qubit*))
828 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 5 to %Qubit*))
829 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
830 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
831 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
832 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
833 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
834 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 2 to %Qubit*))
835 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
836 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
837 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 6 to %Qubit*))
838 call void @__quantum__qis__t__body(%Qubit* inttoptr (i64 1 to %Qubit*))
839 call void @__quantum__qis__t__adj(%Qubit* inttoptr (i64 2 to %Qubit*))
840 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
841 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
842 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
843 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 4 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
844 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
845 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
846 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 3 to %Qubit*))
847 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 2 to %Qubit*))
848 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
849 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*))
850 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
851 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
852 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 2 to %Result*)) #1
853 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Result* inttoptr (i64 3 to %Result*)) #1
854 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 4 to %Qubit*), %Result* inttoptr (i64 4 to %Result*)) #1
855 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 5 to %Qubit*), %Result* inttoptr (i64 5 to %Result*)) #1
856 call void @__quantum__rt__array_record_output(i64 6, i8* null)
857 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
858 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
859 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 2 to %Result*), i8* null)
860 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 3 to %Result*), i8* null)
861 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 4 to %Result*), i8* null)
862 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 5 to %Result*), i8* null)
863 ret void
864 }
865
866 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
867 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
868 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
869 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
870 declare void @__quantum__qis__rx__body(double, %Qubit*)
871 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
872 declare void @__quantum__qis__ry__body(double, %Qubit*)
873 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
874 declare void @__quantum__qis__rz__body(double, %Qubit*)
875 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
876 declare void @__quantum__qis__h__body(%Qubit*)
877 declare void @__quantum__qis__s__body(%Qubit*)
878 declare void @__quantum__qis__s__adj(%Qubit*)
879 declare void @__quantum__qis__t__body(%Qubit*)
880 declare void @__quantum__qis__t__adj(%Qubit*)
881 declare void @__quantum__qis__x__body(%Qubit*)
882 declare void @__quantum__qis__y__body(%Qubit*)
883 declare void @__quantum__qis__z__body(%Qubit*)
884 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
885 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
886 declare void @__quantum__rt__result_record_output(%Result*, i8*)
887 declare void @__quantum__rt__array_record_output(i64, i8*)
888 declare void @__quantum__rt__tuple_record_output(i64, i8*)
889
890 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="8" "required_num_results"="6" }
891 attributes #1 = { "irreversible" }
892
893 ; module flags
894
895 !llvm.module.flags = !{!0, !1, !2, !3}
896
897 !0 = !{i32 1, !"qir_major_version", i32 1}
898 !1 = !{i32 7, !"qir_minor_version", i32 0}
899 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
900 !3 = !{i32 1, !"dynamic_result_management", i1 false}
901 "#]],
902 );
903}
904
905#[test]
906fn qubit_ids_properly_reused() {
907 check(
908 indoc! {"
909 namespace Test {
910
911 open Microsoft.Quantum.Intrinsic;
912
913 // Verifies the use of the CNOT quantum gate from Q#'s Microsoft.Quantum.Intrinsic namespace.
914 // Expected simulation output: ([0, 0], [1, 1]).
915 @EntryPoint()
916 operation IntrinsicCNOT() : (Result[], Result[]) {
917 use registerA = Qubit[2]; // |00⟩
918 CNOT(registerA[0], registerA[1]); // |00⟩
919 let resultsA = MeasureEachZ(registerA);
920 ResetAll(registerA);
921
922 use registerB = Qubit[2]; // |00⟩
923 X(registerB[0]); // |10⟩
924 CNOT(registerB[0], registerB[1]); // |11⟩
925 let resultsB = MeasureEachZ(registerB);
926 ResetAll(registerB);
927
928 return (resultsA, resultsB);
929 }
930 }
931 "},
932 None,
933 &expect![[r#"
934 %Result = type opaque
935 %Qubit = type opaque
936
937 define void @ENTRYPOINT__main() #0 {
938 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
939 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
940 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*))
941 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*))
942 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 3 to %Qubit*))
943 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
944 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 3 to %Qubit*))
945 call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 4 to %Qubit*))
946 call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 4 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
947 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
948 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Qubit* inttoptr (i64 4 to %Qubit*))
949 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 6 to %Qubit*))
950 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
951 call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Qubit* inttoptr (i64 5 to %Qubit*))
952 call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 7 to %Qubit*))
953 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
954 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
955 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 6 to %Qubit*), %Result* inttoptr (i64 2 to %Result*)) #1
956 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 7 to %Qubit*), %Result* inttoptr (i64 3 to %Result*)) #1
957 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
958 call void @__quantum__rt__array_record_output(i64 2, i8* null)
959 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
960 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
961 call void @__quantum__rt__array_record_output(i64 2, i8* null)
962 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 2 to %Result*), i8* null)
963 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 3 to %Result*), i8* null)
964 ret void
965 }
966
967 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
968 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
969 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
970 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
971 declare void @__quantum__qis__rx__body(double, %Qubit*)
972 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
973 declare void @__quantum__qis__ry__body(double, %Qubit*)
974 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
975 declare void @__quantum__qis__rz__body(double, %Qubit*)
976 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
977 declare void @__quantum__qis__h__body(%Qubit*)
978 declare void @__quantum__qis__s__body(%Qubit*)
979 declare void @__quantum__qis__s__adj(%Qubit*)
980 declare void @__quantum__qis__t__body(%Qubit*)
981 declare void @__quantum__qis__t__adj(%Qubit*)
982 declare void @__quantum__qis__x__body(%Qubit*)
983 declare void @__quantum__qis__y__body(%Qubit*)
984 declare void @__quantum__qis__z__body(%Qubit*)
985 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
986 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
987 declare void @__quantum__rt__result_record_output(%Result*, i8*)
988 declare void @__quantum__rt__array_record_output(i64, i8*)
989 declare void @__quantum__rt__tuple_record_output(i64, i8*)
990
991 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="8" "required_num_results"="4" }
992 attributes #1 = { "irreversible" }
993
994 ; module flags
995
996 !llvm.module.flags = !{!0, !1, !2, !3}
997
998 !0 = !{i32 1, !"qir_major_version", i32 1}
999 !1 = !{i32 7, !"qir_minor_version", i32 0}
1000 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1001 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1002 "#]],
1003 );
1004}
1005
1006#[test]
1007fn custom_intrinsic_on_single_qubit() {
1008 check(
1009 indoc! {"
1010 namespace Test {
1011 @EntryPoint()
1012 operation Test() : (Result, Result) {
1013 use (q1, q2) = (Qubit(), Qubit());
1014 MyCustomGate(q1);
1015 MyCustomGate(q2);
1016 return (MResetZ(q1), MResetZ(q2));
1017 }
1018
1019 operation MyCustomGate(q : Qubit) : Unit {
1020 body intrinsic;
1021 }
1022 }
1023 "},
1024 None,
1025 &expect![[r#"
1026 %Result = type opaque
1027 %Qubit = type opaque
1028
1029 define void @ENTRYPOINT__main() #0 {
1030 call void @MyCustomGate(%Qubit* inttoptr (i64 0 to %Qubit*))
1031 call void @MyCustomGate(%Qubit* inttoptr (i64 1 to %Qubit*))
1032 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
1033 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
1034 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
1035 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1036 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
1037 ret void
1038 }
1039
1040 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1041 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1042 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1043 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1044 declare void @__quantum__qis__rx__body(double, %Qubit*)
1045 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
1046 declare void @__quantum__qis__ry__body(double, %Qubit*)
1047 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
1048 declare void @__quantum__qis__rz__body(double, %Qubit*)
1049 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1050 declare void @__quantum__qis__h__body(%Qubit*)
1051 declare void @__quantum__qis__s__body(%Qubit*)
1052 declare void @__quantum__qis__s__adj(%Qubit*)
1053 declare void @__quantum__qis__t__body(%Qubit*)
1054 declare void @__quantum__qis__t__adj(%Qubit*)
1055 declare void @__quantum__qis__x__body(%Qubit*)
1056 declare void @__quantum__qis__y__body(%Qubit*)
1057 declare void @__quantum__qis__z__body(%Qubit*)
1058 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1059 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
1060 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1061 declare void @__quantum__rt__array_record_output(i64, i8*)
1062 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1063 declare void @MyCustomGate(%Qubit*)
1064
1065 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="2" }
1066 attributes #1 = { "irreversible" }
1067
1068 ; module flags
1069
1070 !llvm.module.flags = !{!0, !1, !2, !3}
1071
1072 !0 = !{i32 1, !"qir_major_version", i32 1}
1073 !1 = !{i32 7, !"qir_minor_version", i32 0}
1074 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1075 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1076 "#]],
1077 );
1078}
1079
1080#[test]
1081fn multiple_custom_intrinsic_calls() {
1082 check(
1083 indoc! {"
1084 namespace Test {
1085 @EntryPoint()
1086 operation Test() : (Result, Result) {
1087 use (q0, q1) = (Qubit(), Qubit());
1088 MySecondCustomGate(q0, q1);
1089 MyCustomGate(q0);
1090 MyCustomFunc(42);
1091 return (MResetZ(q0), MResetZ(q1));
1092 }
1093
1094 operation MyCustomGate(q : Qubit) : Unit {
1095 body intrinsic;
1096 }
1097
1098 operation MySecondCustomGate(q0 : Qubit, q1 : Qubit) : Unit {
1099 body intrinsic;
1100 }
1101
1102 function MyCustomFunc(n : Int) : Unit {
1103 body intrinsic;
1104 }
1105 }
1106 "},
1107 None,
1108 &expect![[r#"
1109 %Result = type opaque
1110 %Qubit = type opaque
1111
1112 define void @ENTRYPOINT__main() #0 {
1113 call void @MySecondCustomGate(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*))
1114 call void @MyCustomGate(%Qubit* inttoptr (i64 0 to %Qubit*))
1115 call void @MyCustomFunc(i64 42)
1116 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
1117 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1
1118 call void @__quantum__rt__tuple_record_output(i64 2, i8* null)
1119 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1120 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null)
1121 ret void
1122 }
1123
1124 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1125 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1126 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1127 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1128 declare void @__quantum__qis__rx__body(double, %Qubit*)
1129 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
1130 declare void @__quantum__qis__ry__body(double, %Qubit*)
1131 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
1132 declare void @__quantum__qis__rz__body(double, %Qubit*)
1133 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1134 declare void @__quantum__qis__h__body(%Qubit*)
1135 declare void @__quantum__qis__s__body(%Qubit*)
1136 declare void @__quantum__qis__s__adj(%Qubit*)
1137 declare void @__quantum__qis__t__body(%Qubit*)
1138 declare void @__quantum__qis__t__adj(%Qubit*)
1139 declare void @__quantum__qis__x__body(%Qubit*)
1140 declare void @__quantum__qis__y__body(%Qubit*)
1141 declare void @__quantum__qis__z__body(%Qubit*)
1142 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1143 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
1144 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1145 declare void @__quantum__rt__array_record_output(i64, i8*)
1146 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1147 declare void @MySecondCustomGate(%Qubit*, %Qubit*)
1148 declare void @MyCustomGate(%Qubit*)
1149 declare void @MyCustomFunc(i64)
1150
1151 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="2" "required_num_results"="2" }
1152 attributes #1 = { "irreversible" }
1153
1154 ; module flags
1155
1156 !llvm.module.flags = !{!0, !1, !2, !3}
1157
1158 !0 = !{i32 1, !"qir_major_version", i32 1}
1159 !1 = !{i32 7, !"qir_minor_version", i32 0}
1160 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1161 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1162 "#]],
1163 );
1164}
1165
1166#[test]
1167fn custom_intrinsic_on_qubit_and_double() {
1168 check(
1169 indoc! {"
1170 namespace Test {
1171 @EntryPoint()
1172 operation Test() : Result {
1173 use q = Qubit();
1174 let d = 3.14;
1175 MyCustomGate(q, d);
1176 return MResetZ(q);
1177 }
1178
1179 operation MyCustomGate(q : Qubit, d : Double) : Unit {
1180 body intrinsic;
1181 }
1182 }
1183 "},
1184 None,
1185 &expect![[r#"
1186 %Result = type opaque
1187 %Qubit = type opaque
1188
1189 define void @ENTRYPOINT__main() #0 {
1190 call void @MyCustomGate(%Qubit* inttoptr (i64 0 to %Qubit*), double 3.14)
1191 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
1192 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1193 ret void
1194 }
1195
1196 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1197 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1198 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1199 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1200 declare void @__quantum__qis__rx__body(double, %Qubit*)
1201 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
1202 declare void @__quantum__qis__ry__body(double, %Qubit*)
1203 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
1204 declare void @__quantum__qis__rz__body(double, %Qubit*)
1205 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1206 declare void @__quantum__qis__h__body(%Qubit*)
1207 declare void @__quantum__qis__s__body(%Qubit*)
1208 declare void @__quantum__qis__s__adj(%Qubit*)
1209 declare void @__quantum__qis__t__body(%Qubit*)
1210 declare void @__quantum__qis__t__adj(%Qubit*)
1211 declare void @__quantum__qis__x__body(%Qubit*)
1212 declare void @__quantum__qis__y__body(%Qubit*)
1213 declare void @__quantum__qis__z__body(%Qubit*)
1214 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1215 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
1216 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1217 declare void @__quantum__rt__array_record_output(i64, i8*)
1218 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1219 declare void @MyCustomGate(%Qubit*, double)
1220
1221 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="1" "required_num_results"="1" }
1222 attributes #1 = { "irreversible" }
1223
1224 ; module flags
1225
1226 !llvm.module.flags = !{!0, !1, !2, !3}
1227
1228 !0 = !{i32 1, !"qir_major_version", i32 1}
1229 !1 = !{i32 7, !"qir_minor_version", i32 0}
1230 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1231 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1232 "#]],
1233 );
1234}
1235
1236#[test]
1237fn custom_intrinsic_on_qubit_and_bool() {
1238 check(
1239 indoc! {"
1240 namespace Test {
1241 @EntryPoint()
1242 operation Test() : Result {
1243 use q = Qubit();
1244 let b = true;
1245 MyCustomGate(q, b);
1246 return MResetZ(q);
1247 }
1248
1249 operation MyCustomGate(q : Qubit, b : Bool) : Unit {
1250 body intrinsic;
1251 }
1252 }
1253 "},
1254 None,
1255 &expect![[r#"
1256 %Result = type opaque
1257 %Qubit = type opaque
1258
1259 define void @ENTRYPOINT__main() #0 {
1260 call void @MyCustomGate(%Qubit* inttoptr (i64 0 to %Qubit*), i1 true)
1261 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
1262 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1263 ret void
1264 }
1265
1266 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1267 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1268 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1269 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1270 declare void @__quantum__qis__rx__body(double, %Qubit*)
1271 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
1272 declare void @__quantum__qis__ry__body(double, %Qubit*)
1273 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
1274 declare void @__quantum__qis__rz__body(double, %Qubit*)
1275 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1276 declare void @__quantum__qis__h__body(%Qubit*)
1277 declare void @__quantum__qis__s__body(%Qubit*)
1278 declare void @__quantum__qis__s__adj(%Qubit*)
1279 declare void @__quantum__qis__t__body(%Qubit*)
1280 declare void @__quantum__qis__t__adj(%Qubit*)
1281 declare void @__quantum__qis__x__body(%Qubit*)
1282 declare void @__quantum__qis__y__body(%Qubit*)
1283 declare void @__quantum__qis__z__body(%Qubit*)
1284 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1285 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
1286 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1287 declare void @__quantum__rt__array_record_output(i64, i8*)
1288 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1289 declare void @MyCustomGate(%Qubit*, i1)
1290
1291 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="1" "required_num_results"="1" }
1292 attributes #1 = { "irreversible" }
1293
1294 ; module flags
1295
1296 !llvm.module.flags = !{!0, !1, !2, !3}
1297
1298 !0 = !{i32 1, !"qir_major_version", i32 1}
1299 !1 = !{i32 7, !"qir_minor_version", i32 0}
1300 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1301 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1302 "#]],
1303 );
1304}
1305
1306#[test]
1307fn custom_intrinsic_on_qubit_and_int() {
1308 check(
1309 indoc! {"
1310 namespace Test {
1311 @EntryPoint()
1312 operation Test() : Result {
1313 use q = Qubit();
1314 let i = 42;
1315 MyCustomGate(q, i);
1316 return MResetZ(q);
1317 }
1318
1319 operation MyCustomGate(q : Qubit, i : Int) : Unit {
1320 body intrinsic;
1321 }
1322 }
1323 "},
1324 None,
1325 &expect![[r#"
1326 %Result = type opaque
1327 %Qubit = type opaque
1328
1329 define void @ENTRYPOINT__main() #0 {
1330 call void @MyCustomGate(%Qubit* inttoptr (i64 0 to %Qubit*), i64 42)
1331 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
1332 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1333 ret void
1334 }
1335
1336 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1337 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1338 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1339 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1340 declare void @__quantum__qis__rx__body(double, %Qubit*)
1341 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
1342 declare void @__quantum__qis__ry__body(double, %Qubit*)
1343 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
1344 declare void @__quantum__qis__rz__body(double, %Qubit*)
1345 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1346 declare void @__quantum__qis__h__body(%Qubit*)
1347 declare void @__quantum__qis__s__body(%Qubit*)
1348 declare void @__quantum__qis__s__adj(%Qubit*)
1349 declare void @__quantum__qis__t__body(%Qubit*)
1350 declare void @__quantum__qis__t__adj(%Qubit*)
1351 declare void @__quantum__qis__x__body(%Qubit*)
1352 declare void @__quantum__qis__y__body(%Qubit*)
1353 declare void @__quantum__qis__z__body(%Qubit*)
1354 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1355 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
1356 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1357 declare void @__quantum__rt__array_record_output(i64, i8*)
1358 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1359 declare void @MyCustomGate(%Qubit*, i64)
1360
1361 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="1" "required_num_results"="1" }
1362 attributes #1 = { "irreversible" }
1363
1364 ; module flags
1365
1366 !llvm.module.flags = !{!0, !1, !2, !3}
1367
1368 !0 = !{i32 1, !"qir_major_version", i32 1}
1369 !1 = !{i32 7, !"qir_minor_version", i32 0}
1370 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1371 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1372 "#]],
1373 );
1374}
1375
1376#[test]
1377fn custom_intrinsic_fail_on_result_arg() {
1378 check(
1379 indoc! {"
1380 namespace Test {
1381 @EntryPoint()
1382 operation Test() : Result {
1383 use q = Qubit();
1384 let r = MResetZ(q);
1385 MyCustomGate(q, r);
1386 return r;
1387 }
1388
1389 operation MyCustomGate(q : Qubit, r : Result) : Unit {
1390 body intrinsic;
1391 }
1392 }
1393 "},
1394 None,
1395 &expect![[r#"
1396 IntrinsicFail(
1397 "MyCustomGate",
1398 "unsupported argument type: Result",
1399 PackageSpan {
1400 package: PackageId(
1401 2,
1402 ),
1403 span: Span {
1404 lo: 177,
1405 hi: 261,
1406 },
1407 },
1408 )
1409 "#]],
1410 );
1411}
1412
1413#[test]
1414fn custom_intrinsic_fail_on_bigint_arg() {
1415 check(
1416 indoc! {"
1417 namespace Test {
1418 @EntryPoint()
1419 operation Test() : Result {
1420 use q = Qubit();
1421 let i = 42L;
1422 MyCustomGate(q, i);
1423 return MResetZ(q);
1424 }
1425
1426 operation MyCustomGate(q : Qubit, i : BigInt) : Unit {
1427 body intrinsic;
1428 }
1429 }
1430 "},
1431 None,
1432 &expect![[r#"
1433 IntrinsicFail(
1434 "MyCustomGate",
1435 "unsupported argument type: BigInt",
1436 PackageSpan {
1437 package: PackageId(
1438 2,
1439 ),
1440 span: Span {
1441 lo: 179,
1442 hi: 263,
1443 },
1444 },
1445 )
1446 "#]],
1447 );
1448}
1449
1450#[test]
1451fn custom_intrinsic_fail_on_string_arg() {
1452 check(
1453 indoc! {r#"
1454 namespace Test {
1455 @EntryPoint()
1456 operation Test() : Result {
1457 use q = Qubit();
1458 let s = "hello, world";
1459 MyCustomGate(q, s);
1460 return MResetZ(q);
1461 }
1462
1463 operation MyCustomGate(q : Qubit, s : String) : Unit {
1464 body intrinsic;
1465 }
1466 }
1467 "#},
1468 None,
1469 &expect![[r#"
1470 IntrinsicFail(
1471 "MyCustomGate",
1472 "unsupported argument type: String",
1473 PackageSpan {
1474 package: PackageId(
1475 2,
1476 ),
1477 span: Span {
1478 lo: 190,
1479 hi: 274,
1480 },
1481 },
1482 )
1483 "#]],
1484 );
1485}
1486
1487#[test]
1488fn custom_intrinsic_fail_on_array_arg() {
1489 check(
1490 indoc! {"
1491 namespace Test {
1492 @EntryPoint()
1493 operation Test() : Result {
1494 use q = Qubit();
1495 let a = [1, 2, 3];
1496 MyCustomGate(q, a);
1497 return MResetZ(q);
1498 }
1499
1500 operation MyCustomGate(q : Qubit, a : Int[]) : Unit {
1501 body intrinsic;
1502 }
1503 }
1504 "},
1505 None,
1506 &expect![[r#"
1507 IntrinsicFail(
1508 "MyCustomGate",
1509 "unsupported argument type: Array",
1510 PackageSpan {
1511 package: PackageId(
1512 2,
1513 ),
1514 span: Span {
1515 lo: 185,
1516 hi: 268,
1517 },
1518 },
1519 )
1520 "#]],
1521 );
1522}
1523
1524#[test]
1525fn custom_intrinsic_fail_on_tuple_arg() {
1526 check(
1527 indoc! {"
1528 namespace Test {
1529 @EntryPoint()
1530 operation Test() : Result {
1531 use q = Qubit();
1532 let t = (1, 2, 3);
1533 MyCustomGate(q, t);
1534 return MResetZ(q);
1535 }
1536
1537 operation MyCustomGate(q : Qubit, t : (Int, Int, Int)) : Unit {
1538 body intrinsic;
1539 }
1540 }
1541 "},
1542 None,
1543 &expect![[r#"
1544 IntrinsicFail(
1545 "MyCustomGate",
1546 "unsupported argument type: Tuple",
1547 PackageSpan {
1548 package: PackageId(
1549 2,
1550 ),
1551 span: Span {
1552 lo: 185,
1553 hi: 278,
1554 },
1555 },
1556 )
1557 "#]],
1558 );
1559}
1560
1561#[test]
1562fn custom_intrinsic_fail_on_non_unit_return() {
1563 check(
1564 indoc! {"
1565 namespace Test {
1566 @EntryPoint()
1567 operation Test() : Result {
1568 use q = Qubit();
1569 MyCustomGate(q);
1570 return MResetZ(q);
1571 }
1572
1573 function MyCustomGate(q : Qubit) : Int {
1574 body intrinsic;
1575 }
1576 }
1577 "},
1578 None,
1579 &expect![[r#"
1580 UnsupportedIntrinsicType(
1581 "MyCustomGate",
1582 PackageSpan {
1583 package: PackageId(
1584 2,
1585 ),
1586 span: Span {
1587 lo: 155,
1588 hi: 225,
1589 },
1590 },
1591 )
1592 "#]],
1593 );
1594}
1595
1596#[test]
1597fn pauli_i_rotation_for_global_phase_is_noop() {
1598 check(
1599 indoc! {"
1600 namespace Test {
1601 @EntryPoint()
1602 operation Test() : Result {
1603 use q = Qubit();
1604 R(PauliI, 1.0, q);
1605 return MResetZ(q);
1606 }
1607 }
1608 "},
1609 None,
1610 &expect![[r#"
1611 %Result = type opaque
1612 %Qubit = type opaque
1613
1614 define void @ENTRYPOINT__main() #0 {
1615 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1
1616 call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null)
1617 ret void
1618 }
1619
1620 declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*)
1621 declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*)
1622 declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*)
1623 declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*)
1624 declare void @__quantum__qis__rx__body(double, %Qubit*)
1625 declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*)
1626 declare void @__quantum__qis__ry__body(double, %Qubit*)
1627 declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*)
1628 declare void @__quantum__qis__rz__body(double, %Qubit*)
1629 declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*)
1630 declare void @__quantum__qis__h__body(%Qubit*)
1631 declare void @__quantum__qis__s__body(%Qubit*)
1632 declare void @__quantum__qis__s__adj(%Qubit*)
1633 declare void @__quantum__qis__t__body(%Qubit*)
1634 declare void @__quantum__qis__t__adj(%Qubit*)
1635 declare void @__quantum__qis__x__body(%Qubit*)
1636 declare void @__quantum__qis__y__body(%Qubit*)
1637 declare void @__quantum__qis__z__body(%Qubit*)
1638 declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*)
1639 declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1
1640 declare void @__quantum__rt__result_record_output(%Result*, i8*)
1641 declare void @__quantum__rt__array_record_output(i64, i8*)
1642 declare void @__quantum__rt__tuple_record_output(i64, i8*)
1643
1644 attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="1" "required_num_results"="1" }
1645 attributes #1 = { "irreversible" }
1646
1647 ; module flags
1648
1649 !llvm.module.flags = !{!0, !1, !2, !3}
1650
1651 !0 = !{i32 1, !"qir_major_version", i32 1}
1652 !1 = !{i32 7, !"qir_minor_version", i32 0}
1653 !2 = !{i32 1, !"dynamic_qubit_management", i1 false}
1654 !3 = !{i32 1, !"dynamic_result_management", i1 false}
1655 "#]],
1656 );
1657}
1658