From ba1ae5f4a593596fc0232985c9b364bae27a4711 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Wed, 24 Jun 2026 14:17:08 -0700 Subject: [PATCH] Allow for constant Result arrays in Adaptive Profile This change updates the data types in RIR to allow for variables of type Result to be used in the Adaptive Profile. This makes it possible to emit constant arrays of result identifiers into the data section of the generated QIR the same way arrays of qubit identifiers are supported. This also updates how Result literals are handled, allowing for their emission into RIR by transforming `Zero` and `One` into a extra result ids during QIR codegen that are initialized via a proposed `__quantum__rt__write_result` API (see https://github.com/qir-alliance/qir-spec/issues/65). --- .../qsc/src/codegen/tests/adaptive_profile.rs | 182 +++++++++++------- source/compiler/qsc_codegen/src/qir/v1.rs | 9 + source/compiler/qsc_codegen/src/qir/v2.rs | 3 + source/compiler/qsc_eval/src/val.rs | 2 + .../src/tests/statement/gate_call.rs | 138 ++++++------- source/compiler/qsc_partial_eval/src/lib.rs | 49 +++-- .../qsc_partial_eval/src/tests/assigns.rs | 29 ++- .../qsc_partial_eval/src/tests/bindings.rs | 1 + .../qsc_partial_eval/src/tests/branching.rs | 30 ++- source/compiler/qsc_rca/src/lib.rs | 2 +- source/compiler/qsc_rir/src/builder.rs | 12 ++ source/compiler/qsc_rir/src/passes.rs | 5 +- .../qsc_rir/src/passes/result_literal.rs | 133 +++++++++++++ source/compiler/qsc_rir/src/rir.rs | 11 +- .../adaptive/output/ArithmeticOps.ll | 173 ++++++----------- .../adaptive/output/ExpandedTests.ll | 20 +- .../resources/adaptive/output/RandomBit.ll | 8 +- .../adaptive/output/SampleTeleport.ll | 58 +++--- .../adaptive/output/SwitchHandling.ll | 172 +++++++++-------- .../adaptive_ri/output/SampleTeleport.ll | 8 +- .../adaptive_ri/output/SwitchHandling.ll | 28 +-- source/samples_test/src/tests/OpenQASM.rs | 2 +- source/samples_test/src/tests/algorithms.rs | 14 +- 23 files changed, 662 insertions(+), 427 deletions(-) create mode 100644 source/compiler/qsc_rir/src/passes/result_literal.rs diff --git a/source/compiler/qsc/src/codegen/tests/adaptive_profile.rs b/source/compiler/qsc/src/codegen/tests/adaptive_profile.rs index 20a713c144b..7c94aca0f37 100644 --- a/source/compiler/qsc/src/codegen/tests/adaptive_profile.rs +++ b/source/compiler/qsc/src/codegen/tests/adaptive_profile.rs @@ -5,7 +5,6 @@ use expect_test::expect; use qsc_data_structures::target::{Profile, TargetCapabilityFlags}; use super::compile_source_to_qir; -use super::compile_source_to_qir_result; use super::compile_source_to_qir_with_library; use super::compile_source_to_rir; @@ -510,51 +509,52 @@ fn result_array_dynamic_index_succeeds() { let qir = compile_source_to_qir(source, *CAPABILITIES); expect![[r#" @0 = internal constant [4 x i8] c"0_i\00" + @array0 = internal constant [4 x ptr] [ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 3 to ptr)] define i64 @ENTRYPOINT__main() #0 { block_0: %var_2 = alloca i64 + %var_3 = alloca i64 + %var_5 = alloca i1 call void @__quantum__rt__initialize(ptr null) call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 0 to ptr)) call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 1 to ptr)) call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 2 to ptr)) call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 3 to ptr), ptr inttoptr (i64 3 to ptr)) store i64 0, ptr %var_2 - %var_4 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) - br i1 %var_4, label %block_1, label %block_2 + store i64 0, ptr %var_3 + br label %block_1 block_1: - %var_24 = load i64, ptr %var_2 - %var_6 = add i64 %var_24, 1 - store i64 %var_6, ptr %var_2 - br label %block_2 + %var_13 = load i64, ptr %var_3 + %var_4 = icmp sle i64 %var_13, 3 + store i1 true, ptr %var_5 + br i1 %var_4, label %block_2, label %block_3 block_2: - %var_7 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 1 to ptr)) - br i1 %var_7, label %block_3, label %block_4 + %var_16 = load i1, ptr %var_5 + br i1 %var_16, label %block_4, label %block_5 block_3: - %var_22 = load i64, ptr %var_2 - %var_9 = add i64 %var_22, 1 - store i64 %var_9, ptr %var_2 - br label %block_4 + store i1 false, ptr %var_5 + br label %block_2 block_4: - %var_10 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 2 to ptr)) - br i1 %var_10, label %block_5, label %block_6 + %var_18 = load i64, ptr %var_3 + %var_6 = getelementptr ptr, ptr @array0, i64 %var_18 + %var_19 = load ptr, ptr %var_6 + %var_7 = call i1 @__quantum__rt__read_result(ptr %var_19) + br i1 %var_7, label %block_6, label %block_7 block_5: - %var_20 = load i64, ptr %var_2 - %var_12 = add i64 %var_20, 1 - store i64 %var_12, ptr %var_2 - br label %block_6 - block_6: - %var_13 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 3 to ptr)) - br i1 %var_13, label %block_7, label %block_8 - block_7: - %var_18 = load i64, ptr %var_2 - %var_15 = add i64 %var_18, 1 - store i64 %var_15, ptr %var_2 - br label %block_8 - block_8: %var_17 = load i64, ptr %var_2 call void @__quantum__rt__int_record_output(i64 %var_17, ptr @0) ret i64 0 + block_6: + %var_22 = load i64, ptr %var_2 + %var_9 = add i64 %var_22, 1 + store i64 %var_9, ptr %var_2 + br label %block_7 + block_7: + %var_20 = load i64, ptr %var_3 + %var_10 = add i64 %var_20, 1 + store i64 %var_10, ptr %var_3 + br label %block_1 } declare void @__quantum__rt__initialize(ptr) @@ -613,10 +613,12 @@ fn result_array_while_loop_dynamic_index_succeeds() { let qir = compile_source_to_qir(source, *CAPABILITIES); expect![[r#" @0 = internal constant [4 x i8] c"0_i\00" + @array0 = internal constant [4 x ptr] [ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 3 to ptr)] define i64 @ENTRYPOINT__main() #0 { block_0: %var_2 = alloca i64 + %var_3 = alloca i64 call void @__quantum__rt__initialize(ptr null) call void @H(ptr inttoptr (i64 0 to ptr)) call void @H(ptr inttoptr (i64 1 to ptr)) @@ -627,47 +629,38 @@ fn result_array_while_loop_dynamic_index_succeeds() { call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 2 to ptr)) call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 3 to ptr), ptr inttoptr (i64 3 to ptr)) store i64 0, ptr %var_2 - %var_4 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) - br i1 %var_4, label %block_1, label %block_2 + store i64 0, ptr %var_3 + br label %block_1 block_1: - %var_24 = load i64, ptr %var_2 - %var_6 = add i64 %var_24, 1 - store i64 %var_6, ptr %var_2 - br label %block_2 + %var_12 = load i64, ptr %var_3 + %var_4 = icmp slt i64 %var_12, 4 + br i1 %var_4, label %block_2, label %block_3 block_2: - %var_7 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 1 to ptr)) - br i1 %var_7, label %block_3, label %block_4 + %var_14 = load i64, ptr %var_3 + %var_5 = getelementptr ptr, ptr @array0, i64 %var_14 + %var_15 = load ptr, ptr %var_5 + %var_6 = call i1 @__quantum__rt__read_result(ptr %var_15) + br i1 %var_6, label %block_4, label %block_5 block_3: - %var_22 = load i64, ptr %var_2 - %var_9 = add i64 %var_22, 1 - store i64 %var_9, ptr %var_2 - br label %block_4 + %var_13 = load i64, ptr %var_2 + call void @__quantum__rt__int_record_output(i64 %var_13, ptr @0) + ret i64 0 block_4: - %var_10 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 2 to ptr)) - br i1 %var_10, label %block_5, label %block_6 - block_5: - %var_20 = load i64, ptr %var_2 - %var_12 = add i64 %var_20, 1 - store i64 %var_12, ptr %var_2 - br label %block_6 - block_6: - %var_13 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 3 to ptr)) - br i1 %var_13, label %block_7, label %block_8 - block_7: %var_18 = load i64, ptr %var_2 - %var_15 = add i64 %var_18, 1 - store i64 %var_15, ptr %var_2 - br label %block_8 - block_8: - %var_17 = load i64, ptr %var_2 - call void @__quantum__rt__int_record_output(i64 %var_17, ptr @0) - ret i64 0 + %var_8 = add i64 %var_18, 1 + store i64 %var_8, ptr %var_2 + br label %block_5 + block_5: + %var_16 = load i64, ptr %var_3 + %var_9 = add i64 %var_16, 1 + store i64 %var_9, ptr %var_3 + br label %block_1 } declare void @__quantum__rt__initialize(ptr) define void @H(ptr %var_1) { - block_9: + block_6: call void @__quantum__qis__h__body(ptr %var_1) ret void } @@ -701,9 +694,6 @@ fn result_array_while_loop_dynamic_index_succeeds() { } #[test] -#[should_panic( - expected = "CapabilitiesCk(UseOfDynamicResult) — mutable Result re-measurement requires UseOfDynamicResult, not in Adaptive profile" -)] fn mutable_result_variable_succeeds() { let source = "namespace Test { import Std.Intrinsic.*; @@ -719,9 +709,71 @@ fn mutable_result_variable_succeeds() { r } }"; - let qir = compile_source_to_qir_result(source, *CAPABILITIES) - .expect("CapabilitiesCk(UseOfDynamicResult) — mutable Result re-measurement requires UseOfDynamicResult, not in Adaptive profile"); - assert!(qir.contains("@ENTRYPOINT__main")); + let qir = compile_source_to_qir(source, *CAPABILITIES); + expect![[r#" + @0 = internal constant [4 x i8] c"0_r\00" + + define i64 @ENTRYPOINT__main() #0 { + block_0: + %var_1 = alloca ptr + call void @__quantum__rt__initialize(ptr null) + call void @H(ptr inttoptr (i64 0 to ptr)) + call void @__quantum__qis__m__body(ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 0 to ptr)) + store ptr 0, ptr %var_1 + %var_2 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) + br i1 %var_2, label %block_1, label %block_2 + block_1: + call void @X(ptr inttoptr (i64 0 to ptr)) + call void @__quantum__qis__m__body(ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr)) + store ptr 1, ptr %var_1 + br label %block_2 + block_2: + %var_4 = load ptr, ptr %var_1 + call void @__quantum__rt__result_record_output(ptr %var_4, ptr @0) + ret i64 0 + } + + declare void @__quantum__rt__initialize(ptr) + + define void @H(ptr %var_0) { + block_3: + call void @__quantum__qis__h__body(ptr %var_0) + ret void + } + + declare void @__quantum__qis__h__body(ptr) + + declare void @__quantum__qis__m__body(ptr, ptr) #1 + + declare i1 @__quantum__rt__read_result(ptr) + + define void @X(ptr %var_4) { + block_4: + call void @__quantum__qis__x__body(ptr %var_4) + ret void + } + + declare void @__quantum__qis__x__body(ptr) + + declare void @__quantum__rt__result_record_output(ptr, ptr) + + attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="adaptive_profile" "required_num_qubits"="1" "required_num_results"="2" } + attributes #1 = { "irreversible" } + + ; module flags + + !llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} + + !0 = !{i32 1, !"qir_major_version", i32 2} + !1 = !{i32 7, !"qir_minor_version", i32 1} + !2 = !{i32 1, !"dynamic_qubit_management", i1 false} + !3 = !{i32 1, !"dynamic_result_management", i1 false} + !4 = !{i32 5, !"int_computations", !{!"i64"}} + !5 = !{i32 5, !"float_computations", !{!"double"}} + !6 = !{i32 7, !"backwards_branching", i2 3} + !7 = !{i32 1, !"arrays", i1 true} + !8 = !{i32 1, !"ir_functions", i1 true} + "#]].assert_eq(&qir); } #[test] diff --git a/source/compiler/qsc_codegen/src/qir/v1.rs b/source/compiler/qsc_codegen/src/qir/v1.rs index 528424c1143..e760bbc250d 100644 --- a/source/compiler/qsc_codegen/src/qir/v1.rs +++ b/source/compiler/qsc_codegen/src/qir/v1.rs @@ -48,6 +48,9 @@ impl ToQir for rir::Literal { rir::Literal::Array(_) => { panic!("array literals are not supported in QIR v1 generation") } + rir::Literal::ResultLit(..) => { + panic!("result literal values are not supported in QIR v1 generation") + } } } } @@ -546,6 +549,9 @@ fn get_value_as_str(value: &rir::Operand, program: &rir::Program) -> String { rir::Literal::Array(..) => { panic!("array literals are not supported in QIR v1 generation") } + rir::Literal::ResultLit(..) => { + panic!("result literal values are not supported in QIR v1 generation") + } }, rir::Operand::Variable(var) => ToQir::::to_qir(&var.variable_id, program), } @@ -563,6 +569,9 @@ fn get_value_ty(lhs: &rir::Operand) -> &str { rir::Literal::Array(_) => { panic!("array literals are not supported in QIR v1 generation") } + rir::Literal::ResultLit(..) => { + panic!("result literal values are not supported in QIR v1 generation") + } }, rir::Operand::Variable(var) => get_variable_ty(*var), } diff --git a/source/compiler/qsc_codegen/src/qir/v2.rs b/source/compiler/qsc_codegen/src/qir/v2.rs index f9f1a77f4c6..19b6dcdb65b 100644 --- a/source/compiler/qsc_codegen/src/qir/v2.rs +++ b/source/compiler/qsc_codegen/src/qir/v2.rs @@ -42,6 +42,7 @@ impl ToQir for rir::Literal { rir::Literal::Result(r) => format!("ptr inttoptr (i64 {r} to ptr)"), rir::Literal::Tag(idx, _) => format!("ptr @{idx}"), rir::Literal::Array(idx) => format!("ptr @array{idx}"), + rir::Literal::ResultLit(..) => panic!("Result literals are not supported in QIR"), } } } @@ -559,6 +560,7 @@ fn get_value_as_str(value: &rir::Operand, program: &rir::Program) -> String { rir::Literal::Array(idx) => { format!("@array{idx}") } + rir::Literal::ResultLit(..) => panic!("Result literals are not supported in QIR"), rir::Literal::Tag(..) => panic!( "tag literals should not be used as string values outside of output recording" ), @@ -575,6 +577,7 @@ fn get_value_ty(lhs: &rir::Operand) -> String { rir::Literal::Double(_) => get_f64_ty(), rir::Literal::Qubit(_) | rir::Literal::Result(_) + | rir::Literal::ResultLit(..) | rir::Literal::NullPointer | rir::Literal::Tag(..) | rir::Literal::Array(_) => "ptr", diff --git a/source/compiler/qsc_eval/src/val.rs b/source/compiler/qsc_eval/src/val.rs index 66696726114..7f628f82fec 100644 --- a/source/compiler/qsc_eval/src/val.rs +++ b/source/compiler/qsc_eval/src/val.rs @@ -237,6 +237,7 @@ pub enum VarTy { Integer, Double, Qubit, + Result, } impl Display for VarTy { @@ -246,6 +247,7 @@ impl Display for VarTy { Self::Integer => write!(f, "Integer"), Self::Double => write!(f, "Double"), Self::Qubit => write!(f, "Qubit"), + Self::Result => write!(f, "Result"), } } } diff --git a/source/compiler/qsc_openqasm_compiler/src/tests/statement/gate_call.rs b/source/compiler/qsc_openqasm_compiler/src/tests/statement/gate_call.rs index 29e9bab41bb..c713640ef44 100644 --- a/source/compiler/qsc_openqasm_compiler/src/tests/statement/gate_call.rs +++ b/source/compiler/qsc_openqasm_compiler/src/tests/statement/gate_call.rs @@ -535,108 +535,108 @@ fn custom_gate_with_angle_parameter_generates_qir_adaptive() -> miette::Result<( declare void @__quantum__rt__initialize(ptr) - define void @phase_by(i64 %var_0, i64 %var_1, ptr %var_2) { + define void @phase_by(i64 %var_1, i64 %var_2, ptr %var_3) { block_1: - call void @rz(i64 %var_0, i64 %var_1, ptr %var_2) + call void @rz(i64 %var_1, i64 %var_2, ptr %var_3) ret void } - define void @rz(i64 %var_3, i64 %var_4, ptr %var_5) { + define void @rz(i64 %var_4, i64 %var_5, ptr %var_6) { block_2: - %var_42 = call double @AngleAsDouble(i64 %var_3, i64 %var_4) - call void @Rz(double %var_42, ptr %var_5) + %var_43 = call double @AngleAsDouble(i64 %var_4, i64 %var_5) + call void @Rz(double %var_43, ptr %var_6) ret void } - define double @AngleAsDouble(i64 %var_6, i64 %var_7) { + define double @AngleAsDouble(i64 %var_7, i64 %var_8) { block_3: - %var_9 = alloca i64 - %var_14 = alloca i64 - %var_19 = alloca i64 - %var_21 = alloca i64 - %var_23 = alloca i1 - %var_25 = alloca i1 - %var_28 = alloca i64 - %var_30 = alloca i64 - %var_32 = alloca i64 - %var_8 = icmp sgt i64 %var_7, 53 - br i1 %var_8, label %block_4, label %block_5 + %var_10 = alloca i64 + %var_15 = alloca i64 + %var_20 = alloca i64 + %var_22 = alloca i64 + %var_24 = alloca i1 + %var_26 = alloca i1 + %var_29 = alloca i64 + %var_31 = alloca i64 + %var_33 = alloca i64 + %var_9 = icmp sgt i64 %var_8, 53 + br i1 %var_9, label %block_4, label %block_5 block_4: - %var_10 = sub i64 %var_7, 53 - %var_12 = sub i64 %var_10, 1 - %var_13 = shl i64 1, %var_12 - store i64 %var_13, ptr %var_14 - %var_15 = shl i64 1, %var_10 - %var_16 = sub i64 %var_15, 1 - %var_18 = and i64 %var_6, %var_16 - store i64 %var_18, ptr %var_19 - %var_20 = ashr i64 %var_6, %var_10 - store i64 %var_20, ptr %var_21 - %var_53 = load i64, ptr %var_19 - %var_54 = load i64, ptr %var_14 - %var_22 = icmp sgt i64 %var_53, %var_54 - store i1 true, ptr %var_23 - br i1 %var_22, label %block_9, label %block_6 + %var_11 = sub i64 %var_8, 53 + %var_13 = sub i64 %var_11, 1 + %var_14 = shl i64 1, %var_13 + store i64 %var_14, ptr %var_15 + %var_16 = shl i64 1, %var_11 + %var_17 = sub i64 %var_16, 1 + %var_19 = and i64 %var_7, %var_17 + store i64 %var_19, ptr %var_20 + %var_21 = ashr i64 %var_7, %var_11 + store i64 %var_21, ptr %var_22 + %var_54 = load i64, ptr %var_20 + %var_55 = load i64, ptr %var_15 + %var_23 = icmp sgt i64 %var_54, %var_55 + store i1 true, ptr %var_24 + br i1 %var_23, label %block_9, label %block_6 block_5: - store i64 %var_6, ptr %var_9 + store i64 %var_7, ptr %var_10 br label %block_13 block_6: - %var_56 = load i64, ptr %var_19 - %var_57 = load i64, ptr %var_14 - %var_24 = icmp eq i64 %var_56, %var_57 - store i1 false, ptr %var_25 - br i1 %var_24, label %block_7, label %block_8 + %var_57 = load i64, ptr %var_20 + %var_58 = load i64, ptr %var_15 + %var_25 = icmp eq i64 %var_57, %var_58 + store i1 false, ptr %var_26 + br i1 %var_25, label %block_7, label %block_8 block_7: - %var_68 = load i64, ptr %var_21 - %var_26 = and i64 %var_68, 1 - %var_27 = icmp eq i64 %var_26, 1 - store i1 %var_27, ptr %var_25 + %var_69 = load i64, ptr %var_22 + %var_27 = and i64 %var_69, 1 + %var_28 = icmp eq i64 %var_27, 1 + store i1 %var_28, ptr %var_26 br label %block_8 block_8: - %var_59 = load i1, ptr %var_25 - store i1 %var_59, ptr %var_23 + %var_60 = load i1, ptr %var_26 + store i1 %var_60, ptr %var_24 br label %block_9 block_9: - %var_61 = load i1, ptr %var_23 - br i1 %var_61, label %block_10, label %block_11 + %var_62 = load i1, ptr %var_24 + br i1 %var_62, label %block_10, label %block_11 block_10: - %var_66 = load i64, ptr %var_21 - %var_29 = add i64 %var_66, 1 - store i64 %var_29, ptr %var_28 + %var_67 = load i64, ptr %var_22 + %var_30 = add i64 %var_67, 1 + store i64 %var_30, ptr %var_29 br label %block_12 block_11: - %var_62 = load i64, ptr %var_21 - store i64 %var_62, ptr %var_28 + %var_63 = load i64, ptr %var_22 + store i64 %var_63, ptr %var_29 br label %block_12 block_12: - %var_64 = load i64, ptr %var_28 - store i64 %var_64, ptr %var_9 + %var_65 = load i64, ptr %var_29 + store i64 %var_65, ptr %var_10 br label %block_13 block_13: - %var_44 = load i64, ptr %var_9 - store i64 %var_44, ptr %var_30 - %var_31 = icmp sgt i64 %var_7, 53 - br i1 %var_31, label %block_14, label %block_15 + %var_45 = load i64, ptr %var_10 + store i64 %var_45, ptr %var_31 + %var_32 = icmp sgt i64 %var_8, 53 + br i1 %var_32, label %block_14, label %block_15 block_14: - store i64 53, ptr %var_32 + store i64 53, ptr %var_33 br label %block_16 block_15: - store i64 %var_7, ptr %var_32 + store i64 %var_8, ptr %var_33 br label %block_16 block_16: - %var_47 = load i64, ptr %var_32 - %var_34 = shl i64 1, %var_47 - %var_35 = sitofp i64 %var_34 to double - %var_48 = load i64, ptr %var_30 - %var_37 = sitofp i64 %var_48 to double - %var_39 = fdiv double 6.283185307179586, %var_35 - %var_41 = fmul double %var_37, %var_39 - ret double %var_41 + %var_48 = load i64, ptr %var_33 + %var_35 = shl i64 1, %var_48 + %var_36 = sitofp i64 %var_35 to double + %var_49 = load i64, ptr %var_31 + %var_38 = sitofp i64 %var_49 to double + %var_40 = fdiv double 6.283185307179586, %var_36 + %var_42 = fmul double %var_38, %var_40 + ret double %var_42 } - define void @Rz(double %var_44, ptr %var_45) { + define void @Rz(double %var_45, ptr %var_46) { block_17: - call void @__quantum__qis__rz__body(double %var_44, ptr %var_45) + call void @__quantum__qis__rz__body(double %var_45, ptr %var_46) ret void } diff --git a/source/compiler/qsc_partial_eval/src/lib.rs b/source/compiler/qsc_partial_eval/src/lib.rs index d262441cb4f..baef58ff01a 100644 --- a/source/compiler/qsc_partial_eval/src/lib.rs +++ b/source/compiler/qsc_partial_eval/src/lib.rs @@ -641,6 +641,12 @@ impl<'a> PartialEvaluator<'a> { rhs_expr_id, bin_op_expr_span, ), + Value::Var(v) if v.ty == VarTy::Result => self.eval_bin_op_with_lhs_result_operand( + bin_op, + &lhs_value, + rhs_expr_id, + bin_op_expr_span, + ), Value::Bool(lhs_bool) => { self.eval_bin_op_with_lhs_classical_bool_operand(bin_op, lhs_bool, rhs_expr_id) } @@ -1212,7 +1218,7 @@ impl<'a> PartialEvaluator<'a> { bin_op_expr_span, ) } - VarTy::Qubit => Err(Error::Unexpected( + VarTy::Qubit | VarTy::Result => Err(Error::Unexpected( format!( "unsupported LHS variable type {} in binary operation", lhs_eval_var.ty @@ -2043,8 +2049,11 @@ impl<'a> PartialEvaluator<'a> { let ret_val = match output_var { None => Value::unit(), Some(output_var) => { - if output_var.ty == rir::Ty::Prim(rir::Prim::Qubit) { - // We don't actually accept custom intrinsics that return qubits, so emit an error here. + if matches!( + output_var.ty, + rir::Ty::Prim(rir::Prim::Qubit | rir::Prim::Result) + ) { + // We don't actually accept custom intrinsics that return qubits or results (unless marked as a measurement), so emit an error here. return Err(Error::UnsupportedCustomIntrinsicType( callable_decl.output.to_string(), callee_expr_span, @@ -2887,7 +2896,7 @@ impl<'a> PartialEvaluator<'a> { .config .capabilities .contains(TargetCapabilityFlags::BackwardsBranching)) - && let Some(value) = map_rir_literal_to_eval_value(*literal) + && let Some(value) = map_rir_literal_to_eval_value(*literal, var.ty) { value } else { @@ -3069,6 +3078,9 @@ impl<'a> PartialEvaluator<'a> { .try_into() .expect("could not convert result ID to u32"), )), + Value::Var(v) if v.ty == VarTy::Result => { + Operand::Variable(map_eval_var_to_rir_var(*v)) + } Value::Result(val::Result::Val(bool)) => return Operand::Literal(Literal::Bool(*bool)), Value::Result(val::Result::Loss) => { panic!("loss result should not occur in partial evaluation") @@ -4090,7 +4102,7 @@ impl<'a> PartialEvaluator<'a> { Value::Var(var) => { let current_scope = self.eval_context.get_current_scope(); if let Some(literal) = current_scope.get_static_value(var.id.into()) { - map_rir_literal_to_eval_value(*literal).unwrap_or(Value::Var(var)) + map_rir_literal_to_eval_value(*literal, var.ty).unwrap_or(Value::Var(var)) } else { value } @@ -4193,6 +4205,7 @@ impl<'a> PartialEvaluator<'a> { Ty::Prim(Prim::Bool) => (self.get_bool_record_callable(), "b"), Ty::Prim(Prim::Int) => (self.get_int_record_callable(), "i"), Ty::Prim(Prim::Double) => (self.get_double_record_callable(), "d"), + Ty::Prim(Prim::Result) => (self.get_result_record_callable(), "r"), _ => panic!("unsupported variable type in output recording"), }; let tag = format!("{idx}_{tag_root}{tag_ty}"); @@ -4413,7 +4426,7 @@ impl<'a> PartialEvaluator<'a> { .try_into() .expect("could not convert result ID to u32"), )), - val::Result::Val(bool) => Operand::Literal(Literal::Bool(*bool)), + val::Result::Val(bool) => Operand::Literal(Literal::ResultLit(*bool)), val::Result::Loss => panic!("loss result should not occur in partial evaluation"), }, Value::Var(var) => Operand::Variable(map_eval_var_to_rir_var(*var)), @@ -5039,6 +5052,7 @@ fn map_eval_var_type_to_rir_type(var_ty: VarTy) -> rir::Ty { VarTy::Integer => rir::Ty::Prim(rir::Prim::Integer), VarTy::Double => rir::Ty::Prim(rir::Prim::Double), VarTy::Qubit => rir::Ty::Prim(rir::Prim::Qubit), + VarTy::Result => rir::Ty::Prim(rir::Prim::Result), } } @@ -5053,13 +5067,19 @@ fn map_fir_type_to_rir_type(ty: &Ty) -> Result { } } -fn map_rir_literal_to_eval_value(literal: rir::Literal) -> Option { - match literal { - rir::Literal::Bool(b) => Some(Value::Bool(b)), - rir::Literal::Double(d) => Some(Value::Double(d)), - rir::Literal::Integer(i) => Some(Value::Int(i)), - _ => None, - } +fn map_rir_literal_to_eval_value(literal: rir::Literal, var_ty: VarTy) -> Option { + Some(match literal { + rir::Literal::Bool(b) => match var_ty { + VarTy::Boolean => Value::Bool(b), + VarTy::Result => Value::Result(val::Result::Val(b)), + _ => panic!("Incompatible literal and variable types: {literal}, {var_ty}"), + }, + rir::Literal::Double(d) => Value::Double(d), + rir::Literal::Integer(i) => Value::Int(i), + rir::Literal::Result(r) => Value::Result(val::Result::Id(r as usize)), + rir::Literal::ResultLit(r) => Value::Result(val::Result::Val(r)), + _ => return None, + }) } fn map_rir_var_to_eval_var(var: rir::Variable) -> Result { @@ -5075,6 +5095,7 @@ fn map_rir_type_to_eval_var_type(ty: rir::Ty) -> Result { rir::Ty::Prim(rir::Prim::Integer) => Ok(VarTy::Integer), rir::Ty::Prim(rir::Prim::Double) => Ok(VarTy::Double), rir::Ty::Prim(rir::Prim::Qubit) => Ok(VarTy::Qubit), + rir::Ty::Prim(rir::Prim::Result) => Ok(VarTy::Result), _ => Err(()), } } @@ -5085,6 +5106,7 @@ fn try_get_eval_var_type(value: &Value) -> Option { Value::Int(_) => Some(VarTy::Integer), Value::Double(_) => Some(VarTy::Double), Value::Qubit(_) => Some(VarTy::Qubit), + Value::Result(_) => Some(VarTy::Result), Value::Var(var) => Some(var.ty), _ => None, } @@ -5117,6 +5139,7 @@ fn convert_to_array_literal( Value::Result(val::Result::Id(r)) => { rir::Literal::Result((*r).try_into().expect("could not convert result ID to u32")) } + Value::Result(val::Result::Val(b)) => rir::Literal::ResultLit(*b), _ => { return Err(Error::Unimplemented( format!("array element type `{}`", elem.type_name()), diff --git a/source/compiler/qsc_partial_eval/src/tests/assigns.rs b/source/compiler/qsc_partial_eval/src/tests/assigns.rs index 96f6e8dae21..a63e456e42d 100644 --- a/source/compiler/qsc_partial_eval/src/tests/assigns.rs +++ b/source/compiler/qsc_partial_eval/src/tests/assigns.rs @@ -84,7 +84,9 @@ fn assigning_result_register_updates_value() { &expect![[r#" Block: Call id(1), args( Pointer, ) + Variable(0, Result) = Store ResultLit(false) Call id(2), args( Qubit(0), Result(0), ) + Variable(0, Result) = Store Result(0) Call id(3), args( Result(0), Tag(0, 3), ) Return Integer(0)"#]], ); @@ -474,8 +476,8 @@ fn assigning_classical_int_within_dynamic_if_else_expression_adds_store_instruct } #[test] -fn assigning_result_literal_within_dynamic_if_expression_produces_error() { - let error = get_partial_evaluation_error(indoc! {r#" +fn assigning_result_literal_within_dynamic_if_expression_produces_rir_literal() { + let program = get_rir_program(indoc! {r#" namespace Test { @EntryPoint() operation Main() : Result { @@ -488,11 +490,24 @@ fn assigning_result_literal_within_dynamic_if_expression_produces_error() { } } "#}); - assert_error( - &error, - &expect![[ - r#"Unexpected("re-assignment within a dynamic branch is unsupported for type Result", PackageSpan { package: PackageId(2), span: Span { lo: 166, hi: 167 } })"# - ]], + assert_blocks( + &program, + &expect![[r#" + Blocks: + Block 0:Block: + Call id(1), args( Pointer, ) + Variable(0, Result) = Store ResultLit(false) + Call id(2), args( Qubit(0), Result(0), ) + Variable(1, Boolean) = Call id(3), args( Result(0), ) + Variable(2, Boolean) = Store Variable(1, Boolean) + Branch Variable(2, Boolean), 2, 1 + Block 1:Block: + Variable(3, Result) = Store Variable(0, Result) + Call id(4), args( Variable(3, Result), Tag(0, 3), ) + Return Integer(0) + Block 2:Block: + Variable(0, Result) = Store ResultLit(true) + Jump(1)"#]], ); } diff --git a/source/compiler/qsc_partial_eval/src/tests/bindings.rs b/source/compiler/qsc_partial_eval/src/tests/bindings.rs index c05a63fadae..2a0486be9b1 100644 --- a/source/compiler/qsc_partial_eval/src/tests/bindings.rs +++ b/source/compiler/qsc_partial_eval/src/tests/bindings.rs @@ -111,6 +111,7 @@ fn mutable_result_binding_does_not_generate_store_instruction() { Block: Call id(1), args( Pointer, ) Call id(2), args( Qubit(0), Result(0), ) + Variable(0, Result) = Store Result(0) Call id(3), args( Result(0), Tag(0, 3), ) Return Integer(0)"#]], ); diff --git a/source/compiler/qsc_partial_eval/src/tests/branching.rs b/source/compiler/qsc_partial_eval/src/tests/branching.rs index 588fc4c2edc..b05e0de45b3 100644 --- a/source/compiler/qsc_partial_eval/src/tests/branching.rs +++ b/source/compiler/qsc_partial_eval/src/tests/branching.rs @@ -1307,8 +1307,8 @@ fn if_else_expression_with_dynamic_condition_and_subsequent_call_to_operation() } #[test] -fn if_else_expression_with_result_literal_fails() { - let error = get_partial_evaluation_error(indoc! { +fn if_else_expression_with_result_literal() { + let program = get_rir_program(indoc! { r#" namespace Test { @EntryPoint() @@ -1320,11 +1320,27 @@ fn if_else_expression_with_result_literal_fails() { "#, }); - assert_error( - &error, - &expect![[ - r#"Unexpected("dynamic value of type Result in conditional expression", PackageSpan { package: PackageId(2), span: Span { lo: 101, hi: 137 } })"# - ]], + assert_blocks( + &program, + &expect![[r#" + Blocks: + Block 0:Block: + Call id(1), args( Pointer, ) + Call id(2), args( Qubit(0), Result(0), ) + Variable(0, Boolean) = Call id(3), args( Result(0), ) + Variable(1, Boolean) = Store Variable(0, Boolean) + Branch Variable(1, Boolean), 2, 3 + Block 1:Block: + Variable(3, Result) = Store Variable(2, Result) + Call id(4), args( Variable(3, Result), Tag(0, 3), ) + Return Integer(0) + Block 2:Block: + Variable(2, Result) = Store ResultLit(true) + Jump(1) + Block 3:Block: + Call id(2), args( Qubit(0), Result(1), ) + Variable(2, Result) = Store Result(1) + Jump(1)"#]], ); } diff --git a/source/compiler/qsc_rca/src/lib.rs b/source/compiler/qsc_rca/src/lib.rs index 9b1d3a77cf5..ad77f1e8a07 100644 --- a/source/compiler/qsc_rca/src/lib.rs +++ b/source/compiler/qsc_rca/src/lib.rs @@ -824,7 +824,7 @@ impl RuntimeFeatureFlags { capabilities |= TargetCapabilityFlags::HigherLevelConstructs; } if self.contains(RuntimeFeatureFlags::UseOfDynamicResult) { - capabilities |= TargetCapabilityFlags::HigherLevelConstructs; + capabilities |= TargetCapabilityFlags::StaticSizedArrays; } if self.contains(RuntimeFeatureFlags::UseOfDynamicTuple) { capabilities |= TargetCapabilityFlags::HigherLevelConstructs; diff --git a/source/compiler/qsc_rir/src/builder.rs b/source/compiler/qsc_rir/src/builder.rs index 2288353c426..6c250381f31 100644 --- a/source/compiler/qsc_rir/src/builder.rs +++ b/source/compiler/qsc_rir/src/builder.rs @@ -116,6 +116,18 @@ pub fn read_result_decl() -> Callable { } } +#[must_use] +pub fn write_result_decl() -> Callable { + Callable { + name: "__quantum__rt__write_result".to_string(), + input_type: vec![Ty::Prim(Prim::Boolean), Ty::Prim(Prim::Result)], + input_vars: Vec::new(), + output_type: None, + body: None, + call_type: CallableType::Regular, + } +} + #[must_use] pub fn initialize_decl() -> Callable { Callable { diff --git a/source/compiler/qsc_rir/src/passes.rs b/source/compiler/qsc_rir/src/passes.rs index 80e98f1c149..4635b7db690 100644 --- a/source/compiler/qsc_rir/src/passes.rs +++ b/source/compiler/qsc_rir/src/passes.rs @@ -7,6 +7,7 @@ mod insert_alloca_load; mod prune_unneeded_stores; mod reindex_qubits; mod remap_block_ids; +mod result_literal; mod simplify_control_flow; mod ssa_check; mod ssa_transform; @@ -28,7 +29,8 @@ pub use unreachable_code_check::check_unreachable_code; use crate::{ passes::{ - insert_alloca_load::insert_alloca_load_instrs, prune_unneeded_stores::prune_unneeded_stores, + insert_alloca_load::insert_alloca_load_instrs, + prune_unneeded_stores::prune_unneeded_stores, result_literal::transform_result_literals, }, rir::Program, utils::build_predecessors_map, @@ -54,6 +56,7 @@ pub fn check_and_transform(program: &mut Program) { if uses_non_ssa_pipeline { prune_unneeded_stores(program); insert_alloca_load_instrs(program); + transform_result_literals(program); } else { let preds = build_predecessors_map(program); transform_to_ssa(program, &preds); diff --git a/source/compiler/qsc_rir/src/passes/result_literal.rs b/source/compiler/qsc_rir/src/passes/result_literal.rs new file mode 100644 index 00000000000..0f18665a8f5 --- /dev/null +++ b/source/compiler/qsc_rir/src/passes/result_literal.rs @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +use crate::{ + builder, + rir::{CallableId, Instruction, Literal, Operand, Program}, +}; + +/// Transforms result literals in the program. +/// Since result literals are not supported in QIR, this function attempts to handle them as best as possible. +/// A result literal of `Zero` (or false) will be replaced with an additional result id that is never measured into, +/// which defaults to returning false or 0 if read or recorded. +/// A result literal of `One` cannot be handled and is left un-transformed so that later checks on the program can +/// reject it as incompatible. +pub fn transform_result_literals(program: &mut Program) { + let result_zero_id = program.num_results; + let result_one_id = program.num_results + 1; + let mut replaced_zero = false; + let mut replaced_one = false; + + for block in program.blocks.values_mut() { + for instr in &mut block.0 { + // Result literals are only expected in context of Store, Call, or Return instructions + match instr { + Instruction::Store(operand, _) | Instruction::Return(Some(operand)) => { + let Operand::Literal(Literal::ResultLit(val)) = *operand else { + continue; + }; + let id = if val { + replaced_one = true; + result_one_id + } else { + replaced_zero = true; + result_zero_id + }; + *operand = Operand::Literal(Literal::Result(id)); + } + + Instruction::Call(_, operands, _, _) => { + for operand in operands.iter_mut() { + if let Operand::Literal(Literal::ResultLit(val)) = *operand { + let id = if val { + replaced_one = true; + result_one_id + } else { + replaced_zero = true; + result_zero_id + }; + *operand = Operand::Literal(Literal::Result(id)); + } + } + } + _ => {} + } + } + } + + // Also check the static arrays in global section for the presence of result literals, and replace them with the new result ids. + for array in &mut program.array_literals { + for elem in &mut array.contents { + if let Literal::ResultLit(val) = elem { + let id = if *val { + replaced_one = true; + result_one_id + } else { + replaced_zero = true; + result_zero_id + }; + *elem = Literal::Result(id); + } + } + } + + if replaced_zero || replaced_one { + let write_id = add_write_result(program); + let entry_block_id = program + .callables + .get(program.entry) + .expect("entry point should exist") + .body + .expect("entry point should have a body"); + let entry_block = program + .blocks + .get_mut(entry_block_id) + .expect("entry block should exist"); + let mut instructions = Vec::new(); + if replaced_zero { + instructions.push(Instruction::Call( + write_id, + vec![ + Operand::Literal(Literal::Bool(false)), + Operand::Literal(Literal::Result(result_zero_id)), + ], + None, + None, + )); + } + if replaced_one { + instructions.push(Instruction::Call( + write_id, + vec![ + Operand::Literal(Literal::Bool(true)), + Operand::Literal(Literal::Result(result_one_id)), + ], + None, + None, + )); + } + instructions.append(&mut entry_block.0); + entry_block.0 = instructions; + } + + if replaced_one { + program.num_results += 2; + } else if replaced_zero { + program.num_results += 1; + } +} + +fn add_write_result(program: &mut Program) -> CallableId { + let write_id = CallableId( + program + .callables + .iter() + .map(|(id, _)| id.0) + .max() + .expect("should be at least one callable") + + 1, + ); + program + .callables + .insert(write_id, builder::write_result_decl()); + write_id +} diff --git a/source/compiler/qsc_rir/src/rir.rs b/source/compiler/qsc_rir/src/rir.rs index 9c04582b93d..6b5bd247560 100644 --- a/source/compiler/qsc_rir/src/rir.rs +++ b/source/compiler/qsc_rir/src/rir.rs @@ -658,7 +658,7 @@ impl Operand { match self { Operand::Literal(lit) => match lit { Literal::Qubit(_) => Ty::Prim(Prim::Qubit), - Literal::Result(_) => Ty::Prim(Prim::Result), + Literal::Result(_) | Literal::ResultLit(_) => Ty::Prim(Prim::Result), Literal::Bool(_) => Ty::Prim(Prim::Boolean), Literal::Integer(_) => Ty::Prim(Prim::Integer), Literal::Double(_) => Ty::Prim(Prim::Double), @@ -675,6 +675,7 @@ impl Operand { pub enum Literal { Qubit(u32), Result(u32), + ResultLit(bool), Bool(bool), Integer(i64), Double(f64), @@ -688,6 +689,7 @@ impl Display for Literal { match &self { Self::Qubit(id) => write!(f, "Qubit({id})")?, Self::Result(id) => write!(f, "Result({id})")?, + Self::ResultLit(b) => write!(f, "ResultLit({b})")?, Self::Bool(b) => write!(f, "Bool({b})")?, Self::Integer(i) => write!(f, "Integer({i})")?, Self::Double(d) => write!(f, "Double({d})")?, @@ -740,6 +742,13 @@ impl PartialEq for Literal { false } } + Self::ResultLit(self_result_lit) => { + if let Self::ResultLit(other_result_lit) = other { + self_result_lit == other_result_lit + } else { + false + } + } Self::Tag(self_tag_idx, self_tag_len) => { if let Self::Tag(other_tag_idx, other_tag_len) = other { self_tag_idx == other_tag_idx && self_tag_len == other_tag_len diff --git a/source/qdk_package/tests-integration/resources/adaptive/output/ArithmeticOps.ll b/source/qdk_package/tests-integration/resources/adaptive/output/ArithmeticOps.ll index 9047ac1d52e..7ad7928314d 100644 --- a/source/qdk_package/tests-integration/resources/adaptive/output/ArithmeticOps.ll +++ b/source/qdk_package/tests-integration/resources/adaptive/output/ArithmeticOps.ll @@ -4,6 +4,7 @@ @3 = internal constant [6 x i8] c"3_t2i\00" @4 = internal constant [6 x i8] c"4_t3i\00" @array0 = internal constant [5 x ptr] [ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 3 to ptr), ptr inttoptr (i64 4 to ptr)] +@array1 = internal constant [5 x ptr] [ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 3 to ptr), ptr inttoptr (i64 4 to ptr)] define i64 @ENTRYPOINT__main() #0 { block_0: @@ -12,7 +13,8 @@ block_0: %var_3 = alloca i64 %var_4 = alloca i64 %var_6 = alloca i64 - %var_44 = alloca i64 + %var_13 = alloca i64 + %var_24 = alloca i64 call void @__quantum__rt__initialize(ptr null) store i64 0, ptr %var_1 store i64 0, ptr %var_2 @@ -21,15 +23,15 @@ block_0: store i64 0, ptr %var_6 br label %block_1 block_1: - %var_55 = load i64, ptr %var_6 - %var_7 = icmp slt i64 %var_55, 5 + %var_35 = load i64, ptr %var_6 + %var_7 = icmp slt i64 %var_35, 5 br i1 %var_7, label %block_2, label %block_3 block_2: - %var_105 = load i64, ptr %var_6 - %var_8 = getelementptr ptr, ptr @array0, i64 %var_105 - %var_106 = load ptr, ptr %var_8 - call void @X(ptr %var_106) - %var_11 = add i64 %var_105, 1 + %var_59 = load i64, ptr %var_6 + %var_8 = getelementptr ptr, ptr @array0, i64 %var_59 + %var_60 = load ptr, ptr %var_8 + call void @X(ptr %var_60) + %var_11 = add i64 %var_59, 1 store i64 %var_11, ptr %var_6 br label %block_1 block_3: @@ -38,122 +40,69 @@ block_3: call void @__quantum__qis__m__body(ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 2 to ptr)) call void @__quantum__qis__m__body(ptr inttoptr (i64 3 to ptr), ptr inttoptr (i64 3 to ptr)) call void @__quantum__qis__m__body(ptr inttoptr (i64 4 to ptr), ptr inttoptr (i64 4 to ptr)) - %var_14 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) - br i1 %var_14, label %block_4, label %block_5 + store i64 0, ptr %var_13 + br label %block_4 block_4: - %var_97 = load i64, ptr %var_1 - %var_16 = add i64 %var_97, 1 - store i64 %var_16, ptr %var_1 - %var_99 = load i64, ptr %var_2 - %var_17 = add i64 %var_99, 5 - store i64 %var_17, ptr %var_2 - %var_101 = load i64, ptr %var_3 - %var_18 = sub i64 %var_101, 2 - store i64 %var_18, ptr %var_3 - %var_103 = load i64, ptr %var_4 - %var_19 = mul i64 %var_103, 3 - store i64 %var_19, ptr %var_4 - br label %block_5 + %var_37 = load i64, ptr %var_13 + %var_14 = icmp slt i64 %var_37, 5 + br i1 %var_14, label %block_5, label %block_6 block_5: - %var_20 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 1 to ptr)) - br i1 %var_20, label %block_6, label %block_7 + %var_47 = load i64, ptr %var_13 + %var_15 = getelementptr ptr, ptr @array1, i64 %var_47 + %var_48 = load ptr, ptr %var_15 + %var_17 = call i1 @__quantum__rt__read_result(ptr %var_48) + br i1 %var_17, label %block_7, label %block_9 block_6: - %var_89 = load i64, ptr %var_1 - %var_22 = add i64 %var_89, 1 - store i64 %var_22, ptr %var_1 - %var_91 = load i64, ptr %var_2 - %var_23 = add i64 %var_91, 5 - store i64 %var_23, ptr %var_2 - %var_93 = load i64, ptr %var_3 - %var_24 = sub i64 %var_93, 2 - store i64 %var_24, ptr %var_3 - %var_95 = load i64, ptr %var_4 - %var_25 = mul i64 %var_95, 3 - store i64 %var_25, ptr %var_4 - br label %block_7 + store i64 0, ptr %var_24 + br label %block_8 block_7: - %var_26 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 2 to ptr)) - br i1 %var_26, label %block_8, label %block_9 -block_8: - %var_81 = load i64, ptr %var_1 - %var_28 = add i64 %var_81, 1 - store i64 %var_28, ptr %var_1 - %var_83 = load i64, ptr %var_2 - %var_29 = add i64 %var_83, 5 - store i64 %var_29, ptr %var_2 - %var_85 = load i64, ptr %var_3 - %var_30 = sub i64 %var_85, 2 - store i64 %var_30, ptr %var_3 - %var_87 = load i64, ptr %var_4 - %var_31 = mul i64 %var_87, 3 - store i64 %var_31, ptr %var_4 + %var_51 = load i64, ptr %var_1 + %var_19 = add i64 %var_51, 1 + store i64 %var_19, ptr %var_1 + %var_53 = load i64, ptr %var_2 + %var_20 = add i64 %var_53, 5 + store i64 %var_20, ptr %var_2 + %var_55 = load i64, ptr %var_3 + %var_21 = sub i64 %var_55, 2 + store i64 %var_21, ptr %var_3 + %var_57 = load i64, ptr %var_4 + %var_22 = mul i64 %var_57, 3 + store i64 %var_22, ptr %var_4 br label %block_9 +block_8: + %var_39 = load i64, ptr %var_24 + %var_25 = icmp slt i64 %var_39, 5 + br i1 %var_25, label %block_10, label %block_11 block_9: - %var_32 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 3 to ptr)) - br i1 %var_32, label %block_10, label %block_11 + %var_49 = load i64, ptr %var_13 + %var_23 = add i64 %var_49, 1 + store i64 %var_23, ptr %var_13 + br label %block_4 block_10: - %var_73 = load i64, ptr %var_1 - %var_34 = add i64 %var_73, 1 - store i64 %var_34, ptr %var_1 - %var_75 = load i64, ptr %var_2 - %var_35 = add i64 %var_75, 5 - store i64 %var_35, ptr %var_2 - %var_77 = load i64, ptr %var_3 - %var_36 = sub i64 %var_77, 2 - store i64 %var_36, ptr %var_3 - %var_79 = load i64, ptr %var_4 - %var_37 = mul i64 %var_79, 3 - store i64 %var_37, ptr %var_4 - br label %block_11 + %var_44 = load i64, ptr %var_24 + %var_26 = getelementptr ptr, ptr @array0, i64 %var_44 + %var_45 = load ptr, ptr %var_26 + call void @Reset(ptr %var_45) + %var_29 = add i64 %var_44, 1 + store i64 %var_29, ptr %var_24 + br label %block_8 block_11: - %var_38 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 4 to ptr)) - br i1 %var_38, label %block_12, label %block_13 -block_12: - %var_65 = load i64, ptr %var_1 - %var_40 = add i64 %var_65, 1 - store i64 %var_40, ptr %var_1 - %var_67 = load i64, ptr %var_2 - %var_41 = add i64 %var_67, 5 - store i64 %var_41, ptr %var_2 - %var_69 = load i64, ptr %var_3 - %var_42 = sub i64 %var_69, 2 - store i64 %var_42, ptr %var_3 - %var_71 = load i64, ptr %var_4 - %var_43 = mul i64 %var_71, 3 - store i64 %var_43, ptr %var_4 - br label %block_13 -block_13: - store i64 0, ptr %var_44 - br label %block_14 -block_14: - %var_57 = load i64, ptr %var_44 - %var_45 = icmp slt i64 %var_57, 5 - br i1 %var_45, label %block_15, label %block_16 -block_15: - %var_62 = load i64, ptr %var_44 - %var_46 = getelementptr ptr, ptr @array0, i64 %var_62 - %var_63 = load ptr, ptr %var_46 - call void @Reset(ptr %var_63) - %var_49 = add i64 %var_62, 1 - store i64 %var_49, ptr %var_44 - br label %block_14 -block_16: call void @__quantum__rt__tuple_record_output(i64 4, ptr @0) - %var_58 = load i64, ptr %var_1 - call void @__quantum__rt__int_record_output(i64 %var_58, ptr @1) - %var_59 = load i64, ptr %var_2 - call void @__quantum__rt__int_record_output(i64 %var_59, ptr @2) - %var_60 = load i64, ptr %var_3 - call void @__quantum__rt__int_record_output(i64 %var_60, ptr @3) - %var_61 = load i64, ptr %var_4 - call void @__quantum__rt__int_record_output(i64 %var_61, ptr @4) + %var_40 = load i64, ptr %var_1 + call void @__quantum__rt__int_record_output(i64 %var_40, ptr @1) + %var_41 = load i64, ptr %var_2 + call void @__quantum__rt__int_record_output(i64 %var_41, ptr @2) + %var_42 = load i64, ptr %var_3 + call void @__quantum__rt__int_record_output(i64 %var_42, ptr @3) + %var_43 = load i64, ptr %var_4 + call void @__quantum__rt__int_record_output(i64 %var_43, ptr @4) ret i64 0 } declare void @__quantum__rt__initialize(ptr) define void @X(ptr %var_10) { -block_17: +block_12: call void @__quantum__qis__x__body(ptr %var_10) ret void } @@ -164,9 +113,9 @@ declare void @__quantum__qis__m__body(ptr, ptr) #1 declare i1 @__quantum__rt__read_result(ptr) -define void @Reset(ptr %var_48) { -block_18: - call void @__quantum__qis__reset__body(ptr %var_48) +define void @Reset(ptr %var_28) { +block_13: + call void @__quantum__qis__reset__body(ptr %var_28) ret void } diff --git a/source/qdk_package/tests-integration/resources/adaptive/output/ExpandedTests.ll b/source/qdk_package/tests-integration/resources/adaptive/output/ExpandedTests.ll index 304ecb2fd42..499ed7b5b90 100644 --- a/source/qdk_package/tests-integration/resources/adaptive/output/ExpandedTests.ll +++ b/source/qdk_package/tests-integration/resources/adaptive/output/ExpandedTests.ll @@ -207,41 +207,41 @@ declare void @__quantum__qis__cz__body(ptr, ptr) declare void @__quantum__qis__mresetz__body(ptr, ptr) #1 -define void @CNOT(ptr %var_53, ptr %var_54) { +define void @CNOT(ptr %var_54, ptr %var_55) { block_31: - call void @__quantum__qis__cx__body(ptr %var_53, ptr %var_54) + call void @__quantum__qis__cx__body(ptr %var_54, ptr %var_55) ret void } declare void @__quantum__qis__cx__body(ptr, ptr) -define void @Rx(double %var_55, ptr %var_56) { +define void @Rx(double %var_56, ptr %var_57) { block_32: - call void @__quantum__qis__rx__body(double %var_55, ptr %var_56) + call void @__quantum__qis__rx__body(double %var_56, ptr %var_57) ret void } declare void @__quantum__qis__rx__body(double, ptr) -define void @Rz(double %var_57, ptr %var_58) { +define void @Rz(double %var_58, ptr %var_59) { block_33: - call void @__quantum__qis__rz__body(double %var_57, ptr %var_58) + call void @__quantum__qis__rz__body(double %var_58, ptr %var_59) ret void } declare void @__quantum__qis__rz__body(double, ptr) -define void @Rzz(double %var_59, ptr %var_60, ptr %var_61) { +define void @Rzz(double %var_60, ptr %var_61, ptr %var_62) { block_34: - call void @__quantum__qis__rzz__body(double %var_59, ptr %var_60, ptr %var_61) + call void @__quantum__qis__rzz__body(double %var_60, ptr %var_61, ptr %var_62) ret void } declare void @__quantum__qis__rzz__body(double, ptr, ptr) -define void @CNOT__Adj(ptr %var_62, ptr %var_63) { +define void @CNOT__Adj(ptr %var_63, ptr %var_64) { block_35: - call void @__quantum__qis__cx__body(ptr %var_62, ptr %var_63) + call void @__quantum__qis__cx__body(ptr %var_63, ptr %var_64) ret void } diff --git a/source/qdk_package/tests-integration/resources/adaptive/output/RandomBit.ll b/source/qdk_package/tests-integration/resources/adaptive/output/RandomBit.ll index b7484a63981..51501f239ff 100644 --- a/source/qdk_package/tests-integration/resources/adaptive/output/RandomBit.ll +++ b/source/qdk_package/tests-integration/resources/adaptive/output/RandomBit.ll @@ -12,9 +12,9 @@ block_0: declare void @__quantum__rt__initialize(ptr) -define void @H(ptr %var_1) { +define void @H(ptr %var_2) { block_1: - call void @__quantum__qis__h__body(ptr %var_1) + call void @__quantum__qis__h__body(ptr %var_2) ret void } @@ -22,9 +22,9 @@ declare void @__quantum__qis__h__body(ptr) declare void @__quantum__qis__m__body(ptr, ptr) #1 -define void @Reset(ptr %var_2) { +define void @Reset(ptr %var_3) { block_2: - call void @__quantum__qis__reset__body(ptr %var_2) + call void @__quantum__qis__reset__body(ptr %var_3) ret void } diff --git a/source/qdk_package/tests-integration/resources/adaptive/output/SampleTeleport.ll b/source/qdk_package/tests-integration/resources/adaptive/output/SampleTeleport.ll index e2283444e9a..d9d972b9167 100644 --- a/source/qdk_package/tests-integration/resources/adaptive/output/SampleTeleport.ll +++ b/source/qdk_package/tests-integration/resources/adaptive/output/SampleTeleport.ll @@ -4,7 +4,7 @@ define i64 @ENTRYPOINT__main() #0 { block_0: %var_1 = alloca i1 - %var_14 = alloca i64 + %var_15 = alloca i64 call void @__quantum__rt__initialize(ptr null) store i1 false, ptr %var_1 call void @H(ptr inttoptr (i64 0 to ptr)) @@ -14,17 +14,17 @@ block_0: call void @CNOT(ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 0 to ptr)) call void @H(ptr inttoptr (i64 2 to ptr)) call void @__quantum__qis__m__body(ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 0 to ptr)) - %var_8 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) - br i1 %var_8, label %block_1, label %block_2 + %var_9 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) + br i1 %var_9, label %block_1, label %block_2 block_1: call void @X(ptr inttoptr (i64 1 to ptr)) br label %block_2 block_2: call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 1 to ptr)) - %var_10 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 1 to ptr)) - store i1 %var_10, ptr %var_1 - %var_22 = load i1, ptr %var_1 - br i1 %var_22, label %block_3, label %block_4 + %var_11 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 1 to ptr)) + store i1 %var_11, ptr %var_1 + %var_23 = load i1, ptr %var_1 + br i1 %var_23, label %block_3, label %block_4 block_3: call void @Z(ptr inttoptr (i64 1 to ptr)) br label %block_4 @@ -32,19 +32,19 @@ block_4: call void @H(ptr inttoptr (i64 1 to ptr)) call void @__quantum__qis__m__body(ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr)) call void @H__Adj(ptr inttoptr (i64 1 to ptr)) - store i64 0, ptr %var_14 + store i64 0, ptr %var_15 br label %block_5 block_5: - %var_24 = load i64, ptr %var_14 - %var_15 = icmp slt i64 %var_24, 2 - br i1 %var_15, label %block_6, label %block_7 + %var_25 = load i64, ptr %var_15 + %var_16 = icmp slt i64 %var_25, 2 + br i1 %var_16, label %block_6, label %block_7 block_6: - %var_25 = load i64, ptr %var_14 - %var_16 = getelementptr ptr, ptr @array0, i64 %var_25 - %var_26 = load ptr, ptr %var_16 - call void @Reset(ptr %var_26) - %var_19 = add i64 %var_25, 1 - store i64 %var_19, ptr %var_14 + %var_26 = load i64, ptr %var_15 + %var_17 = getelementptr ptr, ptr @array0, i64 %var_26 + %var_27 = load ptr, ptr %var_17 + call void @Reset(ptr %var_27) + %var_20 = add i64 %var_26, 1 + store i64 %var_20, ptr %var_15 br label %block_5 block_7: call void @__quantum__rt__result_record_output(ptr inttoptr (i64 2 to ptr), ptr @0) @@ -53,25 +53,25 @@ block_7: declare void @__quantum__rt__initialize(ptr) -define void @H(ptr %var_4) { +define void @H(ptr %var_5) { block_8: - call void @__quantum__qis__h__body(ptr %var_4) + call void @__quantum__qis__h__body(ptr %var_5) ret void } declare void @__quantum__qis__h__body(ptr) -define void @CNOT(ptr %var_5, ptr %var_6) { +define void @CNOT(ptr %var_6, ptr %var_7) { block_9: - call void @__quantum__qis__cx__body(ptr %var_5, ptr %var_6) + call void @__quantum__qis__cx__body(ptr %var_6, ptr %var_7) ret void } declare void @__quantum__qis__cx__body(ptr, ptr) -define void @X(ptr %var_7) { +define void @X(ptr %var_8) { block_10: - call void @__quantum__qis__x__body(ptr %var_7) + call void @__quantum__qis__x__body(ptr %var_8) ret void } @@ -83,23 +83,23 @@ declare i1 @__quantum__rt__read_result(ptr) declare void @__quantum__qis__mresetz__body(ptr, ptr) #1 -define void @Z(ptr %var_12) { +define void @Z(ptr %var_13) { block_11: - call void @__quantum__qis__z__body(ptr %var_12) + call void @__quantum__qis__z__body(ptr %var_13) ret void } declare void @__quantum__qis__z__body(ptr) -define void @H__Adj(ptr %var_13) { +define void @H__Adj(ptr %var_14) { block_12: - call void @__quantum__qis__h__body(ptr %var_13) + call void @__quantum__qis__h__body(ptr %var_14) ret void } -define void @Reset(ptr %var_18) { +define void @Reset(ptr %var_19) { block_13: - call void @__quantum__qis__reset__body(ptr %var_18) + call void @__quantum__qis__reset__body(ptr %var_19) ret void } diff --git a/source/qdk_package/tests-integration/resources/adaptive/output/SwitchHandling.ll b/source/qdk_package/tests-integration/resources/adaptive/output/SwitchHandling.ll index d8b207d6a8d..d9bbee9a0c4 100644 --- a/source/qdk_package/tests-integration/resources/adaptive/output/SwitchHandling.ll +++ b/source/qdk_package/tests-integration/resources/adaptive/output/SwitchHandling.ll @@ -1,103 +1,111 @@ @0 = internal constant [4 x i8] c"0_r\00" @array0 = internal constant [2 x ptr] [ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr)] +@array1 = internal constant [2 x ptr] [ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 1 to ptr)] define i64 @ENTRYPOINT__main() #0 { block_0: - %var_2 = alloca i64 - %var_8 = alloca i64 - %var_18 = alloca i64 + %var_3 = alloca i64 + %var_9 = alloca i64 + %var_11 = alloca i64 + %var_20 = alloca i64 call void @__quantum__rt__initialize(ptr null) - store i64 0, ptr %var_2 + store i64 0, ptr %var_3 br label %block_1 block_1: - %var_32 = load i64, ptr %var_2 - %var_3 = icmp slt i64 %var_32, 2 - br i1 %var_3, label %block_2, label %block_3 + %var_34 = load i64, ptr %var_3 + %var_4 = icmp slt i64 %var_34, 2 + br i1 %var_4, label %block_2, label %block_3 block_2: - %var_49 = load i64, ptr %var_2 - %var_4 = getelementptr ptr, ptr @array0, i64 %var_49 - %var_50 = load ptr, ptr %var_4 - call void @X(ptr %var_50) - %var_7 = add i64 %var_49, 1 - store i64 %var_7, ptr %var_2 + %var_54 = load i64, ptr %var_3 + %var_5 = getelementptr ptr, ptr @array0, i64 %var_54 + %var_55 = load ptr, ptr %var_5 + call void @X(ptr %var_55) + %var_8 = add i64 %var_54, 1 + store i64 %var_8, ptr %var_3 br label %block_1 block_3: - store i64 0, ptr %var_8 + store i64 0, ptr %var_9 call void @__quantum__qis__m__body(ptr inttoptr (i64 0 to ptr), ptr inttoptr (i64 0 to ptr)) call void @__quantum__qis__m__body(ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 1 to ptr)) - store i64 0, ptr %var_8 - %var_11 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 0 to ptr)) - br i1 %var_11, label %block_4, label %block_5 + store i64 0, ptr %var_11 + br label %block_4 block_4: - %var_47 = load i64, ptr %var_8 - %var_13 = add i64 %var_47, 1 - store i64 %var_13, ptr %var_8 - br label %block_5 + %var_37 = load i64, ptr %var_11 + %var_12 = icmp slt i64 %var_37, 2 + br i1 %var_12, label %block_5, label %block_6 block_5: - %var_35 = load i64, ptr %var_8 - %var_14 = shl i64 %var_35, 1 - store i64 %var_14, ptr %var_8 - %var_15 = call i1 @__quantum__rt__read_result(ptr inttoptr (i64 1 to ptr)) - br i1 %var_15, label %block_6, label %block_7 + %var_46 = load i64, ptr %var_11 + %var_13 = getelementptr ptr, ptr @array1, i64 %var_46 + %var_47 = load ptr, ptr %var_13 + %var_48 = load i64, ptr %var_9 + %var_15 = shl i64 %var_48, 1 + store i64 %var_15, ptr %var_9 + %var_16 = call i1 @__quantum__rt__read_result(ptr %var_47) + br i1 %var_16, label %block_7, label %block_9 block_6: - %var_45 = load i64, ptr %var_8 - %var_17 = add i64 %var_45, 1 - store i64 %var_17, ptr %var_8 - br label %block_7 -block_7: - store i64 0, ptr %var_18 + store i64 0, ptr %var_20 br label %block_8 +block_7: + %var_52 = load i64, ptr %var_9 + %var_18 = add i64 %var_52, 1 + store i64 %var_18, ptr %var_9 + br label %block_9 block_8: - %var_38 = load i64, ptr %var_18 - %var_19 = icmp slt i64 %var_38, 2 - br i1 %var_19, label %block_9, label %block_10 + %var_39 = load i64, ptr %var_20 + %var_21 = icmp slt i64 %var_39, 2 + br i1 %var_21, label %block_10, label %block_11 block_9: - %var_42 = load i64, ptr %var_18 - %var_20 = getelementptr ptr, ptr @array0, i64 %var_42 - %var_43 = load ptr, ptr %var_20 - call void @Reset(ptr %var_43) - %var_23 = add i64 %var_42, 1 - store i64 %var_23, ptr %var_18 - br label %block_8 + %var_50 = load i64, ptr %var_11 + %var_19 = add i64 %var_50, 1 + store i64 %var_19, ptr %var_11 + br label %block_4 block_10: - %var_39 = load i64, ptr %var_8 - %var_24 = icmp eq i64 %var_39, 0 - br i1 %var_24, label %block_11, label %block_12 + %var_43 = load i64, ptr %var_20 + %var_22 = getelementptr ptr, ptr @array0, i64 %var_43 + %var_44 = load ptr, ptr %var_22 + call void @Reset(ptr %var_44) + %var_25 = add i64 %var_43, 1 + store i64 %var_25, ptr %var_20 + br label %block_8 block_11: - call void @ApplyGlobalPhase(double -1.5707963267948966) - br label %block_13 + %var_40 = load i64, ptr %var_9 + %var_26 = icmp eq i64 %var_40, 0 + br i1 %var_26, label %block_12, label %block_13 block_12: - %var_40 = load i64, ptr %var_8 - %var_27 = icmp eq i64 %var_40, 1 - br i1 %var_27, label %block_14, label %block_15 + call void @ApplyGlobalPhase(double -1.5707963267948966) + br label %block_14 block_13: + %var_41 = load i64, ptr %var_9 + %var_29 = icmp eq i64 %var_41, 1 + br i1 %var_29, label %block_15, label %block_16 +block_14: call void @__quantum__qis__mresetz__body(ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 2 to ptr)) call void @__quantum__rt__result_record_output(ptr inttoptr (i64 2 to ptr), ptr @0) ret i64 0 -block_14: - call void @Ry(double 3.141592653589793, ptr inttoptr (i64 2 to ptr)) - br label %block_16 block_15: - %var_41 = load i64, ptr %var_8 - %var_30 = icmp eq i64 %var_41, 2 - br i1 %var_30, label %block_17, label %block_18 + call void @Ry(double 3.141592653589793, ptr inttoptr (i64 2 to ptr)) + br label %block_17 block_16: - br label %block_13 + %var_42 = load i64, ptr %var_9 + %var_32 = icmp eq i64 %var_42, 2 + br i1 %var_32, label %block_18, label %block_19 block_17: - call void @Rz(double 3.141592653589793, ptr inttoptr (i64 2 to ptr)) - br label %block_19 + br label %block_14 block_18: - call void @Rx(double 3.141592653589793, ptr inttoptr (i64 2 to ptr)) - br label %block_19 + call void @Rz(double 3.141592653589793, ptr inttoptr (i64 2 to ptr)) + br label %block_20 block_19: - br label %block_16 + call void @Rx(double 3.141592653589793, ptr inttoptr (i64 2 to ptr)) + br label %block_20 +block_20: + br label %block_17 } declare void @__quantum__rt__initialize(ptr) -define void @X(ptr %var_6) { -block_20: - call void @__quantum__qis__x__body(ptr %var_6) +define void @X(ptr %var_7) { +block_21: + call void @__quantum__qis__x__body(ptr %var_7) ret void } @@ -107,44 +115,44 @@ declare void @__quantum__qis__m__body(ptr, ptr) #1 declare i1 @__quantum__rt__read_result(ptr) -define void @Reset(ptr %var_22) { -block_21: - call void @__quantum__qis__reset__body(ptr %var_22) +define void @Reset(ptr %var_24) { +block_22: + call void @__quantum__qis__reset__body(ptr %var_24) ret void } declare void @__quantum__qis__reset__body(ptr) #1 -define void @ApplyGlobalPhase(double %var_25) { -block_22: - call void @ControllableGlobalPhase(double %var_25) +define void @ApplyGlobalPhase(double %var_27) { +block_23: + call void @ControllableGlobalPhase(double %var_27) ret void } -define void @ControllableGlobalPhase(double %var_26) { -block_23: +define void @ControllableGlobalPhase(double %var_28) { +block_24: ret void } -define void @Ry(double %var_28, ptr %var_29) { -block_24: - call void @__quantum__qis__ry__body(double %var_28, ptr %var_29) +define void @Ry(double %var_30, ptr %var_31) { +block_25: + call void @__quantum__qis__ry__body(double %var_30, ptr %var_31) ret void } declare void @__quantum__qis__ry__body(double, ptr) -define void @Rz(double %var_31, ptr %var_32) { -block_25: - call void @__quantum__qis__rz__body(double %var_31, ptr %var_32) +define void @Rz(double %var_33, ptr %var_34) { +block_26: + call void @__quantum__qis__rz__body(double %var_33, ptr %var_34) ret void } declare void @__quantum__qis__rz__body(double, ptr) -define void @Rx(double %var_33, ptr %var_34) { -block_26: - call void @__quantum__qis__rx__body(double %var_33, ptr %var_34) +define void @Rx(double %var_35, ptr %var_36) { +block_27: + call void @__quantum__qis__rx__body(double %var_35, ptr %var_36) ret void } diff --git a/source/qdk_package/tests-integration/resources/adaptive_ri/output/SampleTeleport.ll b/source/qdk_package/tests-integration/resources/adaptive_ri/output/SampleTeleport.ll index d63a7a2d7f0..75c13210464 100644 --- a/source/qdk_package/tests-integration/resources/adaptive_ri/output/SampleTeleport.ll +++ b/source/qdk_package/tests-integration/resources/adaptive_ri/output/SampleTeleport.ll @@ -13,15 +13,15 @@ block_0: call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*)) call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*)) call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) - %var_4 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 0 to %Result*)) - br i1 %var_4, label %block_1, label %block_2 + %var_5 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 0 to %Result*)) + br i1 %var_5, label %block_1, label %block_2 block_1: call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 1 to %Qubit*)) br label %block_2 block_2: call void @__quantum__qis__mresetz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) - %var_6 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 1 to %Result*)) - br i1 %var_6, label %block_3, label %block_4 + %var_7 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 1 to %Result*)) + br i1 %var_7, label %block_3, label %block_4 block_3: call void @__quantum__qis__z__body(%Qubit* inttoptr (i64 1 to %Qubit*)) br label %block_4 diff --git a/source/qdk_package/tests-integration/resources/adaptive_ri/output/SwitchHandling.ll b/source/qdk_package/tests-integration/resources/adaptive_ri/output/SwitchHandling.ll index 4fc3968057d..e5e47295541 100644 --- a/source/qdk_package/tests-integration/resources/adaptive_ri/output/SwitchHandling.ll +++ b/source/qdk_package/tests-integration/resources/adaptive_ri/output/SwitchHandling.ll @@ -10,35 +10,35 @@ block_0: call void @__quantum__qis__x__body(%Qubit* inttoptr (i64 1 to %Qubit*)) call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) call void @__quantum__qis__m__body(%Qubit* inttoptr (i64 1 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) - %var_6 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 0 to %Result*)) - br i1 %var_6, label %block_1, label %block_2 + %var_7 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 0 to %Result*)) + br i1 %var_7, label %block_1, label %block_2 block_1: br label %block_2 block_2: - %var_16 = phi i64 [0, %block_0], [1, %block_1] - %var_8 = shl i64 %var_16, 1 - %var_9 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 1 to %Result*)) - br i1 %var_9, label %block_3, label %block_4 + %var_17 = phi i64 [0, %block_0], [1, %block_1] + %var_9 = shl i64 %var_17, 1 + %var_10 = call i1 @__quantum__rt__read_result(%Result* inttoptr (i64 1 to %Result*)) + br i1 %var_10, label %block_3, label %block_4 block_3: - %var_11 = add i64 %var_8, 1 + %var_12 = add i64 %var_9, 1 br label %block_4 block_4: - %var_17 = phi i64 [%var_8, %block_2], [%var_11, %block_3] + %var_18 = phi i64 [%var_9, %block_2], [%var_12, %block_3] call void @__quantum__qis__reset__body(%Qubit* inttoptr (i64 0 to %Qubit*)) call void @__quantum__qis__reset__body(%Qubit* inttoptr (i64 1 to %Qubit*)) - %var_13 = icmp eq i64 %var_17, 0 - br i1 %var_13, label %block_5, label %block_6 + %var_14 = icmp eq i64 %var_18, 0 + br i1 %var_14, label %block_5, label %block_6 block_5: br label %block_13 block_6: - %var_14 = icmp eq i64 %var_17, 1 - br i1 %var_14, label %block_7, label %block_8 + %var_15 = icmp eq i64 %var_18, 1 + br i1 %var_15, label %block_7, label %block_8 block_7: call void @__quantum__qis__ry__body(double 3.141592653589793, %Qubit* inttoptr (i64 2 to %Qubit*)) br label %block_12 block_8: - %var_15 = icmp eq i64 %var_17, 2 - br i1 %var_15, label %block_9, label %block_10 + %var_16 = icmp eq i64 %var_18, 2 + br i1 %var_16, label %block_9, label %block_10 block_9: call void @__quantum__qis__rz__body(double 3.141592653589793, %Qubit* inttoptr (i64 2 to %Qubit*)) br label %block_11 diff --git a/source/samples_test/src/tests/OpenQASM.rs b/source/samples_test/src/tests/OpenQASM.rs index 42f76baa062..6cbff677b1a 100644 --- a/source/samples_test/src/tests/OpenQASM.rs +++ b/source/samples_test/src/tests/OpenQASM.rs @@ -22,7 +22,7 @@ pub const BERNSTEINVAZIRANI_EXPECT_DEBUG: Expect = expect!["[One, Zero, One, Zer pub const BERNSTEINVAZIRANI_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 4341"]; pub const BERNSTEINVAZIRANI_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 4548"]; -pub const BERNSTEINVAZIRANI_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 5429"]; +pub const BERNSTEINVAZIRANI_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 7007"]; pub const GROVER_EXPECT: Expect = expect!["[Zero, One, Zero, One, Zero]"]; pub const GROVER_EXPECT_DEBUG: Expect = expect!["[Zero, One, Zero, One, Zero]"]; pub const GROVER_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 33215"]; diff --git a/source/samples_test/src/tests/algorithms.rs b/source/samples_test/src/tests/algorithms.rs index 49280f4f50f..4b843984415 100644 --- a/source/samples_test/src/tests/algorithms.rs +++ b/source/samples_test/src/tests/algorithms.rs @@ -11,7 +11,7 @@ pub const BERNSTEINVAZIRANI_EXPECT_DEBUG: Expect = expect!["[127, 238, 512]"]; pub const BERNSTEINVAZIRANI_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 29822"]; pub const BERNSTEINVAZIRANI_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 20277"]; -pub const BERNSTEINVAZIRANI_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 18472"]; +pub const BERNSTEINVAZIRANI_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 14329"]; pub const BERNSTEINVAZIRANINISQ_EXPECT: Expect = expect!["[One, Zero, One, Zero, One]"]; pub const BERNSTEINVAZIRANINISQ_EXPECT_DEBUG: Expect = expect!["[One, Zero, One, Zero, One]"]; pub const BERNSTEINVAZIRANINISQ_EXPECT_CIRCUIT: Expect = @@ -37,8 +37,8 @@ pub const BITFLIPCODE_EXPECT_DEBUG: Expect = expect![[r#" |111⟩: 0.8944+0.0000𝑖 One"#]]; pub const BITFLIPCODE_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 8068"]; -pub const BITFLIPCODE_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 3794"]; -pub const BITFLIPCODE_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 5385"]; +pub const BITFLIPCODE_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 3796"]; +pub const BITFLIPCODE_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 5387"]; pub const DEUTSCHJOZSA_EXPECT: Expect = expect!["[true, false, true, false]"]; pub const DEUTSCHJOZSA_EXPECT_DEBUG: Expect = expect!["[true, false, true, false]"]; pub const DEUTSCHJOZSA_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 197703"]; @@ -99,7 +99,7 @@ pub const HIDDENSHIFT_EXPECT_DEBUG: Expect = expect![[r#" [170, 512, 999]"#]]; pub const HIDDENSHIFT_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 42131"]; pub const HIDDENSHIFT_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 25479"]; -pub const HIDDENSHIFT_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 29687"]; +pub const HIDDENSHIFT_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 25427"]; pub const HIDDENSHIFTNISQ_EXPECT: Expect = expect!["[One, Zero, Zero, Zero, Zero, One]"]; pub const HIDDENSHIFTNISQ_EXPECT_DEBUG: Expect = expect!["[One, Zero, Zero, Zero, Zero, One]"]; pub const HIDDENSHIFTNISQ_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 4379"]; @@ -153,12 +153,12 @@ pub const PHASEFLIPCODE_EXPECT_DEBUG: Expect = expect![[r#" One"#]]; pub const PHASEFLIPCODE_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 9784"]; pub const PHASEFLIPCODE_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 4734"]; -pub const PHASEFLIPCODE_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 7605"]; +pub const PHASEFLIPCODE_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 7607"]; pub const QRNG_EXPECT: Expect = expect!["7568811972615905454"]; pub const QRNG_EXPECT_DEBUG: Expect = expect!["7568811972615905454"]; pub const QRNG_EXPECT_CIRCUIT: Expect = expect!["generated circuit of length 232827"]; -pub const QRNG_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 36023"]; -pub const QRNG_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 31004"]; +pub const QRNG_EXPECT_QIR_ADAPTIVE_RIF: Expect = expect!["generated QIR of length 36067"]; +pub const QRNG_EXPECT_QIR_ADAPTIVE: Expect = expect!["generated QIR of length 16247"]; pub const SHOR_EXPECT: Expect = expect![[r#" *** Factorizing 187, attempt 1. Estimating period of 182.