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.