From 48344549a4e743d96f88d27313602a23d64fa9b8 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Tue, 9 Feb 2021 14:12:04 -0800 Subject: [PATCH 01/14] Rebased. --- src/QirRuntime/lib/QIR/bridge-qis.ll | 6 +++ src/QirRuntime/lib/QIR/intrinsicsMath.cpp | 20 +++++++ src/QirRuntime/lib/QIR/quantum__qis.hpp | 1 + .../lib/QIR/quantum__qis_internal.hpp | 18 +++++++ .../test/QIR-static/qir-test-math.cpp | 53 +++++++++++++++++++ .../test/QIR-static/qsharp/qir-test-arrays.qs | 1 + .../test/QIR-static/qsharp/qir-test-math.qs | 4 ++ 7 files changed, 103 insertions(+) create mode 100644 src/QirRuntime/lib/QIR/quantum__qis_internal.hpp diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index 1c93d58f0fe..5ac10aa43f1 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -292,6 +292,7 @@ declare i1 @quantum__qis__isnan__body(double %d) declare double @quantum__qis__infinity__body() declare i1 @quantum__qis__isinf__body(double %d) declare double @quantum__qis__arctan2__body(double %y, double %x) +declare i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) ; API for the user code: define double @__quantum__qis__nan__body() { ; Q#: function NAN() : Double http://www.cplusplus.com/reference/cmath/nan-function/ @@ -336,3 +337,8 @@ define double @__quantum__qis__arctan2__body(double %y, double %x) { ; Q#: func %result = call double @quantum__qis__arctan2__body(double %y, double %x) ret double %result } + +define i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { ; operation DrawRandomInt (min : Int, max : Int) : Int https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint + %result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) + ret i64 %result +} diff --git a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp index a3b97e420e9..e026e9040bd 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp @@ -2,11 +2,16 @@ // Licensed under the MIT License. #include +#include +#include #include "quantum__qis.hpp" +#include "quantum__qis_internal.hpp" extern "C" { +char const excStrDrawRandomInt[] = "Invalid Argument: minimum > maximum for DrawRandomInt()"; + // Implementations: bool quantum__qis__isnan__body(double d) { @@ -28,4 +33,19 @@ double quantum__qis__arctan2__body(double y, double x) return std::atan2(y, x); // https://en.cppreference.com/w/cpp/numeric/math/atan2 } +int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum) +{ + if(minimum > maximum) + { + throw std::invalid_argument( excStrDrawRandomInt ); + } + + // https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution + // https://en.cppreference.com/w/cpp/numeric/random + thread_local static std::random_device rd; + thread_local static std::mt19937_64 gen(rd()); + + return std::uniform_int_distribution(minimum, maximum)(gen); +} + } // extern "C" diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QIR/quantum__qis.hpp index 50e8c249016..4584db22e41 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis.hpp @@ -64,5 +64,6 @@ extern "C" QIR_SHARED_API double quantum__qis__infinity__body(); // NOLINT QIR_SHARED_API bool quantum__qis__isinf__body(double d); // NOLINT QIR_SHARED_API double quantum__qis__arctan2__body(double y, double x); // NOLINT + QIR_SHARED_API int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum); // NOLINT } \ No newline at end of file diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp new file mode 100644 index 00000000000..96e1f81309c --- /dev/null +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -0,0 +1,18 @@ +#pragma once + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// To be included by the QIS implementation and QIS tests only. +// Not to be included by parties outside QIS. + +#ifdef _WIN32 +#define QIR_SHARED_API __declspec(dllexport) +#else +#define QIR_SHARED_API +#endif + +extern "C" +{ + QIR_SHARED_API extern char const excStrDrawRandomInt[]; // = "Invalid Argument: minimum > maximum for DrawRandomInt()"; +} diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 27ccea024f0..d398f97c3a6 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -1,12 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include +#include #include "catch.hpp" +#include "quantum__qis_internal.hpp" + extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body(); // NOLINT extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__LogTest__body(); // NOLINT extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(int64_t min, int64_t max); // NOLINT TEST_CASE("QIR: Math.Sqrt", "[qir.math][qir.Math.Sqrt]") { @@ -23,3 +27,52 @@ TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") REQUIRE(0 == Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body()); } +TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") +{ + // Range of the generated random numbers: + constexpr int64_t minimum = -1024; + constexpr int64_t maximum = 1023; + constexpr size_t count = maximum - minimum + 1; // How many numbers are in the range. + + size_t genAverage = 1000; // Each number should be generated ~1000 times. + size_t times = count * genAverage; // How many times to draw. + + std::vector counters(count, 0); // How many times each random number has been generated. + + // Count how many times each random number has been generated. + while(--times) + { + const int64_t randomNumber = + Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(minimum, maximum); + REQUIRE(minimum <= randomNumber); + REQUIRE(randomNumber <= maximum); + + // Increment the counter for this number: + const int64_t index = randomNumber - minimum; + REQUIRE(0 <= index); + REQUIRE(index < counters.size()); + ++(counters[index]); + } + + // Make sure that each number has been generated, and the distribution is approximately uniform: + for(auto counter : counters) + { + REQUIRE((genAverage - 300) < counter); // The random number has been generated > 700 times (of expected 1000). + REQUIRE(counter < (genAverage + 300)); // The random number has been generated < 1300 times (of expected 1000). + } + + // Make sure the exception std::invalid_argument is thrown if min > max: + REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(10, 5), + std::invalid_argument); + // Check the exception string: + try + { + (void)Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(10, 5); + } + catch(std::invalid_argument const & exc) + { + REQUIRE(0 == strcmp(exc.what(), excStrDrawRandomInt)); + } + +} + diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs index f46e7a06bc4..608f259be55 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs @@ -40,6 +40,7 @@ namespace Microsoft.Quantum.Testing.QIR { let res5 = LogTest(); let res6 = ArcTan2Test(); let res7 = PauliToStringTest(); + let res8 = DrawRandomIntTest(0, 1); } return sum; } diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs index bdca70c30b9..a7def82ff79 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs @@ -60,5 +60,9 @@ namespace Microsoft.Quantum.Testing.QIR.Math { return 0; } + operation DrawRandomIntTest(min : Int, max : Int) : Int { + return DrawRandomInt(min, max); + } + } From c83107133a6e2ef69493239ef952aab16d46f155 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Tue, 9 Feb 2021 18:53:17 -0800 Subject: [PATCH 02/14] Added __quantum__qis__message__body ( function Message (msg : String) : Unit ) --- src/QirRuntime/lib/QIR/CMakeLists.txt | 1 + src/QirRuntime/lib/QIR/bridge-qis.ll | 10 ++++ src/QirRuntime/lib/QIR/quantum__qis.hpp | 3 ++ src/QirRuntime/test/QIR-static/CMakeLists.txt | 1 + .../test/QIR-static/qir-test-ouput.cpp | 48 +++++++++++++++++++ .../test/QIR-static/qir-test-output.qs | 14 ++++++ .../test/QIR-static/qsharp/qir-test-arrays.qs | 2 + 7 files changed, 79 insertions(+) create mode 100644 src/QirRuntime/test/QIR-static/qir-test-ouput.cpp create mode 100644 src/QirRuntime/test/QIR-static/qir-test-output.qs diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index a90b95c7e71..48d8e755119 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -51,6 +51,7 @@ compile_from_qir(bridge-qis ${bridge_qis_target}) set(qis_sup_source_files "intrinsics.cpp" "intrinsicsMath.cpp" + intrinsicsOut.cpp ) add_library(qir-qis-support ${qis_sup_source_files}) diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index 5ac10aa43f1..e74225676bd 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -60,6 +60,8 @@ declare void @quantum__qis__y__ctl(%struct.QirArray*, %class.QUBIT*) declare void @quantum__qis__z__body(%class.QUBIT*) declare void @quantum__qis__z__ctl(%struct.QirArray*, %class.QUBIT*) +declare void @quantum__qis__message__body(%"struct.QirString"* %str) + ;=============================================================================== ; quantum.qis namespace implementations ; @@ -279,6 +281,14 @@ define void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) { } +;=============================================================================== +; +define void @__quantum__qis__message__body(%String* %.str) { + %str = bitcast %String* %.str to %"struct.QirString"* + call void @quantum__qis__message__body(%"struct.QirString"* %str) + ret void +} + ;=============================================================================== ; quantum.qis math functions ; diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QIR/quantum__qis.hpp index 4584db22e41..05ba85cb338 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis.hpp @@ -60,6 +60,9 @@ extern "C" QIR_SHARED_API void quantum__qis__z__body(QUBIT*); // NOLINT QIR_SHARED_API void quantum__qis__z__ctl(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__message__body(QirString* qstr); // NOLINT + + // Q# Math: QIR_SHARED_API bool quantum__qis__isnan__body(double d); // NOLINT QIR_SHARED_API double quantum__qis__infinity__body(); // NOLINT QIR_SHARED_API bool quantum__qis__isinf__body(double d); // NOLINT diff --git a/src/QirRuntime/test/QIR-static/CMakeLists.txt b/src/QirRuntime/test/QIR-static/CMakeLists.txt index 838e1f36f47..a9754805783 100644 --- a/src/QirRuntime/test/QIR-static/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-static/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(qir-static-tests qir-driver.cpp qir-test-math.cpp qir-test-strings.cpp + qir-test-ouput.cpp ) target_link_libraries(qir-static-tests PUBLIC diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp new file mode 100644 index 00000000000..9af3c6a7e00 --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include +#include + +#include "catch.hpp" + +#include "qirTypes.hpp" + +extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(QirString*); // NOLINT + + +// https://stackoverflow.com/a/5419388/6362941 +struct CoutRedirector +{ + CoutRedirector( std::streambuf * newBuffer ) + : old( std::cout.rdbuf( newBuffer ) ) // Redirect std::cout to new_buffer. + {} + + ~CoutRedirector() + { + REQUIRE_NOTHROW( std::cout.rdbuf( old ) ); // Redirect std::cout back to stdout. + } + +private: + std::streambuf * old; +}; + + +TEST_CASE("QIR: Out.Message", "[qir.Out][qir.Out.Message]") +{ + std::string testStr1 = "Test String 1"; + std::string testStr2 = "Test String 2"; + std::stringstream coutBuffer; + + { + CoutRedirector coutRedirector(coutBuffer.rdbuf()); // Redirect std::cout to coutBuffer. + + // Print something to std::cout: + QirString qstr{std::string(testStr1)}; + Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(&qstr); + qstr.str = testStr2; + Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(&qstr); + + } // Recover std::cout. + + REQUIRE(coutBuffer.str() == (testStr1 + "\n" + testStr2 + "\n")); +} diff --git a/src/QirRuntime/test/QIR-static/qir-test-output.qs b/src/QirRuntime/test/QIR-static/qir-test-output.qs new file mode 100644 index 00000000000..d2180b5c75d --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-test-output.qs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Testing.QIR.Out { + + open Microsoft.Quantum.Intrinsic; + + function MessageTest(msg: String) : Unit + { + Message( msg ); + } + +} // namespace Microsoft.Quantum.Testing.QIR.Out + diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs index 608f259be55..b3a629e87e6 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs @@ -4,6 +4,7 @@ namespace Microsoft.Quantum.Testing.QIR { open Microsoft.Quantum.Testing.QIR.Math; open Microsoft.Quantum.Testing.QIR.Str; + open Microsoft.Quantum.Testing.QIR.Out; @EntryPoint() operation Test_Arrays(array : Int[], index : Int, val : Int, compilerDecoy : Bool) : Int { @@ -41,6 +42,7 @@ namespace Microsoft.Quantum.Testing.QIR { let res6 = ArcTan2Test(); let res7 = PauliToStringTest(); let res8 = DrawRandomIntTest(0, 1); + MessageTest("Test"); } return sum; } From ed30a99e2623861a70ddc12fe6ee7918f6c98154 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Wed, 10 Feb 2021 11:37:15 -0800 Subject: [PATCH 03/14] CR changes. Build fix. --- src/QirRuntime/lib/QIR/allocationsTracker.cpp | 2 +- src/QirRuntime/lib/QIR/allocationsTracker.hpp | 2 +- src/QirRuntime/lib/QIR/arrays.cpp | 2 +- src/QirRuntime/lib/QIR/bridge-qis.ll | 2 +- src/QirRuntime/lib/QIR/bridge-rt.ll | 2 +- src/QirRuntime/lib/QIR/callables.cpp | 2 +- src/QirRuntime/lib/QIR/context.cpp | 2 +- src/QirRuntime/lib/QIR/context.hpp | 2 +- src/QirRuntime/lib/QIR/delegated.cpp | 2 +- src/QirRuntime/lib/QIR/intrinsics.cpp | 2 +- src/QirRuntime/lib/QIR/intrinsicsOut.cpp | 15 +++++++++++++++ src/QirRuntime/lib/QIR/qirTypes.hpp | 2 +- src/QirRuntime/lib/QIR/quantum__qis.hpp | 2 +- src/QirRuntime/lib/QIR/quantum__qis_internal.hpp | 2 +- src/QirRuntime/lib/QIR/quantum__rt.hpp | 2 +- src/QirRuntime/lib/QIR/strings.cpp | 2 +- src/QirRuntime/lib/QIR/utils.cpp | 2 +- src/QirRuntime/test/QIR-static/qir-driver.cpp | 2 +- src/QirRuntime/test/QIR-static/qir-test-math.cpp | 8 ++++---- src/QirRuntime/test/QIR-static/qir-test-output.qs | 3 +-- .../test/QIR-static/qsharp/qir-test-arrays.qs | 4 ++-- .../test/QIR-static/qsharp/qir-test-math.qs | 2 +- .../test/QIR-static/qsharp/qir-test-partials.qs | 2 +- 23 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 src/QirRuntime/lib/QIR/intrinsicsOut.cpp diff --git a/src/QirRuntime/lib/QIR/allocationsTracker.cpp b/src/QirRuntime/lib/QIR/allocationsTracker.cpp index fe32e677538..2eaf5613b87 100644 --- a/src/QirRuntime/lib/QIR/allocationsTracker.cpp +++ b/src/QirRuntime/lib/QIR/allocationsTracker.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "allocationsTracker.hpp" diff --git a/src/QirRuntime/lib/QIR/allocationsTracker.hpp b/src/QirRuntime/lib/QIR/allocationsTracker.hpp index 020d4e77834..b5621ed2850 100644 --- a/src/QirRuntime/lib/QIR/allocationsTracker.hpp +++ b/src/QirRuntime/lib/QIR/allocationsTracker.hpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once diff --git a/src/QirRuntime/lib/QIR/arrays.cpp b/src/QirRuntime/lib/QIR/arrays.cpp index 1e65b6831d4..b7cd195a8ed 100644 --- a/src/QirRuntime/lib/QIR/arrays.cpp +++ b/src/QirRuntime/lib/QIR/arrays.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index e74225676bd..a5ec4c32eef 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -1,4 +1,4 @@ -; Copyright (c) Microsoft Corporation. All rights reserved. +; Copyright (c) Microsoft Corporation. ; Licensed under the MIT License. ; The __quantum__qis__* definitions should be automatically generated by QIR, depending on the specific target. diff --git a/src/QirRuntime/lib/QIR/bridge-rt.ll b/src/QirRuntime/lib/QIR/bridge-rt.ll index dba25ad0067..d7712b0d8d8 100644 --- a/src/QirRuntime/lib/QIR/bridge-rt.ll +++ b/src/QirRuntime/lib/QIR/bridge-rt.ll @@ -1,4 +1,4 @@ -; Copyright (c) Microsoft Corporation. All rights reserved. +; Copyright (c) Microsoft Corporation. ; Licensed under the MIT License. ;======================================================================================================================= diff --git a/src/QirRuntime/lib/QIR/callables.cpp b/src/QirRuntime/lib/QIR/callables.cpp index 0ec5ddc54ba..752f109e810 100644 --- a/src/QirRuntime/lib/QIR/callables.cpp +++ b/src/QirRuntime/lib/QIR/callables.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include diff --git a/src/QirRuntime/lib/QIR/context.cpp b/src/QirRuntime/lib/QIR/context.cpp index 81dbc1a9ac0..531c9157ecf 100644 --- a/src/QirRuntime/lib/QIR/context.cpp +++ b/src/QirRuntime/lib/QIR/context.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include diff --git a/src/QirRuntime/lib/QIR/context.hpp b/src/QirRuntime/lib/QIR/context.hpp index e3719cd32f1..672eef42660 100644 --- a/src/QirRuntime/lib/QIR/context.hpp +++ b/src/QirRuntime/lib/QIR/context.hpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once diff --git a/src/QirRuntime/lib/QIR/delegated.cpp b/src/QirRuntime/lib/QIR/delegated.cpp index 1eadee7f826..f3d82253f3c 100644 --- a/src/QirRuntime/lib/QIR/delegated.cpp +++ b/src/QirRuntime/lib/QIR/delegated.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. /*============================================================================= diff --git a/src/QirRuntime/lib/QIR/intrinsics.cpp b/src/QirRuntime/lib/QIR/intrinsics.cpp index 301047a345b..d2ebb99eb2c 100644 --- a/src/QirRuntime/lib/QIR/intrinsics.cpp +++ b/src/QirRuntime/lib/QIR/intrinsics.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. /*============================================================================= diff --git a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp new file mode 100644 index 00000000000..ef08f96e8b3 --- /dev/null +++ b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include + +#include "qirTypes.hpp" +#include "quantum__qis.hpp" + +extern "C" +{ + void quantum__qis__message__body(QirString* qstr) // NOLINT + { + std::cout << qstr->str << std::endl; + } +} // extern "C" diff --git a/src/QirRuntime/lib/QIR/qirTypes.hpp b/src/QirRuntime/lib/QIR/qirTypes.hpp index e8db8ccf4e7..a9ca03fa72f 100644 --- a/src/QirRuntime/lib/QIR/qirTypes.hpp +++ b/src/QirRuntime/lib/QIR/qirTypes.hpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QIR/quantum__qis.hpp index 05ba85cb338..8e80cd80404 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis.hpp @@ -4,7 +4,7 @@ #include "CoreTypes.hpp" -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #ifdef _WIN32 diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp index 96e1f81309c..63d92bc2e56 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -1,6 +1,6 @@ #pragma once -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // To be included by the QIS implementation and QIS tests only. diff --git a/src/QirRuntime/lib/QIR/quantum__rt.hpp b/src/QirRuntime/lib/QIR/quantum__rt.hpp index 40679a99895..a3e26a05c8f 100644 --- a/src/QirRuntime/lib/QIR/quantum__rt.hpp +++ b/src/QirRuntime/lib/QIR/quantum__rt.hpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #pragma once diff --git a/src/QirRuntime/lib/QIR/strings.cpp b/src/QirRuntime/lib/QIR/strings.cpp index 0435329a1ef..90679a5dc1f 100644 --- a/src/QirRuntime/lib/QIR/strings.cpp +++ b/src/QirRuntime/lib/QIR/strings.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include diff --git a/src/QirRuntime/lib/QIR/utils.cpp b/src/QirRuntime/lib/QIR/utils.cpp index 8fb77d8ff07..8ae3e7b98df 100644 --- a/src/QirRuntime/lib/QIR/utils.cpp +++ b/src/QirRuntime/lib/QIR/utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include diff --git a/src/QirRuntime/test/QIR-static/qir-driver.cpp b/src/QirRuntime/test/QIR-static/qir-driver.cpp index 79f9cfdcca4..1c143af5d0a 100644 --- a/src/QirRuntime/test/QIR-static/qir-driver.cpp +++ b/src/QirRuntime/test/QIR-static/qir-driver.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index d398f97c3a6..b4f92836969 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -10,7 +10,7 @@ extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body(); // NOLINT extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__LogTest__body(); // NOLINT extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body(); // NOLINT -extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(int64_t min, int64_t max); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(int64_t min, int64_t max); // NOLINT TEST_CASE("QIR: Math.Sqrt", "[qir.math][qir.Math.Sqrt]") { @@ -43,7 +43,7 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") while(--times) { const int64_t randomNumber = - Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(minimum, maximum); + Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(minimum, maximum); REQUIRE(minimum <= randomNumber); REQUIRE(randomNumber <= maximum); @@ -62,12 +62,12 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") } // Make sure the exception std::invalid_argument is thrown if min > max: - REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(10, 5), + REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5), std::invalid_argument); // Check the exception string: try { - (void)Microsoft__Quantum__Testing__QIR__Math__DrawRandomIntTest__body(10, 5); + (void)Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5); } catch(std::invalid_argument const & exc) { diff --git a/src/QirRuntime/test/QIR-static/qir-test-output.qs b/src/QirRuntime/test/QIR-static/qir-test-output.qs index d2180b5c75d..26479d3664b 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-output.qs +++ b/src/QirRuntime/test/QIR-static/qir-test-output.qs @@ -5,8 +5,7 @@ namespace Microsoft.Quantum.Testing.QIR.Out { open Microsoft.Quantum.Intrinsic; - function MessageTest(msg: String) : Unit - { + function MessageTest(msg: String) : Unit { Message( msg ); } diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs index b3a629e87e6..10154ba9a02 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-arrays.qs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Microsoft.Quantum.Testing.QIR { @@ -41,7 +41,7 @@ namespace Microsoft.Quantum.Testing.QIR { let res5 = LogTest(); let res6 = ArcTan2Test(); let res7 = PauliToStringTest(); - let res8 = DrawRandomIntTest(0, 1); + let res8 = TestDrawRandomInt(0, 1); MessageTest("Test"); } return sum; diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs index a7def82ff79..5bf13d5708d 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs @@ -60,7 +60,7 @@ namespace Microsoft.Quantum.Testing.QIR.Math { return 0; } - operation DrawRandomIntTest(min : Int, max : Int) : Int { + operation TestDrawRandomInt(min : Int, max : Int) : Int { return DrawRandomInt(min, max); } diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-partials.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-partials.qs index 837f09f6286..05e63538699 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-partials.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-partials.qs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace Microsoft.Quantum.Testing.QIR { From 4df9cef5eed449f63f4769cc17fd477b4008ea94 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Wed, 10 Feb 2021 11:55:57 -0800 Subject: [PATCH 04/14] CR changes. --- src/QirRuntime/test/QIR-static/qir-test-math.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index b4f92836969..46fe4b64982 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -29,6 +29,10 @@ TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") { + // Commented out until https://github.com/microsoft/qsharp-runtime/pull/511#discussion_r573978601 + // is resolved. + + /* // Range of the generated random numbers: constexpr int64_t minimum = -1024; constexpr int64_t maximum = 1023; @@ -60,6 +64,7 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") REQUIRE((genAverage - 300) < counter); // The random number has been generated > 700 times (of expected 1000). REQUIRE(counter < (genAverage + 300)); // The random number has been generated < 1300 times (of expected 1000). } + */ // Make sure the exception std::invalid_argument is thrown if min > max: REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5), @@ -75,4 +80,3 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") } } - From 6955e18abb50af3ade896cb55128c442d35dcd54 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Fri, 12 Feb 2021 14:51:24 -0800 Subject: [PATCH 05/14] CR changes. --- src/QirRuntime/lib/QIR/bridge-qis.ll | 4 +++- src/QirRuntime/lib/QIR/intrinsicsMath.cpp | 3 ++- src/QirRuntime/test/QIR-static/qir-test-math.cpp | 7 ++++--- src/QirRuntime/test/QIR-static/qir-test-ouput.cpp | 6 +++--- src/QirRuntime/test/QIR-static/qir-test-output.qs | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index a5ec4c32eef..0230f007999 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -348,7 +348,9 @@ define double @__quantum__qis__arctan2__body(double %y, double %x) { ; Q#: func ret double %result } -define i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { ; operation DrawRandomInt (min : Int, max : Int) : Int https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint +; operation DrawRandomInt (min : Int, max : Int) : Int +; https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint +define i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { %result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) ret i64 %result } diff --git a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp index e026e9040bd..e3a0d6f543d 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp @@ -6,6 +6,7 @@ #include #include "quantum__qis.hpp" #include "quantum__qis_internal.hpp" +#include "quantum__rt.hpp" extern "C" { @@ -37,7 +38,7 @@ int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum) { if(minimum > maximum) { - throw std::invalid_argument( excStrDrawRandomInt ); + quantum__rt__fail(quantum__rt__string_create(excStrDrawRandomInt)); } // https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 46fe4b64982..37017e6d7ce 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -66,15 +66,16 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") } */ - // Make sure the exception std::invalid_argument is thrown if min > max: + // Make sure the correct exception is thrown if min > max: REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5), - std::invalid_argument); + std::runtime_error); + // Check the exception string: try { (void)Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5); } - catch(std::invalid_argument const & exc) + catch(std::runtime_error const & exc) { REQUIRE(0 == strcmp(exc.what(), excStrDrawRandomInt)); } diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 9af3c6a7e00..353b01de48d 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -13,13 +13,13 @@ extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(QirStri // https://stackoverflow.com/a/5419388/6362941 struct CoutRedirector { - CoutRedirector( std::streambuf * newBuffer ) - : old( std::cout.rdbuf( newBuffer ) ) // Redirect std::cout to new_buffer. + CoutRedirector(std::streambuf * newBuffer) + : old(std::cout.rdbuf(newBuffer)) // Redirect std::cout to new_buffer. {} ~CoutRedirector() { - REQUIRE_NOTHROW( std::cout.rdbuf( old ) ); // Redirect std::cout back to stdout. + REQUIRE_NOTHROW(std::cout.rdbuf(old)); // Redirect std::cout back to stdout. } private: diff --git a/src/QirRuntime/test/QIR-static/qir-test-output.qs b/src/QirRuntime/test/QIR-static/qir-test-output.qs index 26479d3664b..17efad96151 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-output.qs +++ b/src/QirRuntime/test/QIR-static/qir-test-output.qs @@ -6,7 +6,7 @@ namespace Microsoft.Quantum.Testing.QIR.Out { open Microsoft.Quantum.Intrinsic; function MessageTest(msg: String) : Unit { - Message( msg ); + Message(msg); } } // namespace Microsoft.Quantum.Testing.QIR.Out From dbaa7618fe8e51137d8f1c7fb84e9a933e0018e6 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Fri, 12 Feb 2021 17:44:30 -0800 Subject: [PATCH 06/14] CR changes. Fixed the output. --- src/QirRuntime/lib/QIR/intrinsicsOut.cpp | 20 ++++++++++++- .../lib/QIR/quantum__qis_internal.hpp | 2 ++ .../test/QIR-static/qir-test-ouput.cpp | 30 +++++++++++-------- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp index ef08f96e8b3..6c91a23bf25 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp @@ -6,10 +6,28 @@ #include "qirTypes.hpp" #include "quantum__qis.hpp" +namespace +{ + std::ostream * currOStream = &std::cout; + + std::ostream& GetQOstream() + { + return *currOStream; + } + +} // namespace + +std::ostream& SetQOstream(std::ostream & newOStream) +{ + std::ostream& oldOStream = *currOStream; + currOStream = &newOStream; + return oldOStream; +} + extern "C" { void quantum__qis__message__body(QirString* qstr) // NOLINT { - std::cout << qstr->str << std::endl; + GetQOstream() << qstr->str << std::endl; } } // extern "C" diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp index 63d92bc2e56..936d8dfcd9f 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -16,3 +16,5 @@ extern "C" { QIR_SHARED_API extern char const excStrDrawRandomInt[]; // = "Invalid Argument: minimum > maximum for DrawRandomInt()"; } + +QIR_SHARED_API extern std::ostream& SetQOstream(std::ostream & newOStream); \ No newline at end of file diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 353b01de48d..4db624f0d64 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -6,43 +6,47 @@ #include "catch.hpp" #include "qirTypes.hpp" +#include "quantum__qis_internal.hpp" extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(QirString*); // NOLINT // https://stackoverflow.com/a/5419388/6362941 -struct CoutRedirector +// https://github.com/microsoft/qsharp-runtime/pull/511#discussion_r574170031 +// https://github.com/microsoft/qsharp-runtime/pull/511#discussion_r574194191 +struct QOstreamRedirector { - CoutRedirector(std::streambuf * newBuffer) - : old(std::cout.rdbuf(newBuffer)) // Redirect std::cout to new_buffer. + QOstreamRedirector(std::ostream & newOstream) + : old(SetQOstream(newOstream)) {} - ~CoutRedirector() + ~QOstreamRedirector() { - REQUIRE_NOTHROW(std::cout.rdbuf(old)); // Redirect std::cout back to stdout. + SetQOstream(old); } private: - std::streambuf * old; + std::ostream& old; }; TEST_CASE("QIR: Out.Message", "[qir.Out][qir.Out.Message]") { - std::string testStr1 = "Test String 1"; - std::string testStr2 = "Test String 2"; - std::stringstream coutBuffer; + const std::string testStr1 = "Test String 1"; + const std::string testStr2 = "Test String 2"; + + std::ostringstream outStrStream; { - CoutRedirector coutRedirector(coutBuffer.rdbuf()); // Redirect std::cout to coutBuffer. + QOstreamRedirector qOStreamRedirector(outStrStream); - // Print something to std::cout: + // Log something: QirString qstr{std::string(testStr1)}; Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(&qstr); qstr.str = testStr2; Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(&qstr); - } // Recover std::cout. + } // Recover the output stream. - REQUIRE(coutBuffer.str() == (testStr1 + "\n" + testStr2 + "\n")); + REQUIRE(outStrStream.str() == (testStr1 + "\n" + testStr2 + "\n")); } From 0ba6ab0199fd943b0ec2f6122dd10b688aa061a4 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Fri, 12 Feb 2021 18:33:28 -0800 Subject: [PATCH 07/14] Rebased. --- src/QirRuntime/test/QIR-static/qir-gen.ll | 1691 +++++++++++++++++ src/QirRuntime/test/QIR-static/qsharp/Math.qs | 6 +- .../{ => qsharp}/qir-test-output.qs | 0 3 files changed, 1696 insertions(+), 1 deletion(-) create mode 100644 src/QirRuntime/test/QIR-static/qir-gen.ll rename src/QirRuntime/test/QIR-static/{ => qsharp}/qir-test-output.qs (100%) diff --git a/src/QirRuntime/test/QIR-static/qir-gen.ll b/src/QirRuntime/test/QIR-static/qir-gen.ll new file mode 100644 index 00000000000..c7b421285b5 --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-gen.ll @@ -0,0 +1,1691 @@ + +%Result = type opaque +%Range = type { i64, i64, i64 } +%Tuple = type opaque +%Callable = type opaque +%Qubit = type opaque +%String = type opaque +%Array = type opaque + +@ResultZero = external global %Result* +@ResultOne = external global %Result* +@PauliI = constant i2 0 +@PauliX = constant i2 1 +@PauliY = constant i2 -1 +@PauliZ = constant i2 -2 +@EmptyRange = internal constant %Range { i64 0, i64 1, i64 -1 } +@Microsoft__Quantum__Testing__QIR__Qop = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper] +@PartialApplication__1 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__ctladj__wrapper] +@MemoryManagement__1 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__1__RefCount, void (%Tuple*, i64)* @MemoryManagement__1__AliasCount] +@0 = internal constant [14 x i8] c"error code: 1\00" +@1 = internal constant [14 x i8] c"error code: 2\00" +@2 = internal constant [14 x i8] c"error code: 3\00" +@3 = internal constant [14 x i8] c"error code: 2\00" +@4 = internal constant [14 x i8] c"error code: 5\00" +@5 = internal constant [14 x i8] c"error code: 6\00" +@6 = internal constant [14 x i8] c"error code: 7\00" +@7 = internal constant [30 x i8] c"Unexpected measurement result\00" +@8 = internal constant [5 x i8] c"Test\00" +@Microsoft__Quantum__Testing__QIR__Subtract = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@PartialApplication__2 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@MemoryManagement__2 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__2__RefCount, void (%Tuple*, i64)* @MemoryManagement__2__AliasCount] +@9 = internal constant [20 x i8] c"Pauli value: PauliI\00" +@10 = internal constant [14 x i8] c"Pauli value: \00" +@11 = internal constant [7 x i8] c"PauliX\00" +@12 = internal constant [7 x i8] c"PauliY\00" +@13 = internal constant [7 x i8] c"PauliZ\00" + +define void @Microsoft__Quantum__Testing__QIR__TestControlled__body() { +entry: + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %Callable*, i64 }* + %2 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 0 + %3 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 1 + %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Qop, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + store %Callable* %4, %Callable** %2 + store i64 1, i64* %3 + %qop = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %0) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 1) + %adj_qop = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %adj_qop) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 1) + %ctl_qop = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %ctl_qop) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 1) + %adj_ctl_qop = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %adj_ctl_qop) + call void @__quantum__rt__callable_make_adjoint(%Callable* %adj_ctl_qop) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 1) + %ctl_ctl_qop = call %Callable* @__quantum__rt__callable_copy(%Callable* %ctl_qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %ctl_ctl_qop) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 1) + %q1 = call %Qubit* @__quantum__rt__qubit_allocate() + %q2 = call %Qubit* @__quantum__rt__qubit_allocate() + %q3 = call %Qubit* @__quantum__rt__qubit_allocate() + %5 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %6 = bitcast %Tuple* %5 to { %Qubit* }* + %7 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %6, i32 0, i32 0 + store %Qubit* %q1, %Qubit** %7 + call void @__quantum__rt__callable_invoke(%Callable* %qop, %Tuple* %5, %Tuple* null) + %8 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q1) + %9 = load %Result*, %Result** @ResultOne + %10 = call i1 @__quantum__rt__result_equal(%Result* %8, %Result* %9) + %11 = xor i1 %10, true + br i1 %11, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + %12 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @0, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %12) + unreachable + +continue__1: ; preds = %entry + %13 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %14 = bitcast %Tuple* %13 to { %Qubit* }* + %15 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %14, i32 0, i32 0 + store %Qubit* %q2, %Qubit** %15 + call void @__quantum__rt__callable_invoke(%Callable* %adj_qop, %Tuple* %13, %Tuple* null) + %16 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q2) + %17 = load %Result*, %Result** @ResultOne + %18 = call i1 @__quantum__rt__result_equal(%Result* %16, %Result* %17) + %19 = xor i1 %18, true + br i1 %19, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + %20 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @1, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %20) + unreachable + +continue__2: ; preds = %continue__1 + %21 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %22 = bitcast %Tuple* %21 to { %Array*, %Qubit* }* + %23 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %22, i32 0, i32 0 + %24 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %22, i32 0, i32 1 + %25 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %26 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %25, i64 0) + %27 = bitcast i8* %26 to %Qubit** + store %Qubit* %q1, %Qubit** %27 + store %Array* %25, %Array** %23 + store %Qubit* %q3, %Qubit** %24 + call void @__quantum__rt__callable_invoke(%Callable* %ctl_qop, %Tuple* %21, %Tuple* null) + %28 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q3) + %29 = load %Result*, %Result** @ResultOne + %30 = call i1 @__quantum__rt__result_equal(%Result* %28, %Result* %29) + %31 = xor i1 %30, true + br i1 %31, label %then0__3, label %continue__3 + +then0__3: ; preds = %continue__2 + %32 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @2, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %25, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %21, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %32) + unreachable + +continue__3: ; preds = %continue__2 + %33 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %34 = bitcast %Tuple* %33 to { %Array*, %Qubit* }* + %35 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %34, i32 0, i32 0 + %36 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %34, i32 0, i32 1 + %37 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %38 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %37, i64 0) + %39 = bitcast i8* %38 to %Qubit** + store %Qubit* %q2, %Qubit** %39 + store %Array* %37, %Array** %35 + store %Qubit* %q3, %Qubit** %36 + call void @__quantum__rt__callable_invoke(%Callable* %adj_ctl_qop, %Tuple* %33, %Tuple* null) + %40 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q3) + %41 = load %Result*, %Result** @ResultZero + %42 = call i1 @__quantum__rt__result_equal(%Result* %40, %Result* %41) + %43 = xor i1 %42, true + br i1 %43, label %then0__4, label %continue__4 + +then0__4: ; preds = %continue__3 + %44 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @3, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %25, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %21, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %37, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %40, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %44) + unreachable + +continue__4: ; preds = %continue__3 + %45 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %46 = bitcast %Tuple* %45 to { %Array*, { %Array*, %Qubit* }* }* + %47 = getelementptr inbounds { %Array*, { %Array*, %Qubit* }* }, { %Array*, { %Array*, %Qubit* }* }* %46, i32 0, i32 0 + %48 = getelementptr inbounds { %Array*, { %Array*, %Qubit* }* }, { %Array*, { %Array*, %Qubit* }* }* %46, i32 0, i32 1 + %49 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %50 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %49, i64 0) + %51 = bitcast i8* %50 to %Qubit** + store %Qubit* %q1, %Qubit** %51 + %52 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %53 = bitcast %Tuple* %52 to { %Array*, %Qubit* }* + %54 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %53, i32 0, i32 0 + %55 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %53, i32 0, i32 1 + %56 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %57 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %56, i64 0) + %58 = bitcast i8* %57 to %Qubit** + store %Qubit* %q2, %Qubit** %58 + store %Array* %56, %Array** %54 + store %Qubit* %q3, %Qubit** %55 + store %Array* %49, %Array** %47 + store { %Array*, %Qubit* }* %53, { %Array*, %Qubit* }** %48 + call void @__quantum__rt__callable_invoke(%Callable* %ctl_ctl_qop, %Tuple* %45, %Tuple* null) + %59 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q3) + %60 = load %Result*, %Result** @ResultOne + %61 = call i1 @__quantum__rt__result_equal(%Result* %59, %Result* %60) + %62 = xor i1 %61, true + br i1 %62, label %then0__5, label %continue__5 + +then0__5: ; preds = %continue__4 + %63 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @4, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %25, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %21, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %37, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %40, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %49, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %56, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %52, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %45, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %63) + unreachable + +continue__5: ; preds = %continue__4 + %64 = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %64, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %64) + %65 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %66 = bitcast %Tuple* %65 to { %Array*, %Qubit* }* + %67 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %66, i32 0, i32 0 + %68 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %66, i32 0, i32 1 + %69 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 2) + %70 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %69, i64 0) + %71 = bitcast i8* %70 to %Qubit** + %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %69, i64 1) + %73 = bitcast i8* %72 to %Qubit** + store %Qubit* %q1, %Qubit** %71 + store %Qubit* %q2, %Qubit** %73 + store %Array* %69, %Array** %67 + store %Qubit* %q3, %Qubit** %68 + call void @__quantum__rt__callable_invoke(%Callable* %64, %Tuple* %65, %Tuple* null) + %74 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q3) + %75 = load %Result*, %Result** @ResultZero + %76 = call i1 @__quantum__rt__result_equal(%Result* %74, %Result* %75) + %77 = xor i1 %76, true + br i1 %77, label %then0__6, label %continue__6 + +then0__6: ; preds = %continue__5 + %78 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @5, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %25, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %21, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %37, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %40, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %49, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %56, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %52, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %45, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %64, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %64, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %69, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %65, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %74, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %78) + unreachable + +continue__6: ; preds = %continue__5 + %q4 = call %Qubit* @__quantum__rt__qubit_allocate() + %79 = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %79, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %79) + %80 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %81 = bitcast %Tuple* %80 to { %Qubit* }* + %82 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %81, i32 0, i32 0 + store %Qubit* %q3, %Qubit** %82 + call void @__quantum__rt__callable_invoke(%Callable* %79, %Tuple* %80, %Tuple* null) + %83 = call %Callable* @__quantum__rt__callable_copy(%Callable* %ctl_ctl_qop, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %83, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %83) + call void @__quantum__rt__callable_make_adjoint(%Callable* %83) + %84 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %85 = bitcast %Tuple* %84 to { %Array*, { %Array*, { %Array*, %Qubit* }* }* }* + %86 = getelementptr inbounds { %Array*, { %Array*, { %Array*, %Qubit* }* }* }, { %Array*, { %Array*, { %Array*, %Qubit* }* }* }* %85, i32 0, i32 0 + %87 = getelementptr inbounds { %Array*, { %Array*, { %Array*, %Qubit* }* }* }, { %Array*, { %Array*, { %Array*, %Qubit* }* }* }* %85, i32 0, i32 1 + %88 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %89 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %88, i64 0) + %90 = bitcast i8* %89 to %Qubit** + store %Qubit* %q1, %Qubit** %90 + %91 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %92 = bitcast %Tuple* %91 to { %Array*, { %Array*, %Qubit* }* }* + %93 = getelementptr inbounds { %Array*, { %Array*, %Qubit* }* }, { %Array*, { %Array*, %Qubit* }* }* %92, i32 0, i32 0 + %94 = getelementptr inbounds { %Array*, { %Array*, %Qubit* }* }, { %Array*, { %Array*, %Qubit* }* }* %92, i32 0, i32 1 + %95 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %96 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %95, i64 0) + %97 = bitcast i8* %96 to %Qubit** + store %Qubit* %q2, %Qubit** %97 + %98 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %99 = bitcast %Tuple* %98 to { %Array*, %Qubit* }* + %100 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %99, i32 0, i32 0 + %101 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %99, i32 0, i32 1 + %102 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %103 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %102, i64 0) + %104 = bitcast i8* %103 to %Qubit** + store %Qubit* %q3, %Qubit** %104 + store %Array* %102, %Array** %100 + store %Qubit* %q4, %Qubit** %101 + store %Array* %95, %Array** %93 + store { %Array*, %Qubit* }* %99, { %Array*, %Qubit* }** %94 + store %Array* %88, %Array** %86 + store { %Array*, { %Array*, %Qubit* }* }* %92, { %Array*, { %Array*, %Qubit* }* }** %87 + call void @__quantum__rt__callable_invoke(%Callable* %83, %Tuple* %84, %Tuple* null) + %105 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q4) + %106 = load %Result*, %Result** @ResultOne + %107 = call i1 @__quantum__rt__result_equal(%Result* %105, %Result* %106) + %108 = xor i1 %107, true + br i1 %108, label %then0__7, label %continue__7 + +then0__7: ; preds = %continue__6 + %109 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @6, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q4) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %79, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %79, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %80, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %83, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %83, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %88, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %95, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %102, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %98, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %91, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %84, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %105, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %25, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %21, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %37, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %40, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %49, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %56, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %52, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %45, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %64, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %64, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %69, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %65, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %74, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__fail(%String* %109) + unreachable + +continue__7: ; preds = %continue__6 + call void @__quantum__rt__qubit_release(%Qubit* %q4) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %79, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %79, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %80, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %83, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %83, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %88, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %95, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %102, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %98, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %91, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %84, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %105, i64 -1) + call void @__quantum__rt__qubit_release(%Qubit* %q1) + call void @__quantum__rt__qubit_release(%Qubit* %q2) + call void @__quantum__rt__qubit_release(%Qubit* %q3) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %13, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %16, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %25, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %21, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %37, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %40, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %49, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %56, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %52, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %45, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %64, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %64, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %69, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %65, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %74, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %adj_ctl_qop, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %ctl_ctl_qop, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %ctl_ctl_qop, i64 -1) + ret void +} + +declare %Tuple* @__quantum__rt__tuple_create(i64) + +define void @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %3 = load %Qubit*, %Qubit** %1 + %4 = load i64, i64* %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %3, i64 %4) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %3 = load %Qubit*, %Qubit** %1 + %4 = load i64, i64* %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %3, i64 %4) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* + %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %3, { %Qubit*, i64 }* %4) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* + %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %3, { %Qubit*, i64 }* %4) + ret void +} + +declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) + +define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* + %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 + %2 = load %Qubit*, %Qubit** %1 + %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* + %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 + store %Qubit* %2, %Qubit** %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__1__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* + %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 + %2 = load %Qubit*, %Qubit** %1 + %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* + %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 + store %Qubit* %2, %Qubit** %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + %12 = call %Callable* @__quantum__rt__callable_copy(%Callable* %11, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %12) + call void @__quantum__rt__callable_invoke(%Callable* %12, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %12, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__1__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* + %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load %Qubit*, %Qubit** %2 + %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 + %7 = load i64, i64* %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* + %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 + store %Qubit* %4, %Qubit** %10 + store i64 %7, i64* %11 + %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* + %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 + %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 + store %Array* %3, %Array** %14 + store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 + %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 + %17 = load %Callable*, %Callable** %16 + %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %18) + call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__1__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* + %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load %Qubit*, %Qubit** %2 + %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 + %7 = load i64, i64* %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* + %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 + store %Qubit* %4, %Qubit** %10 + store i64 %7, i64* %11 + %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* + %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 + %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 + store %Array* %3, %Array** %14 + store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 + %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 + %17 = load %Callable*, %Callable** %16 + %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %18) + call void @__quantum__rt__callable_make_controlled(%Callable* %18) + call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + ret void +} + +define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @MemoryManagement__1__AliasCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) + +declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) + +declare %Callable* @__quantum__rt__callable_copy(%Callable*, i1) + +declare void @__quantum__rt__callable_make_adjoint(%Callable*) + +declare void @__quantum__rt__callable_make_controlled(%Callable*) + +declare %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) + +define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qubit) { +entry: + %bases = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %bases, i64 0) + %1 = bitcast i8* %0 to i2* + %2 = load i2, i2* @PauliZ + store i2 %2, i2* %1 + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) + %qubits = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %3 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %4 = bitcast i8* %3 to %Qubit** + store %Qubit* %qubit, %Qubit** %4 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %5 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qubits, i64 -1) + ret %Result* %5 +} + +declare i1 @__quantum__rt__result_equal(%Result*, %Result*) + +declare %String* @__quantum__rt__string_create(i32, i8*) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) + +declare void @__quantum__rt__fail(%String*) + +declare %Array* @__quantum__rt__array_create_1d(i32, i64) + +declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) + +declare void @__quantum__rt__array_update_reference_count(%Array*, i64) + +define void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() { +entry: + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %1 = bitcast i8* %0 to %Qubit** + %qubit = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__x__body(%Qubit* %qubit) + %q = call %Qubit* @__quantum__rt__qubit_allocate() + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %3 = bitcast i8* %2 to %Qubit** + %4 = load %Qubit*, %Qubit** %3 + %5 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %4) + %6 = load %Result*, %Result** @ResultOne + %7 = call i1 @__quantum__rt__result_equal(%Result* %5, %Result* %6) + br i1 %7, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__x__body(%Qubit* %q) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %9 = bitcast i8* %8 to %Qubit** + %10 = load %Qubit*, %Qubit** %9 + %11 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %10) + %12 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) + %13 = call i1 @__quantum__rt__result_equal(%Result* %11, %Result* %12) + br i1 %13, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + %14 = call %String* @__quantum__rt__string_create(i32 29, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @7, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__qubit_release_array(%Array* %qs) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + call void @__quantum__rt__fail(%String* %14) + unreachable + +continue__2: ; preds = %continue__1 + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) + call void @__quantum__rt__qubit_release_array(%Array* %qs) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + ret void +} + +declare void @__quantum__rt__array_update_alias_count(%Array*, i64) + +declare void @__quantum__qis__x__body(%Qubit*) + +declare void @__quantum__rt__qubit_release_array(%Array*) + +define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %array, i64 %index, i64 %val, i1 %compilerDecoy) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) + %local = alloca %Array* + store %Array* %array, %Array** %local + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) + call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) + %0 = call %Array* @__quantum__rt__array_copy(%Array* %array, i1 false) + %1 = icmp ne %Array* %array, %0 + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %index) + %3 = bitcast i8* %2 to i64* + store i64 %val, i64* %3 + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 1) + store %Array* %0, %Array** %local + %n = call i64 @__quantum__rt__array_get_size_1d(%Array* %0) + %4 = sub i64 %n, 1 + %5 = load %Range, %Range* @EmptyRange + %6 = insertvalue %Range %5, i64 %index, 0 + %7 = insertvalue %Range %6, i64 1, 1 + %8 = insertvalue %Range %7, i64 %4, 2 + %slice1 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %8, i1 false) + call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 1) + %9 = load %Range, %Range* @EmptyRange + %10 = insertvalue %Range %9, i64 %index, 0 + %11 = insertvalue %Range %10, i64 -2, 1 + %12 = insertvalue %Range %11, i64 0, 2 + %slice2 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %12, i1 false) + call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 1) + %result = call %Array* @__quantum__rt__array_concatenate(%Array* %slice2, %Array* %slice1) + call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 1) + %sum = alloca i64 + store i64 0, i64* %sum + %13 = call i64 @__quantum__rt__array_get_size_1d(%Array* %result) + %14 = sub i64 %13, 1 + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %21, %exiting__1 ] + %15 = icmp sle i64 %i, %14 + br i1 %15, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %16 = load i64, i64* %sum + %17 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %result, i64 %i) + %18 = bitcast i8* %17 to i64* + %19 = load i64, i64* %18 + %20 = add i64 %16, %19 + store i64 %20, i64* %sum + br label %exiting__1 + +exiting__1: ; preds = %body__1 + %21 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + br i1 %compilerDecoy, label %then0__1, label %continue__1 + +then0__1: ; preds = %exit__1 + call void @Microsoft__Quantum__Testing__QIR__TestControlled__body() + %res2 = call i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 17, i64 42) + call void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() + %res4 = call i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() + %res5 = call i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() + %res6 = call i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() + %res7 = call i64 @Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body() + %res8 = call i64 @Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(i64 0, i64 1) + %22 = call %String* @__quantum__rt__string_create(i32 4, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @8, i32 0, i32 0)) + call void @Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(%String* %22) + call void @__quantum__rt__string_update_reference_count(%String* %22, i64 -1) + br label %continue__1 + +continue__1: ; preds = %then0__1, %exit__1 + %23 = load i64, i64* %sum + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %slice1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %slice2, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %result, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + ret i64 %23 +} + +declare %Array* @__quantum__rt__array_copy(%Array*, i1) + +declare i64 @__quantum__rt__array_get_size_1d(%Array*) + +declare %Array* @__quantum__rt__array_slice_1d(%Array*, %Range, i1) + +declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) + +define i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 %x, i64 %y) { +entry: + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %Callable*, i64 }* + %2 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 0 + %3 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 1 + %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Subtract, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + store %Callable* %4, %Callable** %2 + store i64 %x, i64* %3 + %subtractor = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %0) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 1) + %5 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) + %6 = bitcast %Tuple* %5 to { i64 }* + %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 + store i64 %y, i64* %7 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) + call void @__quantum__rt__callable_invoke(%Callable* %subtractor, %Tuple* %5, %Tuple* %8) + %9 = bitcast %Tuple* %8 to { i64 }* + %10 = getelementptr inbounds { i64 }, { i64 }* %9, i32 0, i32 0 + %11 = load i64, i64* %10 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %subtractor, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret i64 %11 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() { +entry: + %0 = call double @__quantum__qis__sqrt__body(double 4.000000e+00) + %1 = fcmp one double 2.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + ret i64 1 + +continue__1: ; preds = %entry + %2 = call double @__quantum__qis__sqrt__body(double 9.000000e+00) + %3 = fcmp one double 3.000000e+00, %2 + br i1 %3, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + ret i64 2 + +continue__2: ; preds = %continue__1 + %4 = call double @__quantum__qis__sqrt__body(double 1.000000e+02) + %5 = fcmp one double 1.000000e+01, %4 + br i1 %5, label %then0__3, label %continue__3 + +then0__3: ; preds = %continue__2 + ret i64 3 + +continue__3: ; preds = %continue__2 + %d__4 = call double @__quantum__qis__sqrt__body(double -5.000000e+00) + %6 = call i1 @__quantum__qis__isnan__body(double %d__4) + %7 = xor i1 %6, true + br i1 %7, label %then0__4, label %continue__4 + +then0__4: ; preds = %continue__3 + ret i64 4 + +continue__4: ; preds = %continue__3 + %d__5 = call double @__quantum__qis__nan__body() + %d__6 = call double @__quantum__qis__sqrt__body(double %d__5) + %8 = call i1 @__quantum__qis__isnan__body(double %d__6) + %9 = xor i1 %8, true + br i1 %9, label %then0__5, label %continue__5 + +then0__5: ; preds = %continue__4 + ret i64 5 + +continue__5: ; preds = %continue__4 + %d__7 = call double @__quantum__qis__infinity__body() + %d__8 = call double @__quantum__qis__sqrt__body(double %d__7) + %10 = call i1 @__quantum__qis__isinf__body(double %d__8) + %11 = xor i1 %10, true + br i1 %11, label %then0__6, label %continue__6 + +then0__6: ; preds = %continue__5 + ret i64 6 + +continue__6: ; preds = %continue__5 + ret i64 0 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() { +entry: + %input = call double @Microsoft__Quantum__Math__E__body() + %0 = call double @__quantum__qis__log__body(double %input) + %1 = fcmp one double 1.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + ret i64 1 + +continue__1: ; preds = %entry + %2 = call double @Microsoft__Quantum__Math__E__body() + %3 = call double @Microsoft__Quantum__Math__E__body() + %input__1 = fmul double %2, %3 + %4 = call double @__quantum__qis__log__body(double %input__1) + %5 = fcmp one double 2.000000e+00, %4 + br i1 %5, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + ret i64 2 + +continue__2: ; preds = %continue__1 + %d = call double @__quantum__qis__log__body(double 0.000000e+00) + %6 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) + %7 = xor i1 %6, true + br i1 %7, label %then0__3, label %continue__3 + +then0__3: ; preds = %continue__2 + ret i64 3 + +continue__3: ; preds = %continue__2 + %d__1 = call double @__quantum__qis__log__body(double -5.000000e+00) + %8 = call i1 @__quantum__qis__isnan__body(double %d__1) + %9 = xor i1 %8, true + br i1 %9, label %then0__4, label %continue__4 + +then0__4: ; preds = %continue__3 + ret i64 4 + +continue__4: ; preds = %continue__3 + %input__4 = call double @__quantum__qis__nan__body() + %d__2 = call double @__quantum__qis__log__body(double %input__4) + %10 = call i1 @__quantum__qis__isnan__body(double %d__2) + %11 = xor i1 %10, true + br i1 %11, label %then0__5, label %continue__5 + +then0__5: ; preds = %continue__4 + ret i64 5 + +continue__5: ; preds = %continue__4 + %input__5 = call double @__quantum__qis__infinity__body() + %d__3 = call double @__quantum__qis__log__body(double %input__5) + %12 = call i1 @__quantum__qis__isinf__body(double %d__3) + %13 = xor i1 %12, true + br i1 %13, label %then0__6, label %continue__6 + +then0__6: ; preds = %continue__5 + ret i64 6 + +continue__6: ; preds = %continue__5 + ret i64 0 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() { +entry: + %0 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double 1.000000e+00) + %1 = fcmp one double 0.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + ret i64 1 + +continue__1: ; preds = %entry + %2 = call double @Microsoft__Quantum__Math__PI__body() + %3 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double -1.000000e+00) + %4 = fcmp one double %2, %3 + br i1 %4, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + ret i64 2 + +continue__2: ; preds = %continue__1 + %5 = call double @Microsoft__Quantum__Math__PI__body() + %6 = fdiv double %5, 2.000000e+00 + %7 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double 0.000000e+00) + %8 = fcmp one double %6, %7 + br i1 %8, label %then0__3, label %continue__3 + +then0__3: ; preds = %continue__2 + ret i64 3 + +continue__3: ; preds = %continue__2 + %9 = call double @Microsoft__Quantum__Math__PI__body() + %10 = fneg double %9 + %11 = fdiv double %10, 2.000000e+00 + %12 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double 0.000000e+00) + %13 = fcmp one double %11, %12 + br i1 %13, label %then0__4, label %continue__4 + +then0__4: ; preds = %continue__3 + ret i64 4 + +continue__4: ; preds = %continue__3 + %14 = call double @Microsoft__Quantum__Math__PI__body() + %15 = fdiv double %14, 4.000000e+00 + %16 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double 1.000000e+00) + %17 = fcmp one double %15, %16 + br i1 %17, label %then0__5, label %continue__5 + +then0__5: ; preds = %continue__4 + ret i64 5 + +continue__5: ; preds = %continue__4 + %18 = call double @Microsoft__Quantum__Math__PI__body() + %19 = fmul double %18, 3.000000e+00 + %20 = fdiv double %19, 4.000000e+00 + %21 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double -1.000000e+00) + %22 = fcmp one double %20, %21 + br i1 %22, label %then0__6, label %continue__6 + +then0__6: ; preds = %continue__5 + ret i64 6 + +continue__6: ; preds = %continue__5 + %23 = call double @Microsoft__Quantum__Math__PI__body() + %24 = fneg double %23 + %25 = fmul double %24, 3.000000e+00 + %26 = fdiv double %25, 4.000000e+00 + %27 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double -1.000000e+00) + %28 = fcmp one double %26, %27 + br i1 %28, label %then0__7, label %continue__7 + +then0__7: ; preds = %continue__6 + ret i64 7 + +continue__7: ; preds = %continue__6 + %29 = call double @Microsoft__Quantum__Math__PI__body() + %30 = fneg double %29 + %31 = fdiv double %30, 4.000000e+00 + %32 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double 1.000000e+00) + %33 = fcmp one double %31, %32 + br i1 %33, label %then0__8, label %continue__8 + +then0__8: ; preds = %continue__7 + ret i64 8 + +continue__8: ; preds = %continue__7 + %34 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double 0.000000e+00) + %35 = fcmp one double 0.000000e+00, %34 + br i1 %35, label %then0__9, label %continue__9 + +then0__9: ; preds = %continue__8 + ret i64 9 + +continue__9: ; preds = %continue__8 + %y__9 = call double @__quantum__qis__nan__body() + %d = call double @__quantum__qis__arctan2__body(double %y__9, double 0.000000e+00) + %36 = call i1 @__quantum__qis__isnan__body(double %d) + %37 = xor i1 %36, true + br i1 %37, label %then0__10, label %continue__10 + +then0__10: ; preds = %continue__9 + ret i64 11 + +continue__10: ; preds = %continue__9 + %x__10 = call double @__quantum__qis__nan__body() + %d__1 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double %x__10) + %38 = call i1 @__quantum__qis__isnan__body(double %d__1) + %39 = xor i1 %38, true + br i1 %39, label %then0__11, label %continue__11 + +then0__11: ; preds = %continue__10 + ret i64 12 + +continue__11: ; preds = %continue__10 + %y__11 = call double @__quantum__qis__nan__body() + %x__11 = call double @__quantum__qis__nan__body() + %d__2 = call double @__quantum__qis__arctan2__body(double %y__11, double %x__11) + %40 = call i1 @__quantum__qis__isnan__body(double %d__2) + %41 = xor i1 %40, true + br i1 %41, label %then0__12, label %continue__12 + +then0__12: ; preds = %continue__11 + ret i64 13 + +continue__12: ; preds = %continue__11 + ret i64 0 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body() { +entry: + %0 = call %String* @__quantum__rt__string_create(i32 19, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @9, i32 0, i32 0)) + %1 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @10, i32 0, i32 0)) + %2 = load i2, i2* @PauliI + %3 = call %String* @__quantum__rt__pauli_to_string(i2 %2) + %4 = call %String* @__quantum__rt__string_concatenate(%String* %1, %String* %3) + call void @__quantum__rt__string_update_reference_count(%String* %1, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %3, i64 -1) + %5 = call i1 @__quantum__rt__string_equal(%String* %0, %String* %4) + %6 = xor i1 %5, true + br i1 %6, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__rt__string_update_reference_count(%String* %0, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %4, i64 -1) + ret i64 1 + +continue__1: ; preds = %entry + %7 = call %String* @__quantum__rt__string_create(i32 6, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @11, i32 0, i32 0)) + %8 = load i2, i2* @PauliX + %9 = call %String* @__quantum__rt__pauli_to_string(i2 %8) + %10 = call i1 @__quantum__rt__string_equal(%String* %7, %String* %9) + %11 = xor i1 %10, true + br i1 %11, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + call void @__quantum__rt__string_update_reference_count(%String* %0, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %4, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %7, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %9, i64 -1) + ret i64 2 + +continue__2: ; preds = %continue__1 + %12 = call %String* @__quantum__rt__string_create(i32 6, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @12, i32 0, i32 0)) + %13 = load i2, i2* @PauliY + %14 = call %String* @__quantum__rt__pauli_to_string(i2 %13) + %15 = call i1 @__quantum__rt__string_equal(%String* %12, %String* %14) + %16 = xor i1 %15, true + br i1 %16, label %then0__3, label %continue__3 + +then0__3: ; preds = %continue__2 + call void @__quantum__rt__string_update_reference_count(%String* %0, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %4, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %7, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %9, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %12, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %14, i64 -1) + ret i64 3 + +continue__3: ; preds = %continue__2 + %17 = call %String* @__quantum__rt__string_create(i32 6, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @13, i32 0, i32 0)) + %18 = load i2, i2* @PauliZ + %19 = call %String* @__quantum__rt__pauli_to_string(i2 %18) + %20 = call i1 @__quantum__rt__string_equal(%String* %17, %String* %19) + %21 = xor i1 %20, true + br i1 %21, label %then0__4, label %continue__4 + +then0__4: ; preds = %continue__3 + call void @__quantum__rt__string_update_reference_count(%String* %0, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %4, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %7, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %9, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %12, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %14, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %17, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %19, i64 -1) + ret i64 4 + +continue__4: ; preds = %continue__3 + call void @__quantum__rt__string_update_reference_count(%String* %0, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %4, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %7, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %9, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %12, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %14, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %17, i64 -1) + call void @__quantum__rt__string_update_reference_count(%String* %19, i64 -1) + ret i64 0 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(i64 %min, i64 %max) { +entry: + %0 = call i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) + ret i64 %0 +} + +define void @Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(%String* %msg) { +entry: + call void @__quantum__qis__message__body(%String* %msg) + ret void +} + +declare void @__quantum__rt__string_update_reference_count(%String*, i64) + +define void @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { i64, i64 }* + %1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %0, i32 0, i32 1 + %3 = load i64, i64* %1 + %4 = load i64, i64* %2 + %5 = call i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %3, i64 %4) + %6 = bitcast %Tuple* %result-tuple to { i64 }* + %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 + store i64 %5, i64* %7 + ret void +} + +define void @Lifted__PartialApplication__2__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 1 + %2 = load i64, i64* %1 + %3 = bitcast %Tuple* %arg-tuple to { i64 }* + %4 = getelementptr inbounds { i64 }, { i64 }* %3, i32 0, i32 0 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 2)) + %7 = bitcast %Tuple* %6 to { i64, i64 }* + %8 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 1 + store i64 %2, i64* %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + ret void +} + +define void @MemoryManagement__2__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @MemoryManagement__2__AliasCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) { +entry: + %0 = srem i64 %n, 2 + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__k__body(%Qubit* %q) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + ret void +} + +declare void @__quantum__qis__k__body(%Qubit*) + +define void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %q, i64 %n) { +entry: + call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %ctrls, { %Qubit*, i64 }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %n = load i64, i64* %2 + %3 = srem i64 %n, 2 + %4 = icmp eq i64 %3, 1 + br i1 %4, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) + call void @__quantum__qis__k__ctl(%Array* %ctrls, %Qubit* %q) + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) + ret void +} + +declare void @__quantum__qis__k__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %__controlQubits__, { %Qubit*, i64 }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %n = load i64, i64* %2 + %3 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %4 = bitcast %Tuple* %3 to { %Qubit*, i64 }* + %5 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 0 + %6 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 1 + store %Qubit* %q, %Qubit** %5 + store i64 %n, i64* %6 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %__controlQubits__, { %Qubit*, i64 }* %4) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %3, i64 -1) + ret void +} + +define i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %from, i64 %what) { +entry: + %0 = sub i64 %from, %what + ret i64 %0 +} + +define i1 @Microsoft__Quantum__Intrinsic__IsInf__body(double %d) { +entry: + %0 = call i1 @__quantum__qis__isinf__body(double %d) + ret i1 %0 +} + +declare i1 @__quantum__qis__isinf__body(double) + +define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qubit) { +entry: + call void @__quantum__qis__x__body(%Qubit* %qubit) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %qubit) { +entry: + call void @__quantum__qis__x__body(%Qubit* %qubit) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %__controlQubits__, %Qubit* %qubit) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__x__ctl(%Array* %__controlQubits__, %Qubit* %qubit) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +declare void @__quantum__qis__x__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__X__ctladj(%Array* %__controlQubits__, %Qubit* %qubit) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__x__ctl(%Array* %__controlQubits__, %Qubit* %qubit) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define double @Microsoft__Quantum__Intrinsic__NAN__body() { +entry: + %0 = call double @__quantum__qis__nan__body() + ret double %0 +} + +declare double @__quantum__qis__nan__body() + +define i1 @Microsoft__Quantum__Intrinsic__IsNegativeInfinity__body(double %d) { +entry: + %0 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) + ret i1 %0 +} + +declare i1 @__quantum__qis__isnegativeinfinity__body(double) + +define i64 @Microsoft__Quantum__Intrinsic__DrawRandomInt__body(i64 %min, i64 %max) { +entry: + %0 = call i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) + ret i64 %0 +} + +declare i64 @__quantum__qis__drawrandomint__body(i64, i64) + +define i1 @Microsoft__Quantum__Intrinsic__IsNan__body(double %d) { +entry: + %0 = call i1 @__quantum__qis__isnan__body(double %d) + ret i1 %0 +} + +declare i1 @__quantum__qis__isnan__body(double) + +define void @Microsoft__Quantum__Intrinsic__Message__body(%String* %msg) { +entry: + call void @__quantum__qis__message__body(%String* %msg) + ret void +} + +declare void @__quantum__qis__message__body(%String*) + +define double @Microsoft__Quantum__Intrinsic__INFINITY__body() { +entry: + %0 = call double @__quantum__qis__infinity__body() + ret double %0 +} + +declare double @__quantum__qis__infinity__body() + +define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %bases, %Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) + +define void @Microsoft__Quantum__Intrinsic__K__body(%Qubit* %q) { +entry: + call void @__quantum__qis__k__body(%Qubit* %q) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__K__adj(%Qubit* %q) { +entry: + call void @__quantum__qis__k__body(%Qubit* %q) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__K__ctl(%Array* %__controlQubits__, %Qubit* %q) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__K__ctladj(%Array* %__controlQubits__, %Qubit* %q) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define double @Microsoft__Quantum__Math__E__body() { +entry: + ret double 0x4005BF0A8B145769 +} + +declare double @__quantum__qis__log__body(double) + +declare double @__quantum__qis__sqrt__body(double) + +declare double @__quantum__qis__arctan2__body(double, double) + +define double @Microsoft__Quantum__Math__PI__body() { +entry: + ret double 0x400921FB54442D18 +} + +declare %String* @__quantum__rt__pauli_to_string(i2) + +declare %String* @__quantum__rt__string_concatenate(%String*, %String*) + +declare i1 @__quantum__rt__string_equal(%String*, %String*) + +define double @Microsoft__Quantum__Math__ArcTan2__body(double %y, double %x) { +entry: + %0 = call double @__quantum__qis__arctan2__body(double %y, double %x) + ret double %0 +} + +define double @Microsoft__Quantum__Math__Sqrt__body(double %d) { +entry: + %0 = call double @__quantum__qis__sqrt__body(double %d) + ret double %0 +} + +define double @Microsoft__Quantum__Math__Log__body(double %input) { +entry: + %0 = call double @__quantum__qis__log__body(double %input) + ret double %0 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays(i64 %array__count, i64* %array, i64 %index, i64 %val, i1 %compilerDecoy) #0 { +entry: + %0 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 %array__count) + %1 = icmp sgt i64 %array__count, 0 + br i1 %1, label %copy, label %next + +copy: ; preds = %entry + %2 = ptrtoint i64* %array to i64 + %3 = sub i64 %array__count, 1 + br label %header__1 + +next: ; preds = %exit__1, %entry + %4 = call i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %0, i64 %index, i64 %val, i1 %compilerDecoy) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + ret i64 %4 + +header__1: ; preds = %exiting__1, %copy + %5 = phi i64 [ 0, %copy ], [ %13, %exiting__1 ] + %6 = icmp sle i64 %5, %3 + br i1 %6, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %7 = mul i64 %5, 8 + %8 = add i64 %2, %7 + %9 = inttoptr i64 %8 to i64* + %10 = load i64, i64* %9 + %11 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %5) + %12 = bitcast i8* %11 to i64* + store i64 %10, i64* %12 + br label %exiting__1 + +exiting__1: ; preds = %body__1 + %13 = add i64 %5, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + br label %next +} + +declare void @__quantum__rt__tuple_update_alias_count(%Tuple*, i64) + +attributes #0 = { "EntryPoint" } diff --git a/src/QirRuntime/test/QIR-static/qsharp/Math.qs b/src/QirRuntime/test/QIR-static/qsharp/Math.qs index 12e98bd5458..4785b9ded1b 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/Math.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/Math.qs @@ -28,4 +28,8 @@ namespace Microsoft.Quantum.Intrinsic { body intrinsic; } -} \ No newline at end of file + operation DrawRandomInt(min : Int, max : Int) : Int { + body intrinsic; + } + +} diff --git a/src/QirRuntime/test/QIR-static/qir-test-output.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-output.qs similarity index 100% rename from src/QirRuntime/test/QIR-static/qir-test-output.qs rename to src/QirRuntime/test/QIR-static/qsharp/qir-test-output.qs From fa6faadbd8bd4c4fb8410b503388a362f5c9ac2b Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Fri, 12 Feb 2021 21:54:35 -0800 Subject: [PATCH 08/14] CR Changes. --- src/QirRuntime/lib/QIR/intrinsicsMath.cpp | 34 ++++++-- src/QirRuntime/lib/QIR/intrinsicsOut.cpp | 36 +++++---- .../lib/QIR/quantum__qis_internal.hpp | 8 +- .../test/QIR-static/qir-test-math.cpp | 78 +++++++++++-------- .../test/QIR-static/qir-test-ouput.cpp | 4 +- 5 files changed, 106 insertions(+), 54 deletions(-) diff --git a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp index e3a0d6f543d..413936cf371 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp @@ -8,10 +8,15 @@ #include "quantum__qis_internal.hpp" #include "quantum__rt.hpp" -extern "C" +// Forward declarations: +namespace // Visible in this translation unit only. { + extern thread_local bool seedIsRandom; +} -char const excStrDrawRandomInt[] = "Invalid Argument: minimum > maximum for DrawRandomInt()"; +// Implementation: +extern "C" +{ // Implementations: bool quantum__qis__isnan__body(double d) @@ -38,15 +43,34 @@ int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum) { if(minimum > maximum) { - quantum__rt__fail(quantum__rt__string_create(excStrDrawRandomInt)); + quantum__rt__fail(quantum__rt__string_create(Quantum::Qis::Internal::excStrDrawRandomInt)); } // https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution // https://en.cppreference.com/w/cpp/numeric/random - thread_local static std::random_device rd; - thread_local static std::mt19937_64 gen(rd()); + thread_local static std::mt19937_64 gen(seedIsRandom + ? std::random_device()() : // Default + 0); // For test purposes only. return std::uniform_int_distribution(minimum, maximum)(gen); } } // extern "C" + +namespace // Visible in this translation unit only. +{ + thread_local bool seedIsRandom = true; +} + +// For test purposes only: +namespace Quantum { namespace Qis { namespace Internal +{ + +char const excStrDrawRandomInt[] = "Invalid Argument: minimum > maximum for DrawRandomInt()"; + +void UseRandomSeed(bool random) +{ + seedIsRandom = random; +} + +}}} // namespace Quantum::Qis::Internal diff --git a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp index 6c91a23bf25..b7d9d3571da 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp @@ -6,16 +6,31 @@ #include "qirTypes.hpp" #include "quantum__qis.hpp" -namespace -{ - std::ostream * currOStream = &std::cout; +// Forward declarations: +static std::ostream& GetQOstream(); - std::ostream& GetQOstream() +// Public API: +extern "C" +{ + void quantum__qis__message__body(QirString* qstr) // NOLINT { - return *currOStream; + GetQOstream() << qstr->str << std::endl; } +} // extern "C" + + +// Internal API: +static std::ostream * currOStream = &std::cout; // Log to std::cout by default. + +static std::ostream& GetQOstream() +{ + return *currOStream; +} -} // namespace + +// For test purposes only: +namespace Quantum { namespace Qis { namespace Internal // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. +{ std::ostream& SetQOstream(std::ostream & newOStream) { @@ -24,10 +39,5 @@ std::ostream& SetQOstream(std::ostream & newOStream) return oldOStream; } -extern "C" -{ - void quantum__qis__message__body(QirString* qstr) // NOLINT - { - GetQOstream() << qstr->str << std::endl; - } -} // extern "C" +}}} // namespace Quantum::Qis::Internal + diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp index 936d8dfcd9f..48544d0f69a 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -12,9 +12,11 @@ #define QIR_SHARED_API #endif -extern "C" +// For test purposes only: +namespace Quantum { namespace Qis { namespace Internal // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. { QIR_SHARED_API extern char const excStrDrawRandomInt[]; // = "Invalid Argument: minimum > maximum for DrawRandomInt()"; -} -QIR_SHARED_API extern std::ostream& SetQOstream(std::ostream & newOStream); \ No newline at end of file + QIR_SHARED_API extern std::ostream& SetQOstream(std::ostream & newOStream); + QIR_SHARED_API void UseRandomSeed(bool random); +}}} // namespace Quantum::Qis::Internal diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 37017e6d7ce..5ab8cdded94 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -29,42 +29,59 @@ TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") { - // Commented out until https://github.com/microsoft/qsharp-runtime/pull/511#discussion_r573978601 - // is resolved. - - /* - // Range of the generated random numbers: - constexpr int64_t minimum = -1024; - constexpr int64_t maximum = 1023; - constexpr size_t count = maximum - minimum + 1; // How many numbers are in the range. + // Use const seed (and 100%-predictable sequence of pseudo-random numbers): + Quantum::Qis::Internal::UseRandomSeed(false); + + size_t times = 30; + std::vector actualNumbers; + std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, + -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); + // Get the actual pseudo-random numbers: + actualNumbers.reserve(times); + while(times--) + { + actualNumbers.emplace_back( + Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(-10, 10)); + } - size_t genAverage = 1000; // Each number should be generated ~1000 times. - size_t times = count * genAverage; // How many times to draw. + // Compare the actual numbers with the expected ones: + for(auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); + iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) + { + REQUIRE(*iterExp == *iterAct); + } - std::vector counters(count, 0); // How many times each random number has been generated. - // Count how many times each random number has been generated. - while(--times) + // Repeat for large numbers: + times = 30; + actualNumbers.clear(); + std::vector expectedLargeNumbers( { + -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, + -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, + -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, + 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, + -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, + + -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, + -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, + -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, + 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, + 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ + } ); + + while(times--) { - const int64_t randomNumber = - Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(minimum, maximum); - REQUIRE(minimum <= randomNumber); - REQUIRE(randomNumber <= maximum); - - // Increment the counter for this number: - const int64_t index = randomNumber - minimum; - REQUIRE(0 <= index); - REQUIRE(index < counters.size()); - ++(counters[index]); + actualNumbers.emplace_back( + Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(std::numeric_limits::min(), + std::numeric_limits::max())); } - // Make sure that each number has been generated, and the distribution is approximately uniform: - for(auto counter : counters) + for(auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); + iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) { - REQUIRE((genAverage - 300) < counter); // The random number has been generated > 700 times (of expected 1000). - REQUIRE(counter < (genAverage + 300)); // The random number has been generated < 1300 times (of expected 1000). + REQUIRE(*iterExp == *iterAct); } - */ + // Make sure the correct exception is thrown if min > max: REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5), @@ -77,7 +94,6 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") } catch(std::runtime_error const & exc) { - REQUIRE(0 == strcmp(exc.what(), excStrDrawRandomInt)); + REQUIRE(0 == strcmp(exc.what(), Quantum::Qis::Internal::excStrDrawRandomInt)); } - -} +} // TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 4db624f0d64..048253ea48b 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -17,12 +17,12 @@ extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(QirStri struct QOstreamRedirector { QOstreamRedirector(std::ostream & newOstream) - : old(SetQOstream(newOstream)) + : old(Quantum::Qis::Internal::SetQOstream(newOstream)) {} ~QOstreamRedirector() { - SetQOstream(old); + Quantum::Qis::Internal::SetQOstream(old); } private: From d5754929c5cf0c6f1c3882995a912287ae9f35f5 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Sun, 14 Feb 2021 16:47:35 -0800 Subject: [PATCH 09/14] Instrumented the test output to investigate the Linux and Mac test run failure. --- src/QirRuntime/test/QIR-static/qir-test-math.cpp | 9 +++++++-- src/QirRuntime/test/QIR-static/qir-test-ouput.cpp | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 5ab8cdded94..c2e5ebf2f0c 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include #include +#include #include "catch.hpp" @@ -48,8 +49,10 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") for(auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) { - REQUIRE(*iterExp == *iterAct); + //REQUIRE(*iterExp == *iterAct); + std::cerr << *iterAct << ", "; } + std::cerr << '\n'; // Repeat for large numbers: @@ -79,8 +82,10 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") for(auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) { - REQUIRE(*iterExp == *iterAct); + //REQUIRE(*iterExp == *iterAct); + std::cerr << *iterAct << "(0x" << std::hex << *iterAct << std::dec << "), "; } + std::cerr << '\n'; // Make sure the correct exception is thrown if min > max: diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 048253ea48b..29b6dfe5337 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -38,9 +38,9 @@ TEST_CASE("QIR: Out.Message", "[qir.Out][qir.Out.Message]") std::ostringstream outStrStream; { - QOstreamRedirector qOStreamRedirector(outStrStream); + QOstreamRedirector qOStreamRedirector(outStrStream); // Redirect the output from std::cout to outStrStream. - // Log something: + // Log something (to the redirected output): QirString qstr{std::string(testStr1)}; Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(&qstr); qstr.str = testStr2; From 53971d583f9225e181f99d4b2dce69e1a406435d Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Sun, 14 Feb 2021 17:28:28 -0800 Subject: [PATCH 10/14] Instrumented in more details. --- .../test/QIR-static/qir-test-math.cpp | 76 +++++++++++++++---- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index c2e5ebf2f0c..861fb1fe6ec 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -30,13 +30,61 @@ TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") { +#ifdef _WIN32 + std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, + -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); + std::vector expectedLargeNumbers( { + -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, + -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, + -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, + 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, + -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, + + -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, + -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, + -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, + 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, + 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ + } ); +#elif __APPLE__ + std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, + -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); + std::vector expectedLargeNumbers( { + -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, + -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, + -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, + 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, + -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, + + -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, + -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, + -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, + 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, + 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ + } ); +#else + std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, + -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); + std::vector expectedLargeNumbers( { + -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, + -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, + -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, + 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, + -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, + + -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, + -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, + -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, + 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, + 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ + } ); +#endif + // Use const seed (and 100%-predictable sequence of pseudo-random numbers): Quantum::Qis::Internal::UseRandomSeed(false); size_t times = 30; std::vector actualNumbers; - std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, - -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); // Get the actual pseudo-random numbers: actualNumbers.reserve(times); while(times--) @@ -53,25 +101,16 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") std::cerr << *iterAct << ", "; } std::cerr << '\n'; + for(auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); + iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) + { + CHECK(*iterExp == *iterAct); + } // Repeat for large numbers: times = 30; actualNumbers.clear(); - std::vector expectedLargeNumbers( { - -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, - -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, - -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, - 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, - -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, - - -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, - -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, - -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, - 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, - 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ - } ); - while(times--) { actualNumbers.emplace_back( @@ -86,6 +125,11 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") std::cerr << *iterAct << "(0x" << std::hex << *iterAct << std::dec << "), "; } std::cerr << '\n'; + for(auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); + iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) + { + CHECK(*iterExp == *iterAct); + } // Make sure the correct exception is thrown if min > max: From 86a25c37f5e9b93ceb0fe0bd03edf45c4af4bd33 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Sun, 14 Feb 2021 18:35:18 -0800 Subject: [PATCH 11/14] Added a fix for Linux and Mac. --- .../test/QIR-static/qir-test-math.cpp | 53 ++++++++----------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 861fb1fe6ec..ba7757d36eb 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -30,25 +30,23 @@ TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") { -#ifdef _WIN32 - std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, - -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); +#ifdef __APPLE__ std::vector expectedLargeNumbers( { - -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, - -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, - -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, - 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, - -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, - - -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, - -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, - -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, - 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, - 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ + -2160833387943730151 /*0xe2032d7b74cf6419*/, 7375078072468444798 /*0x66598a6e9c41167e*/, 7708428399011769513 /*0x6af9d6c9b3a12ca9*/, + -8929332642100591101 /*0x8414a3458a4b4603*/, 9131959130339861073 /*0x7ebb3c72234ae251*/, 2129461186021157660 /*0x1d8d5daa93c5eb1c*/, + -4466415676527644493 /*0xc2041a9b355570b3*/, 2654403080104352464 /*0x24d65589a8529ad0*/, 3948910203829515833 /*0x36cd58e87d2c7639*/, + 3600951923571138577 /*0x31f926b221b7a011*/, -7454003569285620820 /*0x988e0f3f2a3c9bac*/, -2896776822558058671 /*0xd7cc94d3e1d79751*/, + -2510694579170103717 /*0xdd2838951d112e5b*/, -8679035075952589054 /*0x878ddf94f8b0c702*/, -8480296875123573728 /*0x8a4feeec30677c20*/, + + -8613430109842542716 /*0x8876f2f3752e6f84*/, 2140032717197149199 /*0x1db2ec6afc40040f*/, -917262003397267527 /*0xf3453b11598aefb9*/, + -3734430349428794203 /*0xcc2ca3620fdbdca5*/, 5134567830016493736 /*0x4741a63cbf4808a8*/, -8243723698983337761 /*0x8d9868f90fa100df*/, + 5560736588152128922 /*0x4d2bb4770253459a*/, 50526560201835791 /* 0xb381a3888d850f*/, 1288735234894005209 /*0x11e281de3d6303d9*/, + 3656101241126025060 /*0x32bd14b53c2e7764*/, 872395409727236160 /* 0xc1b5f00c4792840*/, 7628415731883617240 /*0x69dd93b0e9ecabd8*/, + -1986081594003691539 /*0xe47005501e77e7ed*/, 7532118334194327900 /*0x688775b7d3dc215c*/, -4186893097968929306 /*0xc5e52ae91706f5e6*/ } ); -#elif __APPLE__ - std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, - -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); + std::vector expectedSmallNumbers( { 1, 4, 2, 4, 5, -2, -4, 9, 4, -4, -9, 9, -1, 5, 7, + -8, 0, 2, 5, 0, -1, 1, 9, -3, 5, -8, -9, 6, -1, 6 } ); +#else std::vector expectedLargeNumbers( { -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, @@ -62,23 +60,14 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ } ); -#else +#ifdef _WIN32 std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); - std::vector expectedLargeNumbers( { - -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, - -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, - -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, - 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, - -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, - - -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, - -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, - -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, - 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, - 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ - } ); -#endif +#else + std::vector expectedSmallNumbers( { -7, 10, -10, 2, 1, -9, 3, -2, 7, 9, -2, 3, 9, -3, -5, + -1, 6, 4, 1, -4, -7, 2, 1, -7, -7, -10, 1, 4, -2, 9 } ); +#endif // #ifdef _WIN32 +#endif // #ifdef __APPLE__ // Use const seed (and 100%-predictable sequence of pseudo-random numbers): Quantum::Qis::Internal::UseRandomSeed(false); From d814407b2d1c785d965c3ddde7ac449d245f2b4f Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Sun, 14 Feb 2021 20:11:06 -0800 Subject: [PATCH 12/14] Removed instrumenting after a fix. --- .../test/QIR-static/qir-test-math.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index ba7757d36eb..2f8961a4d72 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -86,14 +86,7 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") for(auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) { - //REQUIRE(*iterExp == *iterAct); - std::cerr << *iterAct << ", "; - } - std::cerr << '\n'; - for(auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); - iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) - { - CHECK(*iterExp == *iterAct); + REQUIRE(*iterExp == *iterAct); } @@ -110,14 +103,7 @@ TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") for(auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) { - //REQUIRE(*iterExp == *iterAct); - std::cerr << *iterAct << "(0x" << std::hex << *iterAct << std::dec << "), "; - } - std::cerr << '\n'; - for(auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); - iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) - { - CHECK(*iterExp == *iterAct); + REQUIRE(*iterExp == *iterAct); } From e9cbe10c9998cc72603bdb37500d5fe3cc782e68 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Tue, 16 Feb 2021 13:07:35 -0800 Subject: [PATCH 13/14] CR changes. --- src/QirRuntime/lib/QIR/bridge-qis.ll | 3 +- src/QirRuntime/lib/QIR/intrinsicsOut.cpp | 2 +- .../lib/QIR/quantum__qis_internal.hpp | 2 +- src/QirRuntime/test/QIR-static/qir-gen.ll | 1457 ++++++++--------- .../test/QIR-static/qir-test-ouput.cpp | 4 +- src/QirRuntime/test/QIR-static/qsharp/Math.qs | 4 - .../test/QIR-static/qsharp/qir-test-math.qs | 1 + 7 files changed, 735 insertions(+), 738 deletions(-) diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index 0230f007999..729b8c77e2e 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -348,8 +348,9 @@ define double @__quantum__qis__arctan2__body(double %y, double %x) { ; Q#: func ret double %result } + ; operation DrawRandomInt (min : Int, max : Int) : Int -; https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint define i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { %result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) ret i64 %result diff --git a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp index b7d9d3571da..fdc919e8e3a 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp @@ -32,7 +32,7 @@ static std::ostream& GetQOstream() namespace Quantum { namespace Qis { namespace Internal // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. { -std::ostream& SetQOstream(std::ostream & newOStream) +std::ostream& SetOutputStream(std::ostream & newOStream) { std::ostream& oldOStream = *currOStream; currOStream = &newOStream; diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp index 48544d0f69a..862103a3511 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -17,6 +17,6 @@ namespace Quantum { namespace Qis { namespace Internal // Replace with `namespa { QIR_SHARED_API extern char const excStrDrawRandomInt[]; // = "Invalid Argument: minimum > maximum for DrawRandomInt()"; - QIR_SHARED_API extern std::ostream& SetQOstream(std::ostream & newOStream); + QIR_SHARED_API extern std::ostream& SetOutputStream(std::ostream & newOStream); QIR_SHARED_API void UseRandomSeed(bool random); }}} // namespace Quantum::Qis::Internal diff --git a/src/QirRuntime/test/QIR-static/qir-gen.ll b/src/QirRuntime/test/QIR-static/qir-gen.ll index c7b421285b5..fcbfdbc3c3b 100644 --- a/src/QirRuntime/test/QIR-static/qir-gen.ll +++ b/src/QirRuntime/test/QIR-static/qir-gen.ll @@ -1,11 +1,10 @@ - %Result = type opaque %Range = type { i64, i64, i64 } %Tuple = type opaque +%Array = type opaque +%String = type opaque %Callable = type opaque %Qubit = type opaque -%String = type opaque -%Array = type opaque @ResultZero = external global %Result* @ResultOne = external global %Result* @@ -14,27 +13,130 @@ @PauliY = constant i2 -1 @PauliZ = constant i2 -2 @EmptyRange = internal constant %Range { i64 0, i64 1, i64 -1 } -@Microsoft__Quantum__Testing__QIR__Qop = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper] -@PartialApplication__1 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__ctladj__wrapper] -@MemoryManagement__1 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__1__RefCount, void (%Tuple*, i64)* @MemoryManagement__1__AliasCount] -@0 = internal constant [14 x i8] c"error code: 1\00" -@1 = internal constant [14 x i8] c"error code: 2\00" -@2 = internal constant [14 x i8] c"error code: 3\00" -@3 = internal constant [14 x i8] c"error code: 2\00" -@4 = internal constant [14 x i8] c"error code: 5\00" -@5 = internal constant [14 x i8] c"error code: 6\00" -@6 = internal constant [14 x i8] c"error code: 7\00" -@7 = internal constant [30 x i8] c"Unexpected measurement result\00" -@8 = internal constant [5 x i8] c"Test\00" +@0 = internal constant [5 x i8] c"Test\00" @Microsoft__Quantum__Testing__QIR__Subtract = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] -@PartialApplication__2 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@PartialApplication__1 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@MemoryManagement__1 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__1__RefCount, void (%Tuple*, i64)* @MemoryManagement__1__AliasCount] +@1 = internal constant [30 x i8] c"Unexpected measurement result\00" +@Microsoft__Quantum__Testing__QIR__Qop = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper] +@PartialApplication__2 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__ctladj__wrapper] @MemoryManagement__2 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__2__RefCount, void (%Tuple*, i64)* @MemoryManagement__2__AliasCount] +@2 = internal constant [14 x i8] c"error code: 1\00" +@3 = internal constant [14 x i8] c"error code: 2\00" +@4 = internal constant [14 x i8] c"error code: 3\00" +@5 = internal constant [14 x i8] c"error code: 2\00" +@6 = internal constant [14 x i8] c"error code: 5\00" +@7 = internal constant [14 x i8] c"error code: 6\00" +@8 = internal constant [14 x i8] c"error code: 7\00" @9 = internal constant [20 x i8] c"Pauli value: PauliI\00" @10 = internal constant [14 x i8] c"Pauli value: \00" @11 = internal constant [7 x i8] c"PauliX\00" @12 = internal constant [7 x i8] c"PauliY\00" @13 = internal constant [7 x i8] c"PauliZ\00" +define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %array, i64 %index, i64 %val, i1 %compilerDecoy) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) + %local = alloca %Array* + store %Array* %array, %Array** %local + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) + call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) + %0 = call %Array* @__quantum__rt__array_copy(%Array* %array, i1 false) + %1 = icmp ne %Array* %array, %0 + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %index) + %3 = bitcast i8* %2 to i64* + store i64 %val, i64* %3 + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 1) + store %Array* %0, %Array** %local + %n = call i64 @__quantum__rt__array_get_size_1d(%Array* %0) + %4 = sub i64 %n, 1 + %5 = load %Range, %Range* @EmptyRange + %6 = insertvalue %Range %5, i64 %index, 0 + %7 = insertvalue %Range %6, i64 1, 1 + %8 = insertvalue %Range %7, i64 %4, 2 + %slice1 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %8, i1 false) + call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 1) + %9 = load %Range, %Range* @EmptyRange + %10 = insertvalue %Range %9, i64 %index, 0 + %11 = insertvalue %Range %10, i64 -2, 1 + %12 = insertvalue %Range %11, i64 0, 2 + %slice2 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %12, i1 false) + call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 1) + %result = call %Array* @__quantum__rt__array_concatenate(%Array* %slice2, %Array* %slice1) + call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 1) + %sum = alloca i64 + store i64 0, i64* %sum + %13 = call i64 @__quantum__rt__array_get_size_1d(%Array* %result) + %14 = sub i64 %13, 1 + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %21, %exiting__1 ] + %15 = icmp sle i64 %i, %14 + br i1 %15, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %16 = load i64, i64* %sum + %17 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %result, i64 %i) + %18 = bitcast i8* %17 to i64* + %19 = load i64, i64* %18 + %20 = add i64 %16, %19 + store i64 %20, i64* %sum + br label %exiting__1 + +exiting__1: ; preds = %body__1 + %21 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + br i1 %compilerDecoy, label %then0__1, label %continue__1 + +then0__1: ; preds = %exit__1 + call void @Microsoft__Quantum__Testing__QIR__TestControlled__body() + %res2 = call i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 17, i64 42) + call void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() + %res4 = call i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() + %res5 = call i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() + %res6 = call i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() + %res7 = call i64 @Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body() + %res8 = call i64 @Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(i64 0, i64 1) + %22 = call %String* @__quantum__rt__string_create(i32 4, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @0, i32 0, i32 0)) + call void @Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(%String* %22) + call void @__quantum__rt__string_update_reference_count(%String* %22, i64 -1) + br label %continue__1 + +continue__1: ; preds = %then0__1, %exit__1 + %23 = load i64, i64* %sum + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %slice1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %slice2, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %result, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + ret i64 %23 +} + +declare void @__quantum__rt__array_update_alias_count(%Array*, i64) + +declare void @__quantum__rt__array_update_reference_count(%Array*, i64) + +declare %Array* @__quantum__rt__array_copy(%Array*, i1) + +declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) + +declare i64 @__quantum__rt__array_get_size_1d(%Array*) + +declare %Array* @__quantum__rt__array_slice_1d(%Array*, %Range, i1) + +declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) + define void @Microsoft__Quantum__Testing__QIR__TestControlled__body() { entry: %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) @@ -44,7 +146,7 @@ entry: %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Qop, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) store %Callable* %4, %Callable** %2 store i64 1, i64* %3 - %qop = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %0) + %qop = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %0) call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 1) call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 1) %adj_qop = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) @@ -83,7 +185,7 @@ entry: br i1 %11, label %then0__1, label %continue__1 then0__1: ; preds = %entry - %12 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @0, i32 0, i32 0)) + %12 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @2, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -125,7 +227,7 @@ continue__1: ; preds = %entry br i1 %19, label %then0__2, label %continue__2 then0__2: ; preds = %continue__1 - %20 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @1, i32 0, i32 0)) + %20 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @3, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -175,7 +277,7 @@ continue__2: ; preds = %continue__1 br i1 %31, label %then0__3, label %continue__3 then0__3: ; preds = %continue__2 - %32 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @2, i32 0, i32 0)) + %32 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @4, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -228,7 +330,7 @@ continue__3: ; preds = %continue__2 br i1 %43, label %then0__4, label %continue__4 then0__4: ; preds = %continue__3 - %44 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @3, i32 0, i32 0)) + %44 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @5, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -294,7 +396,7 @@ continue__4: ; preds = %continue__3 br i1 %62, label %then0__5, label %continue__5 then0__5: ; preds = %continue__4 - %63 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @4, i32 0, i32 0)) + %63 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @6, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -361,7 +463,7 @@ continue__5: ; preds = %continue__4 br i1 %77, label %then0__6, label %continue__6 then0__6: ; preds = %continue__5 - %78 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @5, i32 0, i32 0)) + %78 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @7, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -460,7 +562,7 @@ continue__6: ; preds = %continue__5 br i1 %108, label %then0__7, label %continue__7 then0__7: ; preds = %continue__6 - %109 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @6, i32 0, i32 0)) + %109 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @8, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q4) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) @@ -580,645 +682,297 @@ continue__7: ; preds = %continue__6 ret void } -declare %Tuple* @__quantum__rt__tuple_create(i64) - -define void @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +define i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 %x, i64 %y) { entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %3 = load %Qubit*, %Qubit** %1 - %4 = load i64, i64* %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %3, i64 %4) - ret void + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %Callable*, i64 }* + %2 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 0 + %3 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 1 + %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Subtract, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + store %Callable* %4, %Callable** %2 + store i64 %x, i64* %3 + %subtractor = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %0) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 1) + %5 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) + %6 = bitcast %Tuple* %5 to { i64 }* + %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 + store i64 %y, i64* %7 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) + call void @__quantum__rt__callable_invoke(%Callable* %subtractor, %Tuple* %5, %Tuple* %8) + %9 = bitcast %Tuple* %8 to { i64 }* + %10 = getelementptr inbounds { i64 }, { i64 }* %9, i32 0, i32 0 + %11 = load i64, i64* %10 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %subtractor, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret i64 %11 } -define void @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +define void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() { entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %3 = load %Qubit*, %Qubit** %1 - %4 = load i64, i64* %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %3, i64 %4) - ret void -} + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %1 = bitcast i8* %0 to %Qubit** + %qubit = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__x__body(%Qubit* %qubit) + %q = call %Qubit* @__quantum__rt__qubit_allocate() + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %3 = bitcast i8* %2 to %Qubit** + %4 = load %Qubit*, %Qubit** %3 + %5 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %4) + %6 = load %Result*, %Result** @ResultOne + %7 = call i1 @__quantum__rt__result_equal(%Result* %5, %Result* %6) + br i1 %7, label %then0__1, label %continue__1 -define void @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* - %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %3, { %Qubit*, i64 }* %4) - ret void -} +then0__1: ; preds = %entry + call void @__quantum__qis__x__body(%Qubit* %q) + br label %continue__1 -define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* - %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %3, { %Qubit*, i64 }* %4) - ret void -} +continue__1: ; preds = %then0__1, %entry + %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %9 = bitcast i8* %8 to %Qubit** + %10 = load %Qubit*, %Qubit** %9 + %11 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %10) + %12 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) + %13 = call i1 @__quantum__rt__result_equal(%Result* %11, %Result* %12) + br i1 %13, label %then0__2, label %continue__2 -declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) +then0__2: ; preds = %continue__1 + %14 = call %String* @__quantum__rt__string_create(i32 29, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @1, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__qubit_release_array(%Array* %qs) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + call void @__quantum__rt__fail(%String* %14) + unreachable -define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* - %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 - %2 = load %Qubit*, %Qubit** %1 - %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 - %5 = load i64, i64* %4 - %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* - %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 - %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 - store %Qubit* %2, %Qubit** %8 - store i64 %5, i64* %9 - %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 - %11 = load %Callable*, %Callable** %10 - call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) +continue__2: ; preds = %continue__1 + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) + call void @__quantum__rt__qubit_release_array(%Array* %qs) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) ret void } -define void @Lifted__PartialApplication__1__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +define i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() { entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* - %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 - %2 = load %Qubit*, %Qubit** %1 - %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 - %5 = load i64, i64* %4 - %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* - %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 - %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 - store %Qubit* %2, %Qubit** %8 - store i64 %5, i64* %9 - %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 - %11 = load %Callable*, %Callable** %10 - %12 = call %Callable* @__quantum__rt__callable_copy(%Callable* %11, i1 false) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 1) - call void @__quantum__rt__callable_make_adjoint(%Callable* %12) - call void @__quantum__rt__callable_invoke(%Callable* %12, %Tuple* %6, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %12, i64 -1) - ret void -} + %0 = call double @__quantum__qis__sqrt__body(double 4.000000e+00) + %1 = fcmp one double 2.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 -define void @Lifted__PartialApplication__1__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* - %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load %Qubit*, %Qubit** %2 - %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 - %7 = load i64, i64* %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* - %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 - store %Qubit* %4, %Qubit** %10 - store i64 %7, i64* %11 - %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) - %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* - %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 - %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 - store %Array* %3, %Array** %14 - store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 - %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 - %17 = load %Callable*, %Callable** %16 - %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) - call void @__quantum__rt__callable_make_controlled(%Callable* %18) - call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) - ret void -} +then0__1: ; preds = %entry + ret i64 1 -define void @Lifted__PartialApplication__1__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* - %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load %Qubit*, %Qubit** %2 - %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 - %7 = load i64, i64* %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* - %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 - store %Qubit* %4, %Qubit** %10 - store i64 %7, i64* %11 - %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) - %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* - %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 - %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 - store %Array* %3, %Array** %14 - store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 - %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 - %17 = load %Callable*, %Callable** %16 - %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) - call void @__quantum__rt__callable_make_adjoint(%Callable* %18) - call void @__quantum__rt__callable_make_controlled(%Callable* %18) - call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) - ret void -} +continue__1: ; preds = %entry + %2 = call double @__quantum__qis__sqrt__body(double 9.000000e+00) + %3 = fcmp one double 3.000000e+00, %2 + br i1 %3, label %then0__2, label %continue__2 -define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 - %2 = load %Callable*, %Callable** %1 - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %2, i64 %count-change) - call void @__quantum__rt__callable_update_reference_count(%Callable* %2, i64 %count-change) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %capture-tuple, i64 %count-change) - ret void -} +then0__2: ; preds = %continue__1 + ret i64 2 -define void @MemoryManagement__1__AliasCount(%Tuple* %capture-tuple, i64 %count-change) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 - %2 = load %Callable*, %Callable** %1 - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %2, i64 %count-change) - call void @__quantum__rt__callable_update_alias_count(%Callable* %2, i64 %count-change) - call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) - ret void -} +continue__2: ; preds = %continue__1 + %4 = call double @__quantum__qis__sqrt__body(double 1.000000e+02) + %5 = fcmp one double 1.000000e+01, %4 + br i1 %5, label %then0__3, label %continue__3 -declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) +then0__3: ; preds = %continue__2 + ret i64 3 -declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) +continue__3: ; preds = %continue__2 + %d__4 = call double @__quantum__qis__sqrt__body(double -5.000000e+00) + %6 = call i1 @__quantum__qis__isnan__body(double %d__4) + %7 = xor i1 %6, true + br i1 %7, label %then0__4, label %continue__4 -declare %Callable* @__quantum__rt__callable_copy(%Callable*, i1) +then0__4: ; preds = %continue__3 + ret i64 4 -declare void @__quantum__rt__callable_make_adjoint(%Callable*) +continue__4: ; preds = %continue__3 + %d__5 = call double @__quantum__qis__nan__body() + %d__6 = call double @__quantum__qis__sqrt__body(double %d__5) + %8 = call i1 @__quantum__qis__isnan__body(double %d__6) + %9 = xor i1 %8, true + br i1 %9, label %then0__5, label %continue__5 -declare void @__quantum__rt__callable_make_controlled(%Callable*) +then0__5: ; preds = %continue__4 + ret i64 5 -declare %Qubit* @__quantum__rt__qubit_allocate() +continue__5: ; preds = %continue__4 + %d__7 = call double @__quantum__qis__infinity__body() + %d__8 = call double @__quantum__qis__sqrt__body(double %d__7) + %10 = call i1 @__quantum__qis__isinf__body(double %d__8) + %11 = xor i1 %10, true + br i1 %11, label %then0__6, label %continue__6 -declare %Array* @__quantum__rt__qubit_allocate_array(i64) +then0__6: ; preds = %continue__5 + ret i64 6 -declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) +continue__6: ; preds = %continue__5 + ret i64 0 +} -define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qubit) { +define i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() { entry: - %bases = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 1) - %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %bases, i64 0) - %1 = bitcast i8* %0 to i2* - %2 = load i2, i2* @PauliZ - store i2 %2, i2* %1 - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) - %qubits = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %3 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) - %4 = bitcast i8* %3 to %Qubit** - store %Qubit* %qubit, %Qubit** %4 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %5 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %bases, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qubits, i64 -1) - ret %Result* %5 -} + %input = call double @Microsoft__Quantum__Math__E__body() + %0 = call double @__quantum__qis__log__body(double %input) + %1 = fcmp one double 1.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 -declare i1 @__quantum__rt__result_equal(%Result*, %Result*) +then0__1: ; preds = %entry + ret i64 1 -declare %String* @__quantum__rt__string_create(i32, i8*) +continue__1: ; preds = %entry + %2 = call double @Microsoft__Quantum__Math__E__body() + %3 = call double @Microsoft__Quantum__Math__E__body() + %input__1 = fmul double %2, %3 + %4 = call double @__quantum__qis__log__body(double %input__1) + %5 = fcmp one double 2.000000e+00, %4 + br i1 %5, label %then0__2, label %continue__2 -declare void @__quantum__rt__qubit_release(%Qubit*) +then0__2: ; preds = %continue__1 + ret i64 2 -declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) +continue__2: ; preds = %continue__1 + %d = call double @__quantum__qis__log__body(double 0.000000e+00) + %6 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) + %7 = xor i1 %6, true + br i1 %7, label %then0__3, label %continue__3 -declare void @__quantum__rt__result_update_reference_count(%Result*, i64) +then0__3: ; preds = %continue__2 + ret i64 3 -declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) +continue__3: ; preds = %continue__2 + %d__1 = call double @__quantum__qis__log__body(double -5.000000e+00) + %8 = call i1 @__quantum__qis__isnan__body(double %d__1) + %9 = xor i1 %8, true + br i1 %9, label %then0__4, label %continue__4 -declare void @__quantum__rt__fail(%String*) +then0__4: ; preds = %continue__3 + ret i64 4 -declare %Array* @__quantum__rt__array_create_1d(i32, i64) +continue__4: ; preds = %continue__3 + %input__4 = call double @__quantum__qis__nan__body() + %d__2 = call double @__quantum__qis__log__body(double %input__4) + %10 = call i1 @__quantum__qis__isnan__body(double %d__2) + %11 = xor i1 %10, true + br i1 %11, label %then0__5, label %continue__5 -declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) +then0__5: ; preds = %continue__4 + ret i64 5 -declare void @__quantum__rt__array_update_reference_count(%Array*, i64) +continue__5: ; preds = %continue__4 + %input__5 = call double @__quantum__qis__infinity__body() + %d__3 = call double @__quantum__qis__log__body(double %input__5) + %12 = call i1 @__quantum__qis__isinf__body(double %d__3) + %13 = xor i1 %12, true + br i1 %13, label %then0__6, label %continue__6 -define void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() { +then0__6: ; preds = %continue__5 + ret i64 6 + +continue__6: ; preds = %continue__5 + ret i64 0 +} + +define i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() { entry: - %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) - call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 1) - %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %1 = bitcast i8* %0 to %Qubit** - %qubit = load %Qubit*, %Qubit** %1 - call void @__quantum__qis__x__body(%Qubit* %qubit) - %q = call %Qubit* @__quantum__rt__qubit_allocate() - %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %3 = bitcast i8* %2 to %Qubit** - %4 = load %Qubit*, %Qubit** %3 - %5 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %4) - %6 = load %Result*, %Result** @ResultOne - %7 = call i1 @__quantum__rt__result_equal(%Result* %5, %Result* %6) - br i1 %7, label %then0__1, label %continue__1 + %0 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double 1.000000e+00) + %1 = fcmp one double 0.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 then0__1: ; preds = %entry - call void @__quantum__qis__x__body(%Qubit* %q) - br label %continue__1 - -continue__1: ; preds = %then0__1, %entry - %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %9 = bitcast i8* %8 to %Qubit** - %10 = load %Qubit*, %Qubit** %9 - %11 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %10) - %12 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) - %13 = call i1 @__quantum__rt__result_equal(%Result* %11, %Result* %12) - br i1 %13, label %then0__2, label %continue__2 - -then0__2: ; preds = %continue__1 - %14 = call %String* @__quantum__rt__string_create(i32 29, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @7, i32 0, i32 0)) - call void @__quantum__rt__qubit_release(%Qubit* %q) - call void @__quantum__rt__qubit_release_array(%Array* %qs) - call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) - call void @__quantum__rt__fail(%String* %14) - unreachable - -continue__2: ; preds = %continue__1 - call void @__quantum__rt__qubit_release(%Qubit* %q) - call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) - call void @__quantum__rt__qubit_release_array(%Array* %qs) - call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) - ret void -} - -declare void @__quantum__rt__array_update_alias_count(%Array*, i64) - -declare void @__quantum__qis__x__body(%Qubit*) - -declare void @__quantum__rt__qubit_release_array(%Array*) - -define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %array, i64 %index, i64 %val, i1 %compilerDecoy) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) - %local = alloca %Array* - store %Array* %array, %Array** %local - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) - call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) - %0 = call %Array* @__quantum__rt__array_copy(%Array* %array, i1 false) - %1 = icmp ne %Array* %array, %0 - %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %index) - %3 = bitcast i8* %2 to i64* - store i64 %val, i64* %3 - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 1) - store %Array* %0, %Array** %local - %n = call i64 @__quantum__rt__array_get_size_1d(%Array* %0) - %4 = sub i64 %n, 1 - %5 = load %Range, %Range* @EmptyRange - %6 = insertvalue %Range %5, i64 %index, 0 - %7 = insertvalue %Range %6, i64 1, 1 - %8 = insertvalue %Range %7, i64 %4, 2 - %slice1 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %8, i1 false) - call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 1) - %9 = load %Range, %Range* @EmptyRange - %10 = insertvalue %Range %9, i64 %index, 0 - %11 = insertvalue %Range %10, i64 -2, 1 - %12 = insertvalue %Range %11, i64 0, 2 - %slice2 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %12, i1 false) - call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 1) - %result = call %Array* @__quantum__rt__array_concatenate(%Array* %slice2, %Array* %slice1) - call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 1) - %sum = alloca i64 - store i64 0, i64* %sum - %13 = call i64 @__quantum__rt__array_get_size_1d(%Array* %result) - %14 = sub i64 %13, 1 - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %i = phi i64 [ 0, %entry ], [ %21, %exiting__1 ] - %15 = icmp sle i64 %i, %14 - br i1 %15, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %16 = load i64, i64* %sum - %17 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %result, i64 %i) - %18 = bitcast i8* %17 to i64* - %19 = load i64, i64* %18 - %20 = add i64 %16, %19 - store i64 %20, i64* %sum - br label %exiting__1 - -exiting__1: ; preds = %body__1 - %21 = add i64 %i, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - br i1 %compilerDecoy, label %then0__1, label %continue__1 - -then0__1: ; preds = %exit__1 - call void @Microsoft__Quantum__Testing__QIR__TestControlled__body() - %res2 = call i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 17, i64 42) - call void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() - %res4 = call i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() - %res5 = call i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() - %res6 = call i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() - %res7 = call i64 @Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body() - %res8 = call i64 @Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(i64 0, i64 1) - %22 = call %String* @__quantum__rt__string_create(i32 4, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @8, i32 0, i32 0)) - call void @Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(%String* %22) - call void @__quantum__rt__string_update_reference_count(%String* %22, i64 -1) - br label %continue__1 - -continue__1: ; preds = %then0__1, %exit__1 - %23 = load i64, i64* %sum - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %slice1, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %slice2, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %result, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) - ret i64 %23 -} - -declare %Array* @__quantum__rt__array_copy(%Array*, i1) - -declare i64 @__quantum__rt__array_get_size_1d(%Array*) - -declare %Array* @__quantum__rt__array_slice_1d(%Array*, %Range, i1) - -declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) - -define i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 %x, i64 %y) { -entry: - %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) - %1 = bitcast %Tuple* %0 to { %Callable*, i64 }* - %2 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 0 - %3 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 1 - %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Subtract, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - store %Callable* %4, %Callable** %2 - store i64 %x, i64* %3 - %subtractor = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %0) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 1) - %5 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) - %6 = bitcast %Tuple* %5 to { i64 }* - %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 - store i64 %y, i64* %7 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) - call void @__quantum__rt__callable_invoke(%Callable* %subtractor, %Tuple* %5, %Tuple* %8) - %9 = bitcast %Tuple* %8 to { i64 }* - %10 = getelementptr inbounds { i64 }, { i64 }* %9, i32 0, i32 0 - %11 = load i64, i64* %10 - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %subtractor, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %subtractor, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - ret i64 %11 -} - -define i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() { -entry: - %0 = call double @__quantum__qis__sqrt__body(double 4.000000e+00) - %1 = fcmp one double 2.000000e+00, %0 - br i1 %1, label %then0__1, label %continue__1 - -then0__1: ; preds = %entry - ret i64 1 + ret i64 1 continue__1: ; preds = %entry - %2 = call double @__quantum__qis__sqrt__body(double 9.000000e+00) - %3 = fcmp one double 3.000000e+00, %2 - br i1 %3, label %then0__2, label %continue__2 + %2 = call double @Microsoft__Quantum__Math__PI__body() + %3 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double -1.000000e+00) + %4 = fcmp one double %2, %3 + br i1 %4, label %then0__2, label %continue__2 then0__2: ; preds = %continue__1 ret i64 2 continue__2: ; preds = %continue__1 - %4 = call double @__quantum__qis__sqrt__body(double 1.000000e+02) - %5 = fcmp one double 1.000000e+01, %4 - br i1 %5, label %then0__3, label %continue__3 + %5 = call double @Microsoft__Quantum__Math__PI__body() + %6 = fdiv double %5, 2.000000e+00 + %7 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double 0.000000e+00) + %8 = fcmp one double %6, %7 + br i1 %8, label %then0__3, label %continue__3 then0__3: ; preds = %continue__2 ret i64 3 continue__3: ; preds = %continue__2 - %d__4 = call double @__quantum__qis__sqrt__body(double -5.000000e+00) - %6 = call i1 @__quantum__qis__isnan__body(double %d__4) - %7 = xor i1 %6, true - br i1 %7, label %then0__4, label %continue__4 + %9 = call double @Microsoft__Quantum__Math__PI__body() + %10 = fneg double %9 + %11 = fdiv double %10, 2.000000e+00 + %12 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double 0.000000e+00) + %13 = fcmp one double %11, %12 + br i1 %13, label %then0__4, label %continue__4 then0__4: ; preds = %continue__3 ret i64 4 continue__4: ; preds = %continue__3 - %d__5 = call double @__quantum__qis__nan__body() - %d__6 = call double @__quantum__qis__sqrt__body(double %d__5) - %8 = call i1 @__quantum__qis__isnan__body(double %d__6) - %9 = xor i1 %8, true - br i1 %9, label %then0__5, label %continue__5 + %14 = call double @Microsoft__Quantum__Math__PI__body() + %15 = fdiv double %14, 4.000000e+00 + %16 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double 1.000000e+00) + %17 = fcmp one double %15, %16 + br i1 %17, label %then0__5, label %continue__5 then0__5: ; preds = %continue__4 ret i64 5 continue__5: ; preds = %continue__4 - %d__7 = call double @__quantum__qis__infinity__body() - %d__8 = call double @__quantum__qis__sqrt__body(double %d__7) - %10 = call i1 @__quantum__qis__isinf__body(double %d__8) - %11 = xor i1 %10, true - br i1 %11, label %then0__6, label %continue__6 + %18 = call double @Microsoft__Quantum__Math__PI__body() + %19 = fmul double %18, 3.000000e+00 + %20 = fdiv double %19, 4.000000e+00 + %21 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double -1.000000e+00) + %22 = fcmp one double %20, %21 + br i1 %22, label %then0__6, label %continue__6 then0__6: ; preds = %continue__5 ret i64 6 continue__6: ; preds = %continue__5 - ret i64 0 -} + %23 = call double @Microsoft__Quantum__Math__PI__body() + %24 = fneg double %23 + %25 = fmul double %24, 3.000000e+00 + %26 = fdiv double %25, 4.000000e+00 + %27 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double -1.000000e+00) + %28 = fcmp one double %26, %27 + br i1 %28, label %then0__7, label %continue__7 -define i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() { -entry: - %input = call double @Microsoft__Quantum__Math__E__body() - %0 = call double @__quantum__qis__log__body(double %input) - %1 = fcmp one double 1.000000e+00, %0 - br i1 %1, label %then0__1, label %continue__1 +then0__7: ; preds = %continue__6 + ret i64 7 -then0__1: ; preds = %entry - ret i64 1 +continue__7: ; preds = %continue__6 + %29 = call double @Microsoft__Quantum__Math__PI__body() + %30 = fneg double %29 + %31 = fdiv double %30, 4.000000e+00 + %32 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double 1.000000e+00) + %33 = fcmp one double %31, %32 + br i1 %33, label %then0__8, label %continue__8 -continue__1: ; preds = %entry - %2 = call double @Microsoft__Quantum__Math__E__body() - %3 = call double @Microsoft__Quantum__Math__E__body() - %input__1 = fmul double %2, %3 - %4 = call double @__quantum__qis__log__body(double %input__1) - %5 = fcmp one double 2.000000e+00, %4 - br i1 %5, label %then0__2, label %continue__2 +then0__8: ; preds = %continue__7 + ret i64 8 -then0__2: ; preds = %continue__1 - ret i64 2 - -continue__2: ; preds = %continue__1 - %d = call double @__quantum__qis__log__body(double 0.000000e+00) - %6 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) - %7 = xor i1 %6, true - br i1 %7, label %then0__3, label %continue__3 - -then0__3: ; preds = %continue__2 - ret i64 3 - -continue__3: ; preds = %continue__2 - %d__1 = call double @__quantum__qis__log__body(double -5.000000e+00) - %8 = call i1 @__quantum__qis__isnan__body(double %d__1) - %9 = xor i1 %8, true - br i1 %9, label %then0__4, label %continue__4 - -then0__4: ; preds = %continue__3 - ret i64 4 - -continue__4: ; preds = %continue__3 - %input__4 = call double @__quantum__qis__nan__body() - %d__2 = call double @__quantum__qis__log__body(double %input__4) - %10 = call i1 @__quantum__qis__isnan__body(double %d__2) - %11 = xor i1 %10, true - br i1 %11, label %then0__5, label %continue__5 - -then0__5: ; preds = %continue__4 - ret i64 5 - -continue__5: ; preds = %continue__4 - %input__5 = call double @__quantum__qis__infinity__body() - %d__3 = call double @__quantum__qis__log__body(double %input__5) - %12 = call i1 @__quantum__qis__isinf__body(double %d__3) - %13 = xor i1 %12, true - br i1 %13, label %then0__6, label %continue__6 - -then0__6: ; preds = %continue__5 - ret i64 6 - -continue__6: ; preds = %continue__5 - ret i64 0 -} - -define i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() { -entry: - %0 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double 1.000000e+00) - %1 = fcmp one double 0.000000e+00, %0 - br i1 %1, label %then0__1, label %continue__1 - -then0__1: ; preds = %entry - ret i64 1 - -continue__1: ; preds = %entry - %2 = call double @Microsoft__Quantum__Math__PI__body() - %3 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double -1.000000e+00) - %4 = fcmp one double %2, %3 - br i1 %4, label %then0__2, label %continue__2 - -then0__2: ; preds = %continue__1 - ret i64 2 - -continue__2: ; preds = %continue__1 - %5 = call double @Microsoft__Quantum__Math__PI__body() - %6 = fdiv double %5, 2.000000e+00 - %7 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double 0.000000e+00) - %8 = fcmp one double %6, %7 - br i1 %8, label %then0__3, label %continue__3 - -then0__3: ; preds = %continue__2 - ret i64 3 - -continue__3: ; preds = %continue__2 - %9 = call double @Microsoft__Quantum__Math__PI__body() - %10 = fneg double %9 - %11 = fdiv double %10, 2.000000e+00 - %12 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double 0.000000e+00) - %13 = fcmp one double %11, %12 - br i1 %13, label %then0__4, label %continue__4 - -then0__4: ; preds = %continue__3 - ret i64 4 - -continue__4: ; preds = %continue__3 - %14 = call double @Microsoft__Quantum__Math__PI__body() - %15 = fdiv double %14, 4.000000e+00 - %16 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double 1.000000e+00) - %17 = fcmp one double %15, %16 - br i1 %17, label %then0__5, label %continue__5 - -then0__5: ; preds = %continue__4 - ret i64 5 - -continue__5: ; preds = %continue__4 - %18 = call double @Microsoft__Quantum__Math__PI__body() - %19 = fmul double %18, 3.000000e+00 - %20 = fdiv double %19, 4.000000e+00 - %21 = call double @__quantum__qis__arctan2__body(double 1.000000e+00, double -1.000000e+00) - %22 = fcmp one double %20, %21 - br i1 %22, label %then0__6, label %continue__6 - -then0__6: ; preds = %continue__5 - ret i64 6 - -continue__6: ; preds = %continue__5 - %23 = call double @Microsoft__Quantum__Math__PI__body() - %24 = fneg double %23 - %25 = fmul double %24, 3.000000e+00 - %26 = fdiv double %25, 4.000000e+00 - %27 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double -1.000000e+00) - %28 = fcmp one double %26, %27 - br i1 %28, label %then0__7, label %continue__7 - -then0__7: ; preds = %continue__6 - ret i64 7 - -continue__7: ; preds = %continue__6 - %29 = call double @Microsoft__Quantum__Math__PI__body() - %30 = fneg double %29 - %31 = fdiv double %30, 4.000000e+00 - %32 = call double @__quantum__qis__arctan2__body(double -1.000000e+00, double 1.000000e+00) - %33 = fcmp one double %31, %32 - br i1 %33, label %then0__8, label %continue__8 - -then0__8: ; preds = %continue__7 - ret i64 8 - -continue__8: ; preds = %continue__7 - %34 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double 0.000000e+00) - %35 = fcmp one double 0.000000e+00, %34 - br i1 %35, label %then0__9, label %continue__9 +continue__8: ; preds = %continue__7 + %34 = call double @__quantum__qis__arctan2__body(double 0.000000e+00, double 0.000000e+00) + %35 = fcmp one double 0.000000e+00, %34 + br i1 %35, label %then0__9, label %continue__9 then0__9: ; preds = %continue__8 ret i64 9 @@ -1351,8 +1105,18 @@ entry: ret void } +declare %String* @__quantum__rt__string_create(i32, i8*) + declare void @__quantum__rt__string_update_reference_count(%String*, i64) +define i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %from, i64 %what) { +entry: + %0 = sub i64 %from, %what + ret i64 %0 +} + +declare %Tuple* @__quantum__rt__tuple_create(i64) + define void @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { entry: %0 = bitcast %Tuple* %arg-tuple to { i64, i64 }* @@ -1367,24 +1131,322 @@ entry: ret void } -define void @Lifted__PartialApplication__2__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) + +define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 1 + %2 = load i64, i64* %1 + %3 = bitcast %Tuple* %arg-tuple to { i64 }* + %4 = getelementptr inbounds { i64 }, { i64 }* %3, i32 0, i32 0 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 2)) + %7 = bitcast %Tuple* %6 to { i64, i64 }* + %8 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 1 + store i64 %2, i64* %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + ret void +} + +define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @MemoryManagement__1__AliasCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) + +declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) + +declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) + +declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) + +declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) + +define void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) { +entry: + %0 = srem i64 %n, 2 + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__k__body(%Qubit* %q) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + ret void +} + +declare void @__quantum__qis__k__body(%Qubit*) + +define void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %q, i64 %n) { +entry: + call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %ctrls, { %Qubit*, i64 }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %n = load i64, i64* %2 + %3 = srem i64 %n, 2 + %4 = icmp eq i64 %3, 1 + br i1 %4, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) + call void @__quantum__qis__k__ctl(%Array* %ctrls, %Qubit* %q) + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) + ret void +} + +declare void @__quantum__qis__k__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %__controlQubits__, { %Qubit*, i64 }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %n = load i64, i64* %2 + %3 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %4 = bitcast %Tuple* %3 to { %Qubit*, i64 }* + %5 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 0 + %6 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 1 + store %Qubit* %q, %Qubit** %5 + store i64 %n, i64* %6 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %__controlQubits__, { %Qubit*, i64 }* %4) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %3, i64 -1) + ret void +} + +declare %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare void @__quantum__qis__x__body(%Qubit*) + +define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qubit) { +entry: + %bases = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %bases, i64 0) + %1 = bitcast i8* %0 to i2* + %2 = load i2, i2* @PauliZ + store i2 %2, i2* %1 + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) + %qubits = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %3 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %4 = bitcast i8* %3 to %Qubit** + store %Qubit* %qubit, %Qubit** %4 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %5 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qubits, i64 -1) + ret %Result* %5 +} + +declare i1 @__quantum__rt__result_equal(%Result*, %Result*) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__qubit_release_array(%Array*) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +declare void @__quantum__rt__fail(%String*) + +define void @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %3 = load %Qubit*, %Qubit** %1 + %4 = load i64, i64* %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %3, i64 %4) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %3 = load %Qubit*, %Qubit** %1 + %4 = load i64, i64* %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %3, i64 %4) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* + %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %3, { %Qubit*, i64 }* %4) + ret void +} + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* + %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %3, { %Qubit*, i64 }* %4) + ret void +} + +define void @Lifted__PartialApplication__2__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* + %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 + %2 = load %Qubit*, %Qubit** %1 + %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* + %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 + store %Qubit* %2, %Qubit** %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__2__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* + %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 + %2 = load %Qubit*, %Qubit** %1 + %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* + %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 + store %Qubit* %2, %Qubit** %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + %12 = call %Callable* @__quantum__rt__callable_copy(%Callable* %11, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %12) + call void @__quantum__rt__callable_invoke(%Callable* %12, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %12, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__2__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* + %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load %Qubit*, %Qubit** %2 + %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 + %7 = load i64, i64* %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* + %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 + store %Qubit* %4, %Qubit** %10 + store i64 %7, i64* %11 + %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* + %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 + %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 + store %Array* %3, %Array** %14 + store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 + %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 + %17 = load %Callable*, %Callable** %16 + %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %18) + call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__2__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 1 - %2 = load i64, i64* %1 - %3 = bitcast %Tuple* %arg-tuple to { i64 }* - %4 = getelementptr inbounds { i64 }, { i64 }* %3, i32 0, i32 0 - %5 = load i64, i64* %4 - %6 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 2)) - %7 = bitcast %Tuple* %6 to { i64, i64 }* - %8 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 0 - %9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 1 - store i64 %2, i64* %8 - store i64 %5, i64* %9 - %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 - %11 = load %Callable*, %Callable** %10 - call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* + %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load %Qubit*, %Qubit** %2 + %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 + %7 = load i64, i64* %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* + %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 + store %Qubit* %4, %Qubit** %10 + store i64 %7, i64* %11 + %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* + %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 + %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 + store %Array* %3, %Array** %14 + store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 + %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 + %17 = load %Callable*, %Callable** %16 + %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %18) + call void @__quantum__rt__callable_make_controlled(%Callable* %18) + call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) ret void } @@ -1410,84 +1472,69 @@ entry: ret void } -define void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) { -entry: - %0 = srem i64 %n, 2 - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %continue__1 +declare %Callable* @__quantum__rt__callable_copy(%Callable*, i1) -then0__1: ; preds = %entry - call void @__quantum__qis__k__body(%Qubit* %q) - br label %continue__1 +declare void @__quantum__rt__callable_make_adjoint(%Callable*) -continue__1: ; preds = %then0__1, %entry - ret void -} +declare void @__quantum__rt__callable_make_controlled(%Callable*) -declare void @__quantum__qis__k__body(%Qubit*) +declare %Array* @__quantum__rt__array_create_1d(i32, i64) -define void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %q, i64 %n) { +define i1 @Microsoft__Quantum__Intrinsic__IsNegativeInfinity__body(double %d) { entry: - call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) - ret void + %0 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) + ret i1 %0 } -define void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %ctrls, { %Qubit*, i64 }* %0) { +declare i1 @__quantum__qis__isnegativeinfinity__body(double) + +define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %bases, %Array* %qubits) { entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %q = load %Qubit*, %Qubit** %1 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %n = load i64, i64* %2 - %3 = srem i64 %n, 2 - %4 = icmp eq i64 %3, 1 - br i1 %4, label %then0__1, label %continue__1 + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} -then0__1: ; preds = %entry - call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) - call void @__quantum__qis__k__ctl(%Array* %ctrls, %Qubit* %q) - call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) - br label %continue__1 +declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) -continue__1: ; preds = %then0__1, %entry - call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) +define void @Microsoft__Quantum__Intrinsic__K__body(%Qubit* %q) { +entry: + call void @__quantum__qis__k__body(%Qubit* %q) ret void } -declare void @__quantum__qis__k__ctl(%Array*, %Qubit*) +define void @Microsoft__Quantum__Intrinsic__K__adj(%Qubit* %q) { +entry: + call void @__quantum__qis__k__body(%Qubit* %q) + ret void +} -define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %__controlQubits__, { %Qubit*, i64 }* %0) { +define void @Microsoft__Quantum__Intrinsic__K__ctl(%Array* %__controlQubits__, %Qubit* %q) { entry: call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %q = load %Qubit*, %Qubit** %1 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %n = load i64, i64* %2 - %3 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %4 = bitcast %Tuple* %3 to { %Qubit*, i64 }* - %5 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 0 - %6 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 1 - store %Qubit* %q, %Qubit** %5 - store i64 %n, i64* %6 - call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %__controlQubits__, { %Qubit*, i64 }* %4) + call void @__quantum__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %3, i64 -1) ret void } -define i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %from, i64 %what) { +define void @Microsoft__Quantum__Intrinsic__K__ctladj(%Array* %__controlQubits__, %Qubit* %q) { entry: - %0 = sub i64 %from, %what - ret i64 %0 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void } -define i1 @Microsoft__Quantum__Intrinsic__IsInf__body(double %d) { +define i1 @Microsoft__Quantum__Intrinsic__IsNan__body(double %d) { entry: - %0 = call i1 @__quantum__qis__isinf__body(double %d) + %0 = call i1 @__quantum__qis__isnan__body(double %d) ret i1 %0 } -declare i1 @__quantum__qis__isinf__body(double) +declare i1 @__quantum__qis__isnan__body(double) define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qubit) { entry: @@ -1519,37 +1566,13 @@ entry: ret void } -define double @Microsoft__Quantum__Intrinsic__NAN__body() { +define double @Microsoft__Quantum__Intrinsic__INFINITY__body() { entry: - %0 = call double @__quantum__qis__nan__body() + %0 = call double @__quantum__qis__infinity__body() ret double %0 } -declare double @__quantum__qis__nan__body() - -define i1 @Microsoft__Quantum__Intrinsic__IsNegativeInfinity__body(double %d) { -entry: - %0 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) - ret i1 %0 -} - -declare i1 @__quantum__qis__isnegativeinfinity__body(double) - -define i64 @Microsoft__Quantum__Intrinsic__DrawRandomInt__body(i64 %min, i64 %max) { -entry: - %0 = call i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) - ret i64 %0 -} - -declare i64 @__quantum__qis__drawrandomint__body(i64, i64) - -define i1 @Microsoft__Quantum__Intrinsic__IsNan__body(double %d) { -entry: - %0 = call i1 @__quantum__qis__isnan__body(double %d) - ret i1 %0 -} - -declare i1 @__quantum__qis__isnan__body(double) +declare double @__quantum__qis__infinity__body() define void @Microsoft__Quantum__Intrinsic__Message__body(%String* %msg) { entry: @@ -1559,53 +1582,23 @@ entry: declare void @__quantum__qis__message__body(%String*) -define double @Microsoft__Quantum__Intrinsic__INFINITY__body() { -entry: - %0 = call double @__quantum__qis__infinity__body() - ret double %0 -} - -declare double @__quantum__qis__infinity__body() - -define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %bases, %Array* %qubits) { +define i1 @Microsoft__Quantum__Intrinsic__IsInf__body(double %d) { entry: - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %0 + %0 = call i1 @__quantum__qis__isinf__body(double %d) + ret i1 %0 } -declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) - -define void @Microsoft__Quantum__Intrinsic__K__body(%Qubit* %q) { -entry: - call void @__quantum__qis__k__body(%Qubit* %q) - ret void -} +declare i1 @__quantum__qis__isinf__body(double) -define void @Microsoft__Quantum__Intrinsic__K__adj(%Qubit* %q) { +define double @Microsoft__Quantum__Intrinsic__NAN__body() { entry: - call void @__quantum__qis__k__body(%Qubit* %q) - ret void + %0 = call double @__quantum__qis__nan__body() + ret double %0 } -define void @Microsoft__Quantum__Intrinsic__K__ctl(%Array* %__controlQubits__, %Qubit* %q) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} +declare double @__quantum__qis__nan__body() -define void @Microsoft__Quantum__Intrinsic__K__ctladj(%Array* %__controlQubits__, %Qubit* %q) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} +declare i64 @__quantum__qis__drawrandomint__body(i64, i64) define double @Microsoft__Quantum__Math__E__body() { entry: @@ -1635,16 +1628,22 @@ entry: ret double %0 } +define double @Microsoft__Quantum__Math__Log__body(double %input) { +entry: + %0 = call double @__quantum__qis__log__body(double %input) + ret double %0 +} + define double @Microsoft__Quantum__Math__Sqrt__body(double %d) { entry: %0 = call double @__quantum__qis__sqrt__body(double %d) ret double %0 } -define double @Microsoft__Quantum__Math__Log__body(double %input) { +define i64 @Microsoft__Quantum__Random__DrawRandomInt__body(i64 %min, i64 %max) { entry: - %0 = call double @__quantum__qis__log__body(double %input) - ret double %0 + %0 = call i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) + ret i64 %0 } define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays(i64 %array__count, i64* %array, i64 %index, i64 %val, i1 %compilerDecoy) #0 { diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 29b6dfe5337..4c7b10becfa 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -17,12 +17,12 @@ extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(QirStri struct QOstreamRedirector { QOstreamRedirector(std::ostream & newOstream) - : old(Quantum::Qis::Internal::SetQOstream(newOstream)) + : old(Quantum::Qis::Internal::SetOutputStream(newOstream)) {} ~QOstreamRedirector() { - Quantum::Qis::Internal::SetQOstream(old); + Quantum::Qis::Internal::SetOutputStream(old); } private: diff --git a/src/QirRuntime/test/QIR-static/qsharp/Math.qs b/src/QirRuntime/test/QIR-static/qsharp/Math.qs index 4785b9ded1b..23d81bcbe09 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/Math.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/Math.qs @@ -28,8 +28,4 @@ namespace Microsoft.Quantum.Intrinsic { body intrinsic; } - operation DrawRandomInt(min : Int, max : Int) : Int { - body intrinsic; - } - } diff --git a/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs b/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs index 5bf13d5708d..2ad876a087c 100644 --- a/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs +++ b/src/QirRuntime/test/QIR-static/qsharp/qir-test-math.qs @@ -5,6 +5,7 @@ namespace Microsoft.Quantum.Testing.QIR.Math { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Math; // E() + open Microsoft.Quantum.Random; function SqrtTest() : Int { if 2.0 != Sqrt( 4.0) { return 1; } // The return value indicates which test case has failed. From 7f6fd2f4724603a1f1e2286fb1b87157b1a74685 Mon Sep 17 00:00:00 2001 From: Robin Kuzmin Date: Tue, 16 Feb 2021 21:45:00 -0800 Subject: [PATCH 14/14] CR changes. --- src/QirRuntime/lib/QIR/intrinsicsMath.cpp | 44 +- src/QirRuntime/lib/QIR/intrinsicsOut.cpp | 32 +- .../lib/QIR/quantum__qis_internal.hpp | 19 +- src/QirRuntime/test/QIR-static/qir-gen.ll | 1132 ++++++++--------- .../test/QIR-static/qir-test-math.cpp | 182 +-- .../test/QIR-static/qir-test-ouput.cpp | 12 +- 6 files changed, 732 insertions(+), 689 deletions(-) diff --git a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp index 413936cf371..fedfbd6ba7b 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp @@ -9,9 +9,10 @@ #include "quantum__rt.hpp" // Forward declarations: -namespace // Visible in this translation unit only. +namespace // Visible in this translation unit only. { - extern thread_local bool seedIsRandom; +extern thread_local bool randomizeSeed; +extern int64_t lastGeneratedRndNum; } // Implementation: @@ -48,29 +49,40 @@ int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum) // https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution // https://en.cppreference.com/w/cpp/numeric/random - thread_local static std::mt19937_64 gen(seedIsRandom + thread_local static std::mt19937_64 gen(randomizeSeed ? std::random_device()() : // Default 0); // For test purposes only. - return std::uniform_int_distribution(minimum, maximum)(gen); + lastGeneratedRndNum = std::uniform_int_distribution(minimum, maximum)(gen); + return lastGeneratedRndNum; } -} // extern "C" +} // extern "C" -namespace // Visible in this translation unit only. +namespace // Visible in this translation unit only. { - thread_local bool seedIsRandom = true; +thread_local bool randomizeSeed = true; +int64_t lastGeneratedRndNum = 0; } // For test purposes only: -namespace Quantum { namespace Qis { namespace Internal +namespace Quantum { - -char const excStrDrawRandomInt[] = "Invalid Argument: minimum > maximum for DrawRandomInt()"; - -void UseRandomSeed(bool random) +namespace Qis { - seedIsRandom = random; -} - -}}} // namespace Quantum::Qis::Internal + namespace Internal + { + char const excStrDrawRandomInt[] = "Invalid Argument: minimum > maximum for DrawRandomInt()"; + + void RandomizeSeed(bool randomize) + { + randomizeSeed = randomize; + } + + int64_t GetLastGeneratedRandomNumber() + { + return lastGeneratedRndNum; + } + } // namespace Internal +} // namespace Qis +} // namespace Quantum diff --git a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp index fdc919e8e3a..6b46289be10 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp +++ b/src/QirRuntime/lib/QIR/intrinsicsOut.cpp @@ -7,37 +7,41 @@ #include "quantum__qis.hpp" // Forward declarations: -static std::ostream& GetQOstream(); +static std::ostream& GetOutputStream(); // Public API: extern "C" { void quantum__qis__message__body(QirString* qstr) // NOLINT { - GetQOstream() << qstr->str << std::endl; + GetOutputStream() << qstr->str << std::endl; } } // extern "C" // Internal API: -static std::ostream * currOStream = &std::cout; // Log to std::cout by default. +static std::ostream* currentOutputStream = &std::cout; // Log to std::cout by default. -static std::ostream& GetQOstream() +static std::ostream& GetOutputStream() { - return *currOStream; + return *currentOutputStream; } // For test purposes only: -namespace Quantum { namespace Qis { namespace Internal // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. +namespace Quantum // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. { - -std::ostream& SetOutputStream(std::ostream & newOStream) +namespace Qis { - std::ostream& oldOStream = *currOStream; - currOStream = &newOStream; - return oldOStream; -} - -}}} // namespace Quantum::Qis::Internal + namespace Internal + { + std::ostream& SetOutputStream(std::ostream & newOStream) + { + std::ostream& oldOStream = *currentOutputStream; + currentOutputStream = &newOStream; + return oldOStream; + } + } // namespace Internal +} // namespace Qis +} // namespace Quantum diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp index 862103a3511..52335f32027 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -// To be included by the QIS implementation and QIS tests only. +// To be included by the QIS implementation and QIS tests only. // Not to be included by parties outside QIS. #ifdef _WIN32 @@ -13,10 +13,17 @@ #endif // For test purposes only: -namespace Quantum { namespace Qis { namespace Internal // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. +namespace Quantum // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. { - QIR_SHARED_API extern char const excStrDrawRandomInt[]; // = "Invalid Argument: minimum > maximum for DrawRandomInt()"; +namespace Qis +{ + namespace Internal + { + extern char const excStrDrawRandomInt[]; - QIR_SHARED_API extern std::ostream& SetOutputStream(std::ostream & newOStream); - QIR_SHARED_API void UseRandomSeed(bool random); -}}} // namespace Quantum::Qis::Internal + extern std::ostream& SetOutputStream(std::ostream& newOStream); + void RandomizeSeed(bool randomize); + int64_t GetLastGeneratedRandomNumber(); + } // namespace Internal +} // namespace Qis +} // namespace Quantum diff --git a/src/QirRuntime/test/QIR-static/qir-gen.ll b/src/QirRuntime/test/QIR-static/qir-gen.ll index fcbfdbc3c3b..f4edf3a2b5a 100644 --- a/src/QirRuntime/test/QIR-static/qir-gen.ll +++ b/src/QirRuntime/test/QIR-static/qir-gen.ll @@ -1,10 +1,10 @@ %Result = type opaque %Range = type { i64, i64, i64 } %Tuple = type opaque -%Array = type opaque -%String = type opaque %Callable = type opaque %Qubit = type opaque +%String = type opaque +%Array = type opaque @ResultZero = external global %Result* @ResultOne = external global %Result* @@ -13,130 +13,27 @@ @PauliY = constant i2 -1 @PauliZ = constant i2 -2 @EmptyRange = internal constant %Range { i64 0, i64 1, i64 -1 } -@0 = internal constant [5 x i8] c"Test\00" -@Microsoft__Quantum__Testing__QIR__Subtract = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] -@PartialApplication__1 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] -@MemoryManagement__1 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__1__RefCount, void (%Tuple*, i64)* @MemoryManagement__1__AliasCount] -@1 = internal constant [30 x i8] c"Unexpected measurement result\00" @Microsoft__Quantum__Testing__QIR__Qop = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper] -@PartialApplication__2 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__ctladj__wrapper] -@MemoryManagement__2 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__2__RefCount, void (%Tuple*, i64)* @MemoryManagement__2__AliasCount] -@2 = internal constant [14 x i8] c"error code: 1\00" +@PartialApplication__1 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__1__ctladj__wrapper] +@MemoryManagement__1 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__1__RefCount, void (%Tuple*, i64)* @MemoryManagement__1__AliasCount] +@0 = internal constant [14 x i8] c"error code: 1\00" +@1 = internal constant [14 x i8] c"error code: 2\00" +@2 = internal constant [14 x i8] c"error code: 3\00" @3 = internal constant [14 x i8] c"error code: 2\00" -@4 = internal constant [14 x i8] c"error code: 3\00" -@5 = internal constant [14 x i8] c"error code: 2\00" -@6 = internal constant [14 x i8] c"error code: 5\00" -@7 = internal constant [14 x i8] c"error code: 6\00" -@8 = internal constant [14 x i8] c"error code: 7\00" +@4 = internal constant [14 x i8] c"error code: 5\00" +@5 = internal constant [14 x i8] c"error code: 6\00" +@6 = internal constant [14 x i8] c"error code: 7\00" +@7 = internal constant [5 x i8] c"Test\00" +@8 = internal constant [30 x i8] c"Unexpected measurement result\00" +@Microsoft__Quantum__Testing__QIR__Subtract = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@PartialApplication__2 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__2__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@MemoryManagement__2 = constant [2 x void (%Tuple*, i64)*] [void (%Tuple*, i64)* @MemoryManagement__2__RefCount, void (%Tuple*, i64)* @MemoryManagement__2__AliasCount] @9 = internal constant [20 x i8] c"Pauli value: PauliI\00" @10 = internal constant [14 x i8] c"Pauli value: \00" @11 = internal constant [7 x i8] c"PauliX\00" @12 = internal constant [7 x i8] c"PauliY\00" @13 = internal constant [7 x i8] c"PauliZ\00" -define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %array, i64 %index, i64 %val, i1 %compilerDecoy) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) - %local = alloca %Array* - store %Array* %array, %Array** %local - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) - call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) - %0 = call %Array* @__quantum__rt__array_copy(%Array* %array, i1 false) - %1 = icmp ne %Array* %array, %0 - %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %index) - %3 = bitcast i8* %2 to i64* - store i64 %val, i64* %3 - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 1) - store %Array* %0, %Array** %local - %n = call i64 @__quantum__rt__array_get_size_1d(%Array* %0) - %4 = sub i64 %n, 1 - %5 = load %Range, %Range* @EmptyRange - %6 = insertvalue %Range %5, i64 %index, 0 - %7 = insertvalue %Range %6, i64 1, 1 - %8 = insertvalue %Range %7, i64 %4, 2 - %slice1 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %8, i1 false) - call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 1) - %9 = load %Range, %Range* @EmptyRange - %10 = insertvalue %Range %9, i64 %index, 0 - %11 = insertvalue %Range %10, i64 -2, 1 - %12 = insertvalue %Range %11, i64 0, 2 - %slice2 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %12, i1 false) - call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 1) - %result = call %Array* @__quantum__rt__array_concatenate(%Array* %slice2, %Array* %slice1) - call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 1) - %sum = alloca i64 - store i64 0, i64* %sum - %13 = call i64 @__quantum__rt__array_get_size_1d(%Array* %result) - %14 = sub i64 %13, 1 - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %i = phi i64 [ 0, %entry ], [ %21, %exiting__1 ] - %15 = icmp sle i64 %i, %14 - br i1 %15, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %16 = load i64, i64* %sum - %17 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %result, i64 %i) - %18 = bitcast i8* %17 to i64* - %19 = load i64, i64* %18 - %20 = add i64 %16, %19 - store i64 %20, i64* %sum - br label %exiting__1 - -exiting__1: ; preds = %body__1 - %21 = add i64 %i, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - br i1 %compilerDecoy, label %then0__1, label %continue__1 - -then0__1: ; preds = %exit__1 - call void @Microsoft__Quantum__Testing__QIR__TestControlled__body() - %res2 = call i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 17, i64 42) - call void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() - %res4 = call i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() - %res5 = call i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() - %res6 = call i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() - %res7 = call i64 @Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body() - %res8 = call i64 @Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(i64 0, i64 1) - %22 = call %String* @__quantum__rt__string_create(i32 4, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @0, i32 0, i32 0)) - call void @Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(%String* %22) - call void @__quantum__rt__string_update_reference_count(%String* %22, i64 -1) - br label %continue__1 - -continue__1: ; preds = %then0__1, %exit__1 - %23 = load i64, i64* %sum - call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %slice1, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %slice2, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %result, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) - ret i64 %23 -} - -declare void @__quantum__rt__array_update_alias_count(%Array*, i64) - -declare void @__quantum__rt__array_update_reference_count(%Array*, i64) - -declare %Array* @__quantum__rt__array_copy(%Array*, i1) - -declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) - -declare i64 @__quantum__rt__array_get_size_1d(%Array*) - -declare %Array* @__quantum__rt__array_slice_1d(%Array*, %Range, i1) - -declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) - define void @Microsoft__Quantum__Testing__QIR__TestControlled__body() { entry: %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) @@ -146,7 +43,7 @@ entry: %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Qop, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) store %Callable* %4, %Callable** %2 store i64 1, i64* %3 - %qop = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %0) + %qop = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %0) call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %qop, i64 1) call void @__quantum__rt__callable_update_alias_count(%Callable* %qop, i64 1) %adj_qop = call %Callable* @__quantum__rt__callable_copy(%Callable* %qop, i1 false) @@ -185,7 +82,7 @@ entry: br i1 %11, label %then0__1, label %continue__1 then0__1: ; preds = %entry - %12 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @2, i32 0, i32 0)) + %12 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @0, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -227,7 +124,7 @@ continue__1: ; preds = %entry br i1 %19, label %then0__2, label %continue__2 then0__2: ; preds = %continue__1 - %20 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @3, i32 0, i32 0)) + %20 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @1, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -277,7 +174,7 @@ continue__2: ; preds = %continue__1 br i1 %31, label %then0__3, label %continue__3 then0__3: ; preds = %continue__2 - %32 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @4, i32 0, i32 0)) + %32 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @2, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -330,7 +227,7 @@ continue__3: ; preds = %continue__2 br i1 %43, label %then0__4, label %continue__4 then0__4: ; preds = %continue__3 - %44 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @5, i32 0, i32 0)) + %44 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @3, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -396,7 +293,7 @@ continue__4: ; preds = %continue__3 br i1 %62, label %then0__5, label %continue__5 then0__5: ; preds = %continue__4 - %63 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @6, i32 0, i32 0)) + %63 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @4, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -463,7 +360,7 @@ continue__5: ; preds = %continue__4 br i1 %77, label %then0__6, label %continue__6 then0__6: ; preds = %continue__5 - %78 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @7, i32 0, i32 0)) + %78 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @5, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) call void @__quantum__rt__qubit_release(%Qubit* %q3) @@ -562,7 +459,7 @@ continue__6: ; preds = %continue__5 br i1 %108, label %then0__7, label %continue__7 then0__7: ; preds = %continue__6 - %109 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @8, i32 0, i32 0)) + %109 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @6, i32 0, i32 0)) call void @__quantum__rt__qubit_release(%Qubit* %q4) call void @__quantum__rt__qubit_release(%Qubit* %q1) call void @__quantum__rt__qubit_release(%Qubit* %q2) @@ -682,107 +579,451 @@ continue__7: ; preds = %continue__6 ret void } -define i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 %x, i64 %y) { +declare %Tuple* @__quantum__rt__tuple_create(i64) + +define void @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { entry: - %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) - %1 = bitcast %Tuple* %0 to { %Callable*, i64 }* - %2 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 0 - %3 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 1 - %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Subtract, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - store %Callable* %4, %Callable** %2 - store i64 %x, i64* %3 - %subtractor = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %0) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 1) - %5 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) - %6 = bitcast %Tuple* %5 to { i64 }* - %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 - store i64 %y, i64* %7 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) - call void @__quantum__rt__callable_invoke(%Callable* %subtractor, %Tuple* %5, %Tuple* %8) - %9 = bitcast %Tuple* %8 to { i64 }* - %10 = getelementptr inbounds { i64 }, { i64 }* %9, i32 0, i32 0 - %11 = load i64, i64* %10 - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %subtractor, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %subtractor, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - ret i64 %11 + %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %3 = load %Qubit*, %Qubit** %1 + %4 = load i64, i64* %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %3, i64 %4) + ret void } -define void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() { +define void @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { entry: - %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) - call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 1) - %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %1 = bitcast i8* %0 to %Qubit** - %qubit = load %Qubit*, %Qubit** %1 - call void @__quantum__qis__x__body(%Qubit* %qubit) - %q = call %Qubit* @__quantum__rt__qubit_allocate() - %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %3 = bitcast i8* %2 to %Qubit** - %4 = load %Qubit*, %Qubit** %3 - %5 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %4) - %6 = load %Result*, %Result** @ResultOne - %7 = call i1 @__quantum__rt__result_equal(%Result* %5, %Result* %6) - br i1 %7, label %then0__1, label %continue__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__x__body(%Qubit* %q) - br label %continue__1 - -continue__1: ; preds = %then0__1, %entry - %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %9 = bitcast i8* %8 to %Qubit** - %10 = load %Qubit*, %Qubit** %9 - %11 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %10) - %12 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) - %13 = call i1 @__quantum__rt__result_equal(%Result* %11, %Result* %12) - br i1 %13, label %then0__2, label %continue__2 - -then0__2: ; preds = %continue__1 - %14 = call %String* @__quantum__rt__string_create(i32 29, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @1, i32 0, i32 0)) - call void @__quantum__rt__qubit_release(%Qubit* %q) - call void @__quantum__rt__qubit_release_array(%Array* %qs) - call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) - call void @__quantum__rt__fail(%String* %14) - unreachable - -continue__2: ; preds = %continue__1 - call void @__quantum__rt__qubit_release(%Qubit* %q) - call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) - call void @__quantum__rt__qubit_release_array(%Array* %qs) - call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %3 = load %Qubit*, %Qubit** %1 + %4 = load i64, i64* %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %3, i64 %4) ret void } -define i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() { +define void @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { entry: - %0 = call double @__quantum__qis__sqrt__body(double 4.000000e+00) - %1 = fcmp one double 2.000000e+00, %0 - br i1 %1, label %then0__1, label %continue__1 + %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* + %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %3, { %Qubit*, i64 }* %4) + ret void +} -then0__1: ; preds = %entry - ret i64 1 +define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* + %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %3, { %Qubit*, i64 }* %4) + ret void +} -continue__1: ; preds = %entry - %2 = call double @__quantum__qis__sqrt__body(double 9.000000e+00) - %3 = fcmp one double 3.000000e+00, %2 - br i1 %3, label %then0__2, label %continue__2 +declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) -then0__2: ; preds = %continue__1 - ret i64 2 +define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* + %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 + %2 = load %Qubit*, %Qubit** %1 + %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* + %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 + store %Qubit* %2, %Qubit** %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + ret void +} -continue__2: ; preds = %continue__1 +define void @Lifted__PartialApplication__1__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* + %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 + %2 = load %Qubit*, %Qubit** %1 + %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* + %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 + store %Qubit* %2, %Qubit** %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + %12 = call %Callable* @__quantum__rt__callable_copy(%Callable* %11, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %12) + call void @__quantum__rt__callable_invoke(%Callable* %12, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %12, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__1__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* + %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load %Qubit*, %Qubit** %2 + %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 + %7 = load i64, i64* %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* + %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 + store %Qubit* %4, %Qubit** %10 + store i64 %7, i64* %11 + %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* + %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 + %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 + store %Array* %3, %Array** %14 + store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 + %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 + %17 = load %Callable*, %Callable** %16 + %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) + call void @__quantum__rt__callable_make_controlled(%Callable* %18) + call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + ret void +} + +define void @Lifted__PartialApplication__1__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* + %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 + %3 = load %Array*, %Array** %1 + %4 = load %Qubit*, %Qubit** %2 + %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 + %7 = load i64, i64* %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* + %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 + store %Qubit* %4, %Qubit** %10 + store i64 %7, i64* %11 + %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* + %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 + %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 + store %Array* %3, %Array** %14 + store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 + %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 + %17 = load %Callable*, %Callable** %16 + %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) + call void @__quantum__rt__callable_make_adjoint(%Callable* %18) + call void @__quantum__rt__callable_make_controlled(%Callable* %18) + call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + ret void +} + +define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @MemoryManagement__1__AliasCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %2 = load %Callable*, %Callable** %1 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %2, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %2, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) + +declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) + +declare %Callable* @__quantum__rt__callable_copy(%Callable*, i1) + +declare void @__quantum__rt__callable_make_adjoint(%Callable*) + +declare void @__quantum__rt__callable_make_controlled(%Callable*) + +declare %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) + +define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qubit) { +entry: + %bases = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %bases, i64 0) + %1 = bitcast i8* %0 to i2* + %2 = load i2, i2* @PauliZ + store i2 %2, i2* %1 + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) + %qubits = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %3 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %4 = bitcast i8* %3 to %Qubit** + store %Qubit* %qubit, %Qubit** %4 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %5 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qubits, i64 -1) + ret %Result* %5 +} + +declare i1 @__quantum__rt__result_equal(%Result*, %Result*) + +declare %String* @__quantum__rt__string_create(i32, i8*) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) + +declare void @__quantum__rt__fail(%String*) + +declare %Array* @__quantum__rt__array_create_1d(i32, i64) + +declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) + +declare void @__quantum__rt__array_update_reference_count(%Array*, i64) + +define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %array, i64 %index, i64 %val, i1 %compilerDecoy) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) + %local = alloca %Array* + store %Array* %array, %Array** %local + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 1) + call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) + %0 = call %Array* @__quantum__rt__array_copy(%Array* %array, i1 false) + %1 = icmp ne %Array* %array, %0 + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %index) + %3 = bitcast i8* %2 to i64* + store i64 %val, i64* %3 + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 1) + store %Array* %0, %Array** %local + %n = call i64 @__quantum__rt__array_get_size_1d(%Array* %0) + %4 = sub i64 %n, 1 + %5 = load %Range, %Range* @EmptyRange + %6 = insertvalue %Range %5, i64 %index, 0 + %7 = insertvalue %Range %6, i64 1, 1 + %8 = insertvalue %Range %7, i64 %4, 2 + %slice1 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %8, i1 false) + call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 1) + %9 = load %Range, %Range* @EmptyRange + %10 = insertvalue %Range %9, i64 %index, 0 + %11 = insertvalue %Range %10, i64 -2, 1 + %12 = insertvalue %Range %11, i64 0, 2 + %slice2 = call %Array* @__quantum__rt__array_slice_1d(%Array* %0, %Range %12, i1 false) + call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 1) + %result = call %Array* @__quantum__rt__array_concatenate(%Array* %slice2, %Array* %slice1) + call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 1) + %sum = alloca i64 + store i64 0, i64* %sum + %13 = call i64 @__quantum__rt__array_get_size_1d(%Array* %result) + %14 = sub i64 %13, 1 + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %21, %exiting__1 ] + %15 = icmp sle i64 %i, %14 + br i1 %15, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %16 = load i64, i64* %sum + %17 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %result, i64 %i) + %18 = bitcast i8* %17 to i64* + %19 = load i64, i64* %18 + %20 = add i64 %16, %19 + store i64 %20, i64* %sum + br label %exiting__1 + +exiting__1: ; preds = %body__1 + %21 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + br i1 %compilerDecoy, label %then0__1, label %continue__1 + +then0__1: ; preds = %exit__1 + call void @Microsoft__Quantum__Testing__QIR__TestControlled__body() + %res2 = call i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 17, i64 42) + call void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() + %res4 = call i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() + %res5 = call i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() + %res6 = call i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() + %res7 = call i64 @Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body() + %res8 = call i64 @Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(i64 0, i64 1) + %22 = call %String* @__quantum__rt__string_create(i32 4, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @7, i32 0, i32 0)) + call void @Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(%String* %22) + call void @__quantum__rt__string_update_reference_count(%String* %22, i64 -1) + br label %continue__1 + +continue__1: ; preds = %then0__1, %exit__1 + %23 = load i64, i64* %sum + call void @__quantum__rt__array_update_alias_count(%Array* %array, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %0, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %slice1, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %slice2, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %result, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %array, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %slice1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %slice2, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %result, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + ret i64 %23 +} + +declare void @__quantum__rt__array_update_alias_count(%Array*, i64) + +declare %Array* @__quantum__rt__array_copy(%Array*, i1) + +declare i64 @__quantum__rt__array_get_size_1d(%Array*) + +declare %Array* @__quantum__rt__array_slice_1d(%Array*, %Range, i1) + +declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) + +define i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 %x, i64 %y) { +entry: + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Callable*, i64 }* getelementptr ({ %Callable*, i64 }, { %Callable*, i64 }* null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %Callable*, i64 }* + %2 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 0 + %3 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %1, i32 0, i32 1 + %4 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__QIR__Subtract, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + store %Callable* %4, %Callable** %2 + store i64 %x, i64* %3 + %subtractor = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %0) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 1) + %5 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) + %6 = bitcast %Tuple* %5 to { i64 }* + %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 + store i64 %y, i64* %7 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64)) + call void @__quantum__rt__callable_invoke(%Callable* %subtractor, %Tuple* %5, %Tuple* %8) + %9 = bitcast %Tuple* %8 to { i64 }* + %10 = getelementptr inbounds { i64 }, { i64 }* %9, i32 0, i32 0 + %11 = load i64, i64* %10 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %subtractor, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %subtractor, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %5, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret i64 %11 +} + +define void @Microsoft__Quantum__Testing__QIR__TestQubitResultManagement__body() { +entry: + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %1 = bitcast i8* %0 to %Qubit** + %qubit = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__x__body(%Qubit* %qubit) + %q = call %Qubit* @__quantum__rt__qubit_allocate() + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %3 = bitcast i8* %2 to %Qubit** + %4 = load %Qubit*, %Qubit** %3 + %5 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %4) + %6 = load %Result*, %Result** @ResultOne + %7 = call i1 @__quantum__rt__result_equal(%Result* %5, %Result* %6) + br i1 %7, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__x__body(%Qubit* %q) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %9 = bitcast i8* %8 to %Qubit** + %10 = load %Qubit*, %Qubit** %9 + %11 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %10) + %12 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) + %13 = call i1 @__quantum__rt__result_equal(%Result* %11, %Result* %12) + br i1 %13, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + %14 = call %String* @__quantum__rt__string_create(i32 29, i8* getelementptr inbounds ([30 x i8], [30 x i8]* @8, i32 0, i32 0)) + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__qubit_release_array(%Array* %qs) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + call void @__quantum__rt__fail(%String* %14) + unreachable + +continue__2: ; preds = %continue__1 + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__result_update_reference_count(%Result* %5, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %12, i64 -1) + call void @__quantum__rt__qubit_release_array(%Array* %qs) + call void @__quantum__rt__array_update_alias_count(%Array* %qs, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + ret void +} + +define i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() { +entry: + %0 = call double @__quantum__qis__sqrt__body(double 4.000000e+00) + %1 = fcmp one double 2.000000e+00, %0 + br i1 %1, label %then0__1, label %continue__1 + +then0__1: ; preds = %entry + ret i64 1 + +continue__1: ; preds = %entry + %2 = call double @__quantum__qis__sqrt__body(double 9.000000e+00) + %3 = fcmp one double 3.000000e+00, %2 + br i1 %3, label %then0__2, label %continue__2 + +then0__2: ; preds = %continue__1 + ret i64 2 + +continue__2: ; preds = %continue__1 %4 = call double @__quantum__qis__sqrt__body(double 1.000000e+02) %5 = fcmp one double 1.000000e+01, %4 br i1 %5, label %then0__3, label %continue__3 @@ -1105,87 +1346,8 @@ entry: ret void } -declare %String* @__quantum__rt__string_create(i32, i8*) - declare void @__quantum__rt__string_update_reference_count(%String*, i64) -define i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %from, i64 %what) { -entry: - %0 = sub i64 %from, %what - ret i64 %0 -} - -declare %Tuple* @__quantum__rt__tuple_create(i64) - -define void @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { i64, i64 }* - %1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %0, i32 0, i32 1 - %3 = load i64, i64* %1 - %4 = load i64, i64* %2 - %5 = call i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %3, i64 %4) - %6 = bitcast %Tuple* %result-tuple to { i64 }* - %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 - store i64 %5, i64* %7 - ret void -} - -declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) - -define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 1 - %2 = load i64, i64* %1 - %3 = bitcast %Tuple* %arg-tuple to { i64 }* - %4 = getelementptr inbounds { i64 }, { i64 }* %3, i32 0, i32 0 - %5 = load i64, i64* %4 - %6 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 2)) - %7 = bitcast %Tuple* %6 to { i64, i64 }* - %8 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 0 - %9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 1 - store i64 %2, i64* %8 - store i64 %5, i64* %9 - %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 - %11 = load %Callable*, %Callable** %10 - call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) - ret void -} - -define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 - %2 = load %Callable*, %Callable** %1 - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %2, i64 %count-change) - call void @__quantum__rt__callable_update_reference_count(%Callable* %2, i64 %count-change) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %capture-tuple, i64 %count-change) - ret void -} - -define void @MemoryManagement__1__AliasCount(%Tuple* %capture-tuple, i64 %count-change) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 - %2 = load %Callable*, %Callable** %1 - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %2, i64 %count-change) - call void @__quantum__rt__callable_update_alias_count(%Callable* %2, i64 %count-change) - call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) - ret void -} - -declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) - -declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) - -declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) - -declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) - -declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) - define void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) { entry: %0 = srem i64 %n, 2 @@ -1230,223 +1392,69 @@ continue__1: ; preds = %then0__1, %entry ret void } -declare void @__quantum__qis__k__ctl(%Array*, %Qubit*) - -define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %__controlQubits__, { %Qubit*, i64 }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %q = load %Qubit*, %Qubit** %1 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %n = load i64, i64* %2 - %3 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %4 = bitcast %Tuple* %3 to { %Qubit*, i64 }* - %5 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 0 - %6 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 1 - store %Qubit* %q, %Qubit** %5 - store i64 %n, i64* %6 - call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %__controlQubits__, { %Qubit*, i64 }* %4) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %3, i64 -1) - ret void -} - -declare %Qubit* @__quantum__rt__qubit_allocate() - -declare %Array* @__quantum__rt__qubit_allocate_array(i64) - -declare void @__quantum__qis__x__body(%Qubit*) - -define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qubit) { -entry: - %bases = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 1) - %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %bases, i64 0) - %1 = bitcast i8* %0 to i2* - %2 = load i2, i2* @PauliZ - store i2 %2, i2* %1 - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) - %qubits = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %3 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) - %4 = bitcast i8* %3 to %Qubit** - store %Qubit* %qubit, %Qubit** %4 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %5 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %bases, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qubits, i64 -1) - ret %Result* %5 -} - -declare i1 @__quantum__rt__result_equal(%Result*, %Result*) - -declare void @__quantum__rt__qubit_release(%Qubit*) - -declare void @__quantum__rt__qubit_release_array(%Array*) - -declare void @__quantum__rt__result_update_reference_count(%Result*, i64) - -declare void @__quantum__rt__fail(%String*) - -define void @Microsoft__Quantum__Testing__QIR__Qop__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %3 = load %Qubit*, %Qubit** %1 - %4 = load i64, i64* %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %3, i64 %4) - ret void -} - -define void @Microsoft__Quantum__Testing__QIR__Qop__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit*, i64 }* - %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 - %3 = load %Qubit*, %Qubit** %1 - %4 = load i64, i64* %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %3, i64 %4) - ret void -} - -define void @Microsoft__Quantum__Testing__QIR__Qop__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* - %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %3, { %Qubit*, i64 }* %4) - ret void -} - -define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, { %Qubit*, i64 }* }* - %1 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load { %Qubit*, i64 }*, { %Qubit*, i64 }** %2 - call void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %3, { %Qubit*, i64 }* %4) - ret void -} - -define void @Lifted__PartialApplication__2__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* - %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 - %2 = load %Qubit*, %Qubit** %1 - %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 - %5 = load i64, i64* %4 - %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* - %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 - %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 - store %Qubit* %2, %Qubit** %8 - store i64 %5, i64* %9 - %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 - %11 = load %Callable*, %Callable** %10 - call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) - ret void -} - -define void @Lifted__PartialApplication__2__adj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +declare void @__quantum__qis__k__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %__controlQubits__, { %Qubit*, i64 }* %0) { entry: - %0 = bitcast %Tuple* %arg-tuple to { %Qubit* }* - %1 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %0, i32 0, i32 0 - %2 = load %Qubit*, %Qubit** %1 - %3 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %4 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 1 - %5 = load i64, i64* %4 - %6 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %7 = bitcast %Tuple* %6 to { %Qubit*, i64 }* - %8 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 0 - %9 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %7, i32 0, i32 1 - store %Qubit* %2, %Qubit** %8 - store i64 %5, i64* %9 - %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %3, i32 0, i32 0 - %11 = load %Callable*, %Callable** %10 - %12 = call %Callable* @__quantum__rt__callable_copy(%Callable* %11, i1 false) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 1) - call void @__quantum__rt__callable_make_adjoint(%Callable* %12) - call void @__quantum__rt__callable_invoke(%Callable* %12, %Tuple* %6, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %12, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %12, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %1 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i32 0, i32 1 + %n = load i64, i64* %2 + %3 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) + %4 = bitcast %Tuple* %3 to { %Qubit*, i64 }* + %5 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 0 + %6 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %4, i32 0, i32 1 + store %Qubit* %q, %Qubit** %5 + store i64 %n, i64* %6 + call void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %__controlQubits__, { %Qubit*, i64 }* %4) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %3, i64 -1) ret void } -define void @Lifted__PartialApplication__2__ctl__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +define i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %from, i64 %what) { entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* - %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load %Qubit*, %Qubit** %2 - %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 - %7 = load i64, i64* %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* - %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 - store %Qubit* %4, %Qubit** %10 - store i64 %7, i64* %11 - %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) - %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* - %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 - %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 - store %Array* %3, %Array** %14 - store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 - %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 - %17 = load %Callable*, %Callable** %16 - %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) - call void @__quantum__rt__callable_make_controlled(%Callable* %18) - call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + %0 = sub i64 %from, %what + ret i64 %0 +} + +declare void @__quantum__qis__x__body(%Qubit*) + +declare void @__quantum__rt__qubit_release_array(%Array*) + +define void @Microsoft__Quantum__Testing__QIR__Subtract__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { i64, i64 }* + %1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %0, i32 0, i32 1 + %3 = load i64, i64* %1 + %4 = load i64, i64* %2 + %5 = call i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %3, i64 %4) + %6 = bitcast %Tuple* %result-tuple to { i64 }* + %7 = getelementptr inbounds { i64 }, { i64 }* %6, i32 0, i32 0 + store i64 %5, i64* %7 ret void } -define void @Lifted__PartialApplication__2__ctladj__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +define void @Lifted__PartialApplication__2__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { entry: - %0 = bitcast %Tuple* %arg-tuple to { %Array*, %Qubit* }* - %1 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Array*, %Qubit* }, { %Array*, %Qubit* }* %0, i32 0, i32 1 - %3 = load %Array*, %Array** %1 - %4 = load %Qubit*, %Qubit** %2 - %5 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* - %6 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 1 - %7 = load i64, i64* %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint ({ %Qubit*, i64 }* getelementptr ({ %Qubit*, i64 }, { %Qubit*, i64 }* null, i32 1) to i64)) - %9 = bitcast %Tuple* %8 to { %Qubit*, i64 }* - %10 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Qubit*, i64 }, { %Qubit*, i64 }* %9, i32 0, i32 1 - store %Qubit* %4, %Qubit** %10 - store i64 %7, i64* %11 - %12 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) - %13 = bitcast %Tuple* %12 to { %Array*, { %Qubit*, i64 }* }* - %14 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 0 - %15 = getelementptr inbounds { %Array*, { %Qubit*, i64 }* }, { %Array*, { %Qubit*, i64 }* }* %13, i32 0, i32 1 - store %Array* %3, %Array** %14 - store { %Qubit*, i64 }* %9, { %Qubit*, i64 }** %15 - %16 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %5, i32 0, i32 0 - %17 = load %Callable*, %Callable** %16 - %18 = call %Callable* @__quantum__rt__callable_copy(%Callable* %17, i1 false) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 1) - call void @__quantum__rt__callable_make_adjoint(%Callable* %18) - call void @__quantum__rt__callable_make_controlled(%Callable* %18) - call void @__quantum__rt__callable_invoke(%Callable* %18, %Tuple* %12, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %12, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %18, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %18, i64 -1) + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, i64 }* + %1 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 1 + %2 = load i64, i64* %1 + %3 = bitcast %Tuple* %arg-tuple to { i64 }* + %4 = getelementptr inbounds { i64 }, { i64 }* %3, i32 0, i32 0 + %5 = load i64, i64* %4 + %6 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 2)) + %7 = bitcast %Tuple* %6 to { i64, i64 }* + %8 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 0 + %9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %7, i32 0, i32 1 + store i64 %2, i64* %8 + store i64 %5, i64* %9 + %10 = getelementptr inbounds { %Callable*, i64 }, { %Callable*, i64 }* %0, i32 0, i32 0 + %11 = load %Callable*, %Callable** %10 + call void @__quantum__rt__callable_invoke(%Callable* %11, %Tuple* %6, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %6, i64 -1) ret void } @@ -1472,33 +1480,13 @@ entry: ret void } -declare %Callable* @__quantum__rt__callable_copy(%Callable*, i1) - -declare void @__quantum__rt__callable_make_adjoint(%Callable*) - -declare void @__quantum__rt__callable_make_controlled(%Callable*) - -declare %Array* @__quantum__rt__array_create_1d(i32, i64) - -define i1 @Microsoft__Quantum__Intrinsic__IsNegativeInfinity__body(double %d) { -entry: - %0 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) - ret i1 %0 -} - -declare i1 @__quantum__qis__isnegativeinfinity__body(double) - -define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %bases, %Array* %qubits) { +define void @Microsoft__Quantum__Intrinsic__Message__body(%String* %msg) { entry: - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %0 + call void @__quantum__qis__message__body(%String* %msg) + ret void } -declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) +declare void @__quantum__qis__message__body(%String*) define void @Microsoft__Quantum__Intrinsic__K__body(%Qubit* %q) { entry: @@ -1528,6 +1516,26 @@ entry: ret void } +define i1 @Microsoft__Quantum__Intrinsic__IsNegativeInfinity__body(double %d) { +entry: + %0 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d) + ret i1 %0 +} + +declare i1 @__quantum__qis__isnegativeinfinity__body(double) + +define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %bases, %Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__measure__body(%Array* %bases, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %bases, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) + define i1 @Microsoft__Quantum__Intrinsic__IsNan__body(double %d) { entry: %0 = call i1 @__quantum__qis__isnan__body(double %d) @@ -1536,6 +1544,30 @@ entry: declare i1 @__quantum__qis__isnan__body(double) +define double @Microsoft__Quantum__Intrinsic__NAN__body() { +entry: + %0 = call double @__quantum__qis__nan__body() + ret double %0 +} + +declare double @__quantum__qis__nan__body() + +define i1 @Microsoft__Quantum__Intrinsic__IsInf__body(double %d) { +entry: + %0 = call i1 @__quantum__qis__isinf__body(double %d) + ret i1 %0 +} + +declare i1 @__quantum__qis__isinf__body(double) + +define double @Microsoft__Quantum__Intrinsic__INFINITY__body() { +entry: + %0 = call double @__quantum__qis__infinity__body() + ret double %0 +} + +declare double @__quantum__qis__infinity__body() + define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qubit) { entry: call void @__quantum__qis__x__body(%Qubit* %qubit) @@ -1566,37 +1598,11 @@ entry: ret void } -define double @Microsoft__Quantum__Intrinsic__INFINITY__body() { -entry: - %0 = call double @__quantum__qis__infinity__body() - ret double %0 -} - -declare double @__quantum__qis__infinity__body() - -define void @Microsoft__Quantum__Intrinsic__Message__body(%String* %msg) { -entry: - call void @__quantum__qis__message__body(%String* %msg) - ret void -} - -declare void @__quantum__qis__message__body(%String*) - -define i1 @Microsoft__Quantum__Intrinsic__IsInf__body(double %d) { -entry: - %0 = call i1 @__quantum__qis__isinf__body(double %d) - ret i1 %0 -} - -declare i1 @__quantum__qis__isinf__body(double) +declare %String* @__quantum__rt__pauli_to_string(i2) -define double @Microsoft__Quantum__Intrinsic__NAN__body() { -entry: - %0 = call double @__quantum__qis__nan__body() - ret double %0 -} +declare %String* @__quantum__rt__string_concatenate(%String*, %String*) -declare double @__quantum__qis__nan__body() +declare i1 @__quantum__rt__string_equal(%String*, %String*) declare i64 @__quantum__qis__drawrandomint__body(i64, i64) @@ -1607,8 +1613,6 @@ entry: declare double @__quantum__qis__log__body(double) -declare double @__quantum__qis__sqrt__body(double) - declare double @__quantum__qis__arctan2__body(double, double) define double @Microsoft__Quantum__Math__PI__body() { @@ -1616,15 +1620,11 @@ entry: ret double 0x400921FB54442D18 } -declare %String* @__quantum__rt__pauli_to_string(i2) - -declare %String* @__quantum__rt__string_concatenate(%String*, %String*) - -declare i1 @__quantum__rt__string_equal(%String*, %String*) +declare double @__quantum__qis__sqrt__body(double) -define double @Microsoft__Quantum__Math__ArcTan2__body(double %y, double %x) { +define double @Microsoft__Quantum__Math__Sqrt__body(double %d) { entry: - %0 = call double @__quantum__qis__arctan2__body(double %y, double %x) + %0 = call double @__quantum__qis__sqrt__body(double %d) ret double %0 } @@ -1634,9 +1634,9 @@ entry: ret double %0 } -define double @Microsoft__Quantum__Math__Sqrt__body(double %d) { +define double @Microsoft__Quantum__Math__ArcTan2__body(double %y, double %x) { entry: - %0 = call double @__quantum__qis__sqrt__body(double %d) + %0 = call double @__quantum__qis__arctan2__body(double %y, double %x) ret double %0 } diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 2f8961a4d72..f1007acd73e 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -8,10 +8,10 @@ #include "quantum__qis_internal.hpp" -extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body(); // NOLINT -extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__LogTest__body(); // NOLINT -extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body(); // NOLINT -extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(int64_t min, int64_t max); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__LogTest__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body(); // NOLINT +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(int64_t min, int64_t max); // NOLINT TEST_CASE("QIR: Math.Sqrt", "[qir.math][qir.Math.Sqrt]") { @@ -30,94 +30,114 @@ TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") { -#ifdef __APPLE__ - std::vector expectedLargeNumbers( { - -2160833387943730151 /*0xe2032d7b74cf6419*/, 7375078072468444798 /*0x66598a6e9c41167e*/, 7708428399011769513 /*0x6af9d6c9b3a12ca9*/, - -8929332642100591101 /*0x8414a3458a4b4603*/, 9131959130339861073 /*0x7ebb3c72234ae251*/, 2129461186021157660 /*0x1d8d5daa93c5eb1c*/, - -4466415676527644493 /*0xc2041a9b355570b3*/, 2654403080104352464 /*0x24d65589a8529ad0*/, 3948910203829515833 /*0x36cd58e87d2c7639*/, - 3600951923571138577 /*0x31f926b221b7a011*/, -7454003569285620820 /*0x988e0f3f2a3c9bac*/, -2896776822558058671 /*0xd7cc94d3e1d79751*/, - -2510694579170103717 /*0xdd2838951d112e5b*/, -8679035075952589054 /*0x878ddf94f8b0c702*/, -8480296875123573728 /*0x8a4feeec30677c20*/, - - -8613430109842542716 /*0x8876f2f3752e6f84*/, 2140032717197149199 /*0x1db2ec6afc40040f*/, -917262003397267527 /*0xf3453b11598aefb9*/, - -3734430349428794203 /*0xcc2ca3620fdbdca5*/, 5134567830016493736 /*0x4741a63cbf4808a8*/, -8243723698983337761 /*0x8d9868f90fa100df*/, - 5560736588152128922 /*0x4d2bb4770253459a*/, 50526560201835791 /* 0xb381a3888d850f*/, 1288735234894005209 /*0x11e281de3d6303d9*/, - 3656101241126025060 /*0x32bd14b53c2e7764*/, 872395409727236160 /* 0xc1b5f00c4792840*/, 7628415731883617240 /*0x69dd93b0e9ecabd8*/, - -1986081594003691539 /*0xe47005501e77e7ed*/, 7532118334194327900 /*0x688775b7d3dc215c*/, -4186893097968929306 /*0xc5e52ae91706f5e6*/ - } ); - std::vector expectedSmallNumbers( { 1, 4, 2, 4, 5, -2, -4, 9, 4, -4, -9, 9, -1, 5, 7, - -8, 0, 2, 5, 0, -1, 1, 9, -3, 5, -8, -9, 6, -1, 6 } ); -#else - std::vector expectedLargeNumbers( { - -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, - -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, - -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, - 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, - -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, - - -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, - -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, - -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, - 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, - 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ - } ); -#ifdef _WIN32 - std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, - -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); -#else - std::vector expectedSmallNumbers( { -7, 10, -10, 2, 1, -9, 3, -2, 7, 9, -2, 3, 9, -3, -5, - -1, 6, 4, 1, -4, -7, 2, 1, -7, -7, -10, 1, 4, -2, 9 } ); -#endif // #ifdef _WIN32 -#endif // #ifdef __APPLE__ - - // Use const seed (and 100%-predictable sequence of pseudo-random numbers): - Quantum::Qis::Internal::UseRandomSeed(false); - - size_t times = 30; - std::vector actualNumbers; - // Get the actual pseudo-random numbers: - actualNumbers.reserve(times); - while(times--) + // Test that the Q# random number generator is a wrapper around the C++ generator: + size_t times = 1000; + while(--times) { - actualNumbers.emplace_back( - Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(-10, 10)); + const uint64_t qsRndNum = + Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(std::numeric_limits::min(), + std::numeric_limits::max()); + const uint64_t cppRndNum = Quantum::Qis::Internal::GetLastGeneratedRandomNumber(); // This call must be done + // _after_ the Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(). + REQUIRE(qsRndNum == cppRndNum); } - // Compare the actual numbers with the expected ones: - for(auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); - iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) - { - REQUIRE(*iterExp == *iterAct); - } - - - // Repeat for large numbers: - times = 30; - actualNumbers.clear(); - while(times--) - { - actualNumbers.emplace_back( - Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(std::numeric_limits::min(), - std::numeric_limits::max())); - } - - for(auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); - iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) - { - REQUIRE(*iterExp == *iterAct); - } - - // Make sure the correct exception is thrown if min > max: - REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5), - std::runtime_error); + REQUIRE_THROWS_AS(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5), std::runtime_error); // Check the exception string: try { (void)Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(10, 5); } - catch(std::runtime_error const & exc) + catch (std::runtime_error const& exc) { REQUIRE(0 == strcmp(exc.what(), Quantum::Qis::Internal::excStrDrawRandomInt)); } + + // There is a strong difference in the opinions about how the random number generator must be tested. + // More or less agreed-upon items are: + // * The test must be 100% deterministic, i.e. must not fail, even with a very low probability. + // Otherwise it will bother the unrelated CI builds/test-runs, that are done a lot. + // * The test must not be platform-, compiler-, etc. dependent. + // Otherwise it can break upon migration to a newer compiler, OS update, new OS added to the test runs, etc. + // + // The code below is platform-dependent, can also depend on the compiler version. + // Commenting out for now. + + // #ifdef __APPLE__ + // std::vector expectedLargeNumbers( { + // -2160833387943730151 /*0xe2032d7b74cf6419*/, 7375078072468444798 /*0x66598a6e9c41167e*/, 7708428399011769513 /*0x6af9d6c9b3a12ca9*/, + // -8929332642100591101 /*0x8414a3458a4b4603*/, 9131959130339861073 /*0x7ebb3c72234ae251*/, 2129461186021157660 /*0x1d8d5daa93c5eb1c*/, + // -4466415676527644493 /*0xc2041a9b355570b3*/, 2654403080104352464 /*0x24d65589a8529ad0*/, 3948910203829515833 /*0x36cd58e87d2c7639*/, + // 3600951923571138577 /*0x31f926b221b7a011*/, -7454003569285620820 /*0x988e0f3f2a3c9bac*/, -2896776822558058671 /*0xd7cc94d3e1d79751*/, + // -2510694579170103717 /*0xdd2838951d112e5b*/, -8679035075952589054 /*0x878ddf94f8b0c702*/, -8480296875123573728 /*0x8a4feeec30677c20*/, + + // -8613430109842542716 /*0x8876f2f3752e6f84*/, 2140032717197149199 /*0x1db2ec6afc40040f*/, -917262003397267527 /*0xf3453b11598aefb9*/, + // -3734430349428794203 /*0xcc2ca3620fdbdca5*/, 5134567830016493736 /*0x4741a63cbf4808a8*/, -8243723698983337761 /*0x8d9868f90fa100df*/, + // 5560736588152128922 /*0x4d2bb4770253459a*/, 50526560201835791 /* 0xb381a3888d850f*/, 1288735234894005209 /*0x11e281de3d6303d9*/, + // 3656101241126025060 /*0x32bd14b53c2e7764*/, 872395409727236160 /* 0xc1b5f00c4792840*/, 7628415731883617240 /*0x69dd93b0e9ecabd8*/, + // -1986081594003691539 /*0xe47005501e77e7ed*/, 7532118334194327900 /*0x688775b7d3dc215c*/, -4186893097968929306 /*0xc5e52ae91706f5e6*/ + // } ); + // std::vector expectedSmallNumbers( { 1, 4, 2, 4, 5, -2, -4, 9, 4, -4, -9, 9, -1, 5, 7, + // -8, 0, 2, 5, 0, -1, 1, 9, -3, 5, -8, -9, 6, -1, 6 } ); + // #else + // std::vector expectedLargeNumbers( { + // -5906760355100746824 /*0xae06f8c09cdc1bb8*/, -5720189720460620649 /*0xb09dcdc1901a8c97*/, -439612500227010677 /*0xf9e62ec29d25cf8b*/, + // -4480907261563067469 /*0xc1d09e962310a3b3*/, 8861952245290091527 /*0x7afbfa9d4cfdc407*/, 8955350353842143311 /*0x7c47cbb307ee004f*/, + // -6280323296958344769 /*0xa8d7cf3c6a3011bf*/, 3137151747734999458 /*0x2b8966e4aa3d91a2*/, 4939508655077151009 /*0x448ca8f37ed75121*/, + // 6238374286314258160 /*0x5693285c6fb13ef0*/, -6040247118112373857 /*0xac2cbb3fa955c39f*/, -6824740380414679031 /*0xa149a6c8751e6809*/, + // -3380739839894412592 /*0xd11533070d1522d0*/, 7062538648911045657 /*0x62032d7b74cf6419*/, -1848293964386331010 /*0xe6598a6e9c41167e*/, + + // -1514943637843006295 /*0xeaf9d6c9b3a12ca9*/, 294039394754184707 /* 0x414a3458a4b4603*/, -91412906514914735 /*0xfebb3c72234ae251*/, + // -7093910850833618148 /*0x9d8d5daa93c5eb1c*/, 4756956360327131315 /*0x42041a9b355570b3*/, -6568968956750423344 /*0xa4d65589a8529ad0*/, + // -5274461833025259975 /*0xb6cd58e87d2c7639*/, -5622420113283637231 /*0xb1f926b221b7a011*/, 1769368467569154988 /*0x188e0f3f2a3c9bac*/, + // 6326595214296717137 /*0x57cc94d3e1d79751*/, 6712677457684672091 /*0x5d2838951d112e5b*/, 544336960902186754 /* 0x78ddf94f8b0c702*/, + // 743075161731202080 /* 0xa4feeec30677c20*/, 609941927012233092 /* 0x876f2f3752e6f84*/, -7083339319657626609 /*0x9db2ec6afc40040f*/ + // } ); + // #ifdef _WIN32 + // std::vector expectedSmallNumbers( { -7, 7, 0, -4, 9, -8, -6, 2, 10, -2, -2, 5, -6, 7, -6, + // -8, -7, 7, 1, 0, -7, -4, -4, -5, 9, 6, 9, 8, 0, 10 } ); + // #else + // std::vector expectedSmallNumbers( { -7, 10, -10, 2, 1, -9, 3, -2, 7, 9, -2, 3, 9, -3, -5, + // -1, 6, 4, 1, -4, -7, 2, 1, -7, -7, -10, 1, 4, -2, 9 } ); + // #endif // #ifdef _WIN32 + // #endif // #ifdef __APPLE__ + + // // Use const seed (and 100%-predictable sequence of pseudo-random numbers): + // Quantum::Qis::Internal::RandomizeSeed(false); + + // size_t times = 30; + // std::vector actualNumbers; + // // Get the actual pseudo-random numbers: + // actualNumbers.reserve(times); + // while (times--) + // { + // actualNumbers.emplace_back(Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(-10, 10)); + // } + + // // Compare the actual numbers with the expected ones: + // for (auto iterExp = expectedSmallNumbers.begin(), iterAct = actualNumbers.begin(); + // iterExp != expectedSmallNumbers.end(); ++iterExp, ++iterAct) + // { + // REQUIRE(*iterExp == *iterAct); + // } + + + // // Repeat for large numbers: + // times = 30; + // actualNumbers.clear(); + // while (times--) + // { + // actualNumbers.emplace_back( + // Microsoft__Quantum__Testing__QIR__Math__TestDrawRandomInt__body(std::numeric_limits::min(), + // std::numeric_limits::max())); + // } + + // for (auto iterExp = expectedLargeNumbers.begin(), iterAct = actualNumbers.begin(); + // iterExp != expectedLargeNumbers.end(); ++iterExp, ++iterAct) + // { + // REQUIRE(*iterExp == *iterAct); + // } + } // TEST_CASE("QIR: Math.DrawRandomInt", "[qir.math][qir.Math.DrawRandomInt]") diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 4c7b10becfa..8456be356b0 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -8,24 +8,24 @@ #include "qirTypes.hpp" #include "quantum__qis_internal.hpp" -extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(QirString*); // NOLINT +extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(void*); // NOLINT // https://stackoverflow.com/a/5419388/6362941 // https://github.com/microsoft/qsharp-runtime/pull/511#discussion_r574170031 // https://github.com/microsoft/qsharp-runtime/pull/511#discussion_r574194191 -struct QOstreamRedirector +struct OstreamRedirectorScoped { - QOstreamRedirector(std::ostream & newOstream) + OstreamRedirectorScoped(std::ostream& newOstream) : old(Quantum::Qis::Internal::SetOutputStream(newOstream)) {} - ~QOstreamRedirector() + ~OstreamRedirectorScoped() { Quantum::Qis::Internal::SetOutputStream(old); } -private: + private: std::ostream& old; }; @@ -38,7 +38,7 @@ TEST_CASE("QIR: Out.Message", "[qir.Out][qir.Out.Message]") std::ostringstream outStrStream; { - QOstreamRedirector qOStreamRedirector(outStrStream); // Redirect the output from std::cout to outStrStream. + OstreamRedirectorScoped qOStreamRedirector(outStrStream); // Redirect the output from std::cout to outStrStream. // Log something (to the redirected output): QirString qstr{std::string(testStr1)};