diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index 58701c2d2da..37455ba9634 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -70,6 +70,7 @@ add_dependencies(qir-rt ${bridge_rt_target}) # set(qis_sup_source_files "intrinsics.cpp" + "intrinsicsMath.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 9a011f112a4..1c93d58f0fe 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -13,7 +13,7 @@ %Range = type { i64, i64, i64 } %Result = type opaque %String = type opaque -%Pauli = type {i2} +%Pauli = type i2 ;======================================================================================================================= ; Native types @@ -29,9 +29,7 @@ %struct.QirCallable = type opaque %struct.QirRange = type { i64, i64, i64 } %struct.QirString = type opaque - -; Assumptions: -; %PauliId = type {i32} +%PauliId = type i32 ;=============================================================================== ; declarations of the native methods this bridge delegates to @@ -139,53 +137,53 @@ define %Result* @__quantum__qis__measure__body(%Array* %.paulis, %Array* %.qubit ret %Result* %.r } -define void @__quantum__qis__r__body(i2 %.pauli, double %theta, %Qubit* %.q) { +define void @__quantum__qis__r__body(%Pauli %.pauli, double %theta, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* - %pauli = zext i2 %.pauli to i32 - call void @quantum__qis__r__body(i32 %pauli, double %theta, %class.QUBIT* %q) + %pauli = zext %Pauli %.pauli to %PauliId + call void @quantum__qis__r__body(%PauliId %pauli, double %theta, %class.QUBIT* %q) ret void } -define void @__quantum__qis__r__adj(i2 %.pauli, double %theta, %Qubit* %.q) { +define void @__quantum__qis__r__adj(%Pauli %.pauli, double %theta, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* - %pauli = zext i2 %.pauli to i32 - call void @quantum__qis__r__adj(i32 %pauli, double %theta, %class.QUBIT* %q) + %pauli = zext %Pauli %.pauli to %PauliId + call void @quantum__qis__r__adj(%PauliId %pauli, double %theta, %class.QUBIT* %q) ret void } -define void @__quantum__qis__r__ctl(%Array* %.ctls, {i2, double, %Qubit*}* %.args) { +define void @__quantum__qis__r__ctl(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* - %.ppauli = getelementptr inbounds {i2, double, %Qubit*}, {i2, double, %Qubit*}* %.args, i32 0, i32 0 - %.pauli = load i2, i2* %.ppauli - %pauli = zext i2 %.pauli to i32 + %.ppauli = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 0 + %.pauli = load %Pauli, %Pauli* %.ppauli + %pauli = zext %Pauli %.pauli to %PauliId - %.ptheta = getelementptr inbounds {i2, double, %Qubit*}, {i2, double, %Qubit*}* %.args, i32 0, i32 1 + %.ptheta = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 1 %theta = load double, double* %.ptheta - %.pq = getelementptr inbounds {i2, double, %Qubit*}, {i2, double, %Qubit*}* %.args, i32 0, i32 2 + %.pq = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 2 %.q = load %Qubit*, %Qubit** %.pq %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__r__ctl(%struct.QirArray* %ctls, i32 %pauli, double %theta, %class.QUBIT* %q) + call void @quantum__qis__r__ctl(%struct.QirArray* %ctls, %PauliId %pauli, double %theta, %class.QUBIT* %q) ret void } -define void @__quantum__qis__r__ctladj(%Array* %.ctls, {i2, double, %Qubit*}* %.args) { +define void @__quantum__qis__r__ctladj(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* - %.ppauli = getelementptr inbounds {i2, double, %Qubit*}, {i2, double, %Qubit*}* %.args, i32 0, i32 0 - %.pauli = load i2, i2* %.ppauli - %pauli = zext i2 %.pauli to i32 + %.ppauli = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 0 + %.pauli = load %Pauli, %Pauli* %.ppauli + %pauli = zext %Pauli %.pauli to %PauliId - %.ptheta = getelementptr inbounds {i2, double, %Qubit*}, {i2, double, %Qubit*}* %.args, i32 0, i32 1 + %.ptheta = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 1 %theta = load double, double* %.ptheta - %.pq = getelementptr inbounds {i2, double, %Qubit*}, {i2, double, %Qubit*}* %.args, i32 0, i32 2 + %.pq = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 2 %.q = load %Qubit*, %Qubit** %.pq %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__r__ctladj(%struct.QirArray* %ctls, i32 %pauli, double %theta, %class.QUBIT* %q) + call void @quantum__qis__r__ctladj(%struct.QirArray* %ctls, %PauliId %pauli, double %theta, %class.QUBIT* %q) ret void } @@ -281,3 +279,60 @@ define void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) { } +;=============================================================================== +; quantum.qis math functions +; + +; LLVM intrinsics (https://llvm.org/docs/LangRef.html): +declare double @llvm.sqrt.f64(double %.val) +declare double @llvm.log.f64(double %Val) + +; Native implementations: +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) + +; API for the user code: +define double @__quantum__qis__nan__body() { ; Q#: function NAN() : Double http://www.cplusplus.com/reference/cmath/nan-function/ + %result = call double @llvm.sqrt.f64(double -1.0) ; sqrt() -> NaN + ret double %result +} + +define i1 @__quantum__qis__isnan__body(double %d) { ; http://www.cplusplus.com/reference/cmath/isnan/ + %result = call i1 @quantum__qis__isnan__body(double %d) + ret i1 %result +} + +define double @__quantum__qis__infinity__body() { ; https://en.cppreference.com/w/c/numeric/math/INFINITY + %result = call double @quantum__qis__infinity__body() + ret double %result +} + +define i1 @__quantum__qis__isinf__body(double %d) { ; https://en.cppreference.com/w/cpp/numeric/math/isinf + %result = call i1 @quantum__qis__isinf__body(double %d) + ret i1 %result +} + +define double @__quantum__qis__sqrt__body(double %d) { ; https://en.cppreference.com/w/cpp/numeric/math/sqrt + %result = call double @llvm.sqrt.f64(double %d) + ret double %result +} + +define double @__quantum__qis__log__body(double %d) { ; https://en.cppreference.com/w/cpp/numeric/math/log + %result = call double @llvm.log.f64(double %d) + ret double %result +} + +define i1 @__quantum__qis__isnegativeinfinity__body(double %d) { ; Q#: function IsNegativeInfinity(d : Double) : Bool + ; https://en.cppreference.com/w/cpp/numeric/math/log https://llvm.org/docs/LangRef.html#llvm-log-intrinsic + %negInf = call double @llvm.log.f64(double 0.0) ; ln(0) -> (-infinity) + %result = fcmp oeq double %negInf, %d ; %result = (%negInf == %d) + ret i1 %result +} + +define double @__quantum__qis__arctan2__body(double %y, double %x) { ; Q#: function ArcTan2 (y : Double, x : Double) : Double + ; https://en.cppreference.com/w/cpp/numeric/math/atan2 + %result = call double @quantum__qis__arctan2__body(double %y, double %x) + ret double %result +} diff --git a/src/QirRuntime/lib/QIR/bridge-rt.ll b/src/QirRuntime/lib/QIR/bridge-rt.ll index dc9ea4995e0..73a33d737a6 100644 --- a/src/QirRuntime/lib/QIR/bridge-rt.ll +++ b/src/QirRuntime/lib/QIR/bridge-rt.ll @@ -11,7 +11,7 @@ %Result = type opaque %String = type opaque %Tuple = type opaque -%Pauli = type {i2} +%Pauli = type i2 ;======================================================================================================================= ; Native types @@ -27,6 +27,7 @@ %"struct.QirCallable" = type opaque %"struct.QirRange" = type { i64, i64, i64 } %"struct.QirString" = type opaque +%PauliId = type i32 ; %Tuple* is mapped to i8* ;======================================================================================================================= @@ -97,7 +98,7 @@ declare %"struct.QirString"* @quantum__rt__int_to_string(i64) declare %"struct.QirString"* @quantum__rt__double_to_string(double) declare %"struct.QirString"* @quantum__rt__bool_to_string(i1) declare %"struct.QirString"* @quantum__rt__result_to_string(%class.RESULT*) -declare %"struct.QirString"* @quantum__rt__pauli_to_string(i32) +declare %"struct.QirString"* @quantum__rt__pauli_to_string(%PauliId) declare %"struct.QirString"* @quantum__rt__qubit_to_string(%class.QUBIT*) declare %"struct.QirString"* @quantum__rt__range_to_string(%"struct.QirRange"* dereferenceable(24) %range) @@ -378,10 +379,9 @@ define void @__quantum__rt__callable_memory_management(i32 %index, %Callable* %. ; strings bridge ; ; NYI: -;define %String* @__quantum__rt__pauli_to_string(%Pauli) ; need to check that the type is lowered correctly ;define %String* @__quantum__rt__bigint_to_string(%BigInt*) -define %String* @__quantum__rt__string_create(i8* %null_terminated_buffer) { +define %String* @__quantum__rt__string_create(i32 %ignoredStrLength, i8* %null_terminated_buffer) { %str = call %"struct.QirString"* @quantum__rt__string_create(i8* %null_terminated_buffer) %.str = bitcast %"struct.QirString"* %str to %String* ret %String* %.str @@ -435,6 +435,13 @@ define %String* @__quantum__rt__result_to_string(%Result* %.r) { ret %String* %.str } +define %String* @__quantum__rt__pauli_to_string(%Pauli %.pauli) { + %pauli = zext %Pauli %.pauli to %PauliId + %str = call %"struct.QirString"* @quantum__rt__pauli_to_string(%PauliId %pauli) + %.str = bitcast %"struct.QirString"* %str to %String* + ret %String* %.str +} + define %String* @__quantum__rt__qubit_to_string(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %"class.QUBIT"* %str = call %"struct.QirString"* @quantum__rt__qubit_to_string(%"class.QUBIT"* %q) @@ -451,7 +458,6 @@ define %String* @__quantum__rt__range_to_string(%Range %.range) { ret %String* %.str } - ;------------------------------------------------------------------------------ ; bigints bridge ; diff --git a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp new file mode 100644 index 00000000000..a3b97e420e9 --- /dev/null +++ b/src/QirRuntime/lib/QIR/intrinsicsMath.cpp @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include +#include "quantum__qis.hpp" + +extern "C" +{ + +// Implementations: +bool quantum__qis__isnan__body(double d) +{ + return std::isnan(d); // https://en.cppreference.com/w/cpp/numeric/math/isnan +} + +double quantum__qis__infinity__body() +{ + return INFINITY; // https://en.cppreference.com/w/c/numeric/math/INFINITY +} + +bool quantum__qis__isinf__body(double d) +{ + return std::isinf(d); // https://en.cppreference.com/w/cpp/numeric/math/isinf +} + +double quantum__qis__arctan2__body(double y, double x) +{ + return std::atan2(y, x); // https://en.cppreference.com/w/cpp/numeric/math/atan2 +} + +} // extern "C" diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QIR/quantum__qis.hpp index 8f90770c9c2..50e8c249016 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis.hpp @@ -59,4 +59,10 @@ extern "C" QIR_SHARED_API void quantum__qis__y__ctl(QirArray*, QUBIT*); // NOLINT QIR_SHARED_API void quantum__qis__z__body(QUBIT*); // NOLINT QIR_SHARED_API void quantum__qis__z__ctl(QirArray*, QUBIT*); // NOLINT + + 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 + QIR_SHARED_API double quantum__qis__arctan2__body(double y, double x); // NOLINT + } \ No newline at end of file diff --git a/src/QirRuntime/lib/QIR/strings.cpp b/src/QirRuntime/lib/QIR/strings.cpp index 3885bbdf3cb..0435329a1ef 100644 --- a/src/QirRuntime/lib/QIR/strings.cpp +++ b/src/QirRuntime/lib/QIR/strings.cpp @@ -135,7 +135,10 @@ extern "C" return quantum__rt__string_create("PauliY"); case PauliId_Z: return quantum__rt__string_create("PauliZ"); + default: + break; } + return quantum__rt__string_create(""); } // Returns a string representation of the range. diff --git a/src/QirRuntime/public/CoreTypes.hpp b/src/QirRuntime/public/CoreTypes.hpp index 6dd527f7f85..99319f8beaf 100644 --- a/src/QirRuntime/public/CoreTypes.hpp +++ b/src/QirRuntime/public/CoreTypes.hpp @@ -1,5 +1,7 @@ #pragma once +#include + // The core types will be exposed in the C-interfaces for interop, thus no // namespaces or scoped enums can be used to define them. @@ -27,7 +29,7 @@ enum ResultValue /*============================================================================== PauliId matrices ==============================================================================*/ -enum PauliId +enum PauliId : int32_t { PauliId_I = 0, PauliId_X = 1, diff --git a/src/QirRuntime/test/QIR-static/CMakeLists.txt b/src/QirRuntime/test/QIR-static/CMakeLists.txt index 7a7e99eb1fb..ae056c3453b 100644 --- a/src/QirRuntime/test/QIR-static/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-static/CMakeLists.txt @@ -20,7 +20,10 @@ add_custom_target(qir_static_test_lib DEPENDS ${QIR_TESTS_LIBS}) # The executable target for QIR tests triggers the custom actions to compile ll files # add_executable(qir-static-tests - qir-driver.cpp) + qir-driver.cpp + qir-test-math.cpp + qir-test-strings.cpp +) target_link_libraries(qir-static-tests PUBLIC ${QIR_TESTS_LIBS} diff --git a/src/QirRuntime/test/QIR-static/compiler/Constants.qs b/src/QirRuntime/test/QIR-static/compiler/Constants.qs new file mode 100644 index 00000000000..1192459dbb2 --- /dev/null +++ b/src/QirRuntime/test/QIR-static/compiler/Constants.qs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// these are all the static methods and const fields form System.Math class of .NET CLR +// that are not exposed as language operators and are relevant within type System. +// If there are two versions of the function for Int and Double types, the corresponding +// functions have suffix I or D. ExpD also has a suffix to avoid name clash with Primitives.Exp. + +namespace Microsoft.Quantum.Math { + + /// # Summary + /// Returns the natural logarithmic base to double-precision. + /// + /// # Output + /// A double-precision approximation of the natural logarithic base, + /// $e \approx 2.7182818284590452354$. + /// + /// # See Also + /// - Microsoft.Quantum.Math.PI + function E() : Double { + return 2.7182818284590452354; + } + + /// # Summary + /// Represents the ratio of the circumference of a circle to its diameter. + /// + /// # Ouptut + /// A double-precision approximation of the the circumference of a circle + /// to its diameter, $\pi \approx 3.14159265358979323846$. + /// + /// # See Also + /// - Microsoft.Quantum.Math.E + function PI() : Double { + return 3.14159265358979323846; + } + +} diff --git a/src/QirRuntime/test/QIR-static/compiler/QirTarget.qs b/src/QirRuntime/test/QIR-static/compiler/QirTarget.qs index 9b8a7833579..c117bdd0667 100644 --- a/src/QirRuntime/test/QIR-static/compiler/QirTarget.qs +++ b/src/QirRuntime/test/QIR-static/compiler/QirTarget.qs @@ -5,6 +5,47 @@ namespace Microsoft.Quantum.Intrinsic { open Microsoft.Quantum.Targeting; + @Inline() + function NAN() : Double { + body intrinsic; + } + + @Inline() + function IsNan(d: Double) : Bool { + body intrinsic; + } + + @Inline() + function INFINITY() : Double { + body intrinsic; + } + + @Inline() + function IsInf(d: Double) : Bool { + body intrinsic; + } + + @Inline() + function IsNegativeInfinity(d : Double) : Bool { + body intrinsic; + } + + @Inline() + function Sqrt(d : Double) : Double { + body intrinsic; + } + + @Inline() + function Log(d : Double) : Double { + body intrinsic; + } + + @Inline() + function ArcTan2(y : Double, x : Double) : Double { + body intrinsic; + } + + operation X(qb : Qubit) : Unit is Adj + Ctl { body intrinsic; diff --git a/src/QirRuntime/test/QIR-static/generate.py b/src/QirRuntime/test/QIR-static/generate.py index af6daa37c5e..99242f689b4 100644 --- a/src/QirRuntime/test/QIR-static/generate.py +++ b/src/QirRuntime/test/QIR-static/generate.py @@ -39,7 +39,7 @@ def log(message): output_file = file_name command = (qsc + " build --qir s --build-exe --input " + files_to_process + - " compiler\\qircore.qs compiler\\qirtarget.qs --proj " + output_file) + " compiler\\qircore.qs compiler\\qirtarget.qs compiler\\Constants.qs --proj " + output_file) log("Executing: " + command) subprocess.run(command, shell = True) diff --git a/src/QirRuntime/test/QIR-static/qir-driver.cpp b/src/QirRuntime/test/QIR-static/qir-driver.cpp index bac6bc26414..c6059c93a8e 100644 --- a/src/QirRuntime/test/QIR-static/qir-driver.cpp +++ b/src/QirRuntime/test/QIR-static/qir-driver.cpp @@ -57,8 +57,8 @@ extern "C" int64_t Microsoft__Quantum__Testing__QIR__Test_Arrays( // NOLINT int64_t* array, int64_t index, int64_t val, - bool dummy); -TEST_CASE("QIR: Using 1D arrays", "[qir]") + bool compilerDecoy); +TEST_CASE("QIR: Using 1D arrays", "[qir][qir.arr1d]") { // re-enable tracking when https://github.com/microsoft/qsharp-compiler/issues/844 is fixed QirContextScope qirctx(nullptr, false /*trackAllocatedObjects*/); @@ -152,7 +152,7 @@ struct QubitsResultsTestSimulator : public Microsoft::Quantum::SimulatorStub return reinterpret_cast(1); } }; -TEST_CASE("QIR: allocating and releasing qubits and results", "[qir]") +TEST_CASE("QIR: allocating and releasing qubits and results", "[qir][qir.qubit][qir.result]") { unique_ptr sim = make_unique(); QirContextScope qirctx(sim.get(), true /*trackAllocatedObjects*/); @@ -182,7 +182,7 @@ TEST_CASE("QIR: allocating and releasing qubits and results", "[qir]") // that is written to the original array at [1,1,1] and then retrieved from [1,1]. // Thus, all three dimensions must be at least 2. extern "C" int64_t TestMultidimArrays(char value, int64_t dim0, int64_t dim1, int64_t dim2); -TEST_CASE("QIR: multidimensional arrays", "[qir]") +TEST_CASE("QIR: multidimensional arrays", "[qir][qir.arrMultid]") { QirContextScope qirctx(nullptr, true /*trackAllocatedObjects*/); @@ -195,7 +195,7 @@ TEST_CASE("QIR: multidimensional arrays", "[qir]") // Manually authored QIR to test dumping range [0..2..6] into string and then raising a failure with it extern "C" void TestFailWithRangeString(int64_t start, int64_t step, int64_t end); -TEST_CASE("QIR: Report range in a failure message", "[qir]") +TEST_CASE("QIR: Report range in a failure message", "[qir][qir.range]") { QirContextScope qirctx(nullptr, true /*trackAllocatedObjects*/); @@ -215,7 +215,7 @@ TEST_CASE("QIR: Report range in a failure message", "[qir]") #if 0 // TODO: Q# compiler crashes generating QIR for TestPartials // TestPartials subtracts the second argument from the first and returns the result. extern "C" int64_t Microsoft__Quantum__Testing__QIR__TestPartials__body(int64_t, int64_t); // NOLINT -TEST_CASE("QIR: Partial application of a callable", "[qir]") +TEST_CASE("QIR: Partial application of a callable", "[qir][qir.partCallable]") { QirContextScope qirctx(nullptr, true /*trackAllocatedObjects*/); @@ -309,7 +309,7 @@ extern "C" void __quantum__qis__k__ctl(QirArray* controls, Qubit q) // NOLINT { g_ctrqapi->ControlledX(controls->count, reinterpret_cast(controls->buffer), q); } -TEST_CASE("QIR: application of nested controlled functor", "[qir]") +TEST_CASE("QIR: application of nested controlled functor", "[qir][qir.functor]") { unique_ptr qapi = make_unique(); QirContextScope qirctx(qapi.get(), true /*trackAllocatedObjects*/); diff --git a/src/QirRuntime/test/QIR-static/qir-test-arrays.qs b/src/QirRuntime/test/QIR-static/qir-test-arrays.qs index 9752c047d00..65d05ca8ef2 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-arrays.qs +++ b/src/QirRuntime/test/QIR-static/qir-test-arrays.qs @@ -3,8 +3,11 @@ namespace Microsoft.Quantum.Testing.QIR { + open Microsoft.Quantum.Testing.QIR.Math; + open Microsoft.Quantum.Testing.QIR.Str; + @EntryPoint() - operation Test_Arrays(array : Int[], index : Int, val : Int, dummy : Bool) : Int + operation Test_Arrays(array : Int[], index : Int, val : Int, compilerDecoy : Bool) : Int { // exercise __quantum__rt__array_copy mutable local = array; @@ -30,12 +33,17 @@ namespace Microsoft.Quantum.Testing.QIR } // The purpose of this block is to keep the Q# compiler from optimizing away other tests when generating QIR - if (dummy) + if (compilerDecoy) { let res1 = TestControlled(); - //Q# compiler crashes if both TestControlled and TestPartials are enabled - //let res2 = TestPartials(17, 42); + let res2 = TestPartials(17, 42); let res3 = Test_Qubit_Result_Management(); + + // Math tests: + let res4 = SqrtTest(); + let res5 = LogTest(); + let res6 = ArcTan2Test(); + let res7 = PauliToStringTest(); } return sum; diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp new file mode 100644 index 00000000000..27ccea024f0 --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include + +#include "catch.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 + +TEST_CASE("QIR: Math.Sqrt", "[qir.math][qir.Math.Sqrt]") +{ + REQUIRE(0 == Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body()); +} + +TEST_CASE("QIR: Math.Log", "[qir.math][qir.Math.Log]") +{ + REQUIRE(0 == Microsoft__Quantum__Testing__QIR__Math__LogTest__body()); +} + +TEST_CASE("QIR: Math.ArcTan2", "[qir.math][qir.Math.ArcTan2]") +{ + REQUIRE(0 == Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body()); +} + diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.qs b/src/QirRuntime/test/QIR-static/qir-test-math.qs new file mode 100644 index 00000000000..bdca70c30b9 --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-test-math.qs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Testing.QIR.Math { + + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Math; // E() + + function SqrtTest() : Int { + if 2.0 != Sqrt( 4.0) { return 1; } // The return value indicates which test case has failed. + if 3.0 != Sqrt( 9.0) { return 2; } + if 10.0 != Sqrt(100.0) { return 3; } + + if not IsNan(Sqrt(-5.0)) { return 4; } + if not IsNan(Sqrt(NAN())) { return 5; } + if not IsInf(Sqrt(INFINITY())) { return 6; } + + return 0; + } + + function LogTest() : Int { + if 1.0 != Log(E()) { return 1; } // ln(e) -> 1 // The return value indicates which test case has failed. + if 2.0 != Log(E() * E()) { return 2; } // ln(e^2) -> 2 + + if not IsNegativeInfinity(Log(0.0)) { return 3; } // ln(0) -> (-nfinity) + if not IsNan(Log(-5.0)) { return 4; } // ln() -> NaN + if not IsNan(Log(NAN())) { return 5; } // ln(NaN) -> NaN + if not IsInf(Log(INFINITY())) { return 6; } // ln(+infinity) -> +infinity + + return 0; + } + + function ArcTan2Test() : Int { + + // function ArcTan2(y : Double, x : Double) : Double + + if 0.0 != ArcTan2( 0.0, 1.0 ) { return 1; } // The return value indicates which test case has failed. + if PI() != ArcTan2( 0.0, -1.0 ) { return 2; } + if PI()/2.0 != ArcTan2( 1.0, 0.0 ) { return 3; } + if -PI()/2.0 != ArcTan2(-1.0, 0.0 ) { return 4; } + + if PI()/4.0 != ArcTan2( 1.0, 1.0 ) { return 5; } + if PI()*3.0/4.0 != ArcTan2( 1.0, -1.0 ) { return 6; } + if -PI()*3.0/4.0 != ArcTan2(-1.0, -1.0 ) { return 7; } + if -PI()/4.0 != ArcTan2(-1.0, 1.0 ) { return 8; } + + if 0.0 != ArcTan2( 0.0, 0.0 ) { return 9; } + + // Fails because of lack of precision: + // if PI()/6.0 != ArcTan2( 1.0, Sqrt(3.0) ) { return 10; } // tg(Pi/6) = sin(Pi/6) / cos(Pi/6) = (1/2) / (Sqrt(3)/2) = 1/Sqrt(3) = y/x. ArcTan2(1.0, Sqrt(3)) -> Pi/6 + + if not IsNan(ArcTan2(NAN(), 0.0) ) { return 11; } + if not IsNan(ArcTan2( 0.0, NAN()) ) { return 12; } + if not IsNan(ArcTan2(NAN(), NAN()) ) { return 13; } + + // The infinity cases show discrepancy between + // https://docs.microsoft.com/en-us/dotnet/api/system.math.atan2?view=net-5.0 + // and https://en.cppreference.com/w/cpp/numeric/math/atan2 . + + return 0; + } + +} + diff --git a/src/QirRuntime/test/QIR-static/qir-test-qsharp.ll b/src/QirRuntime/test/QIR-static/qir-test-qsharp.ll index 774cf5774ac..a619a2a6218 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-qsharp.ll +++ b/src/QirRuntime/test/QIR-static/qir-test-qsharp.ll @@ -2,9 +2,10 @@ %Result = type opaque %Range = type { i64, i64, i64 } %Tuple = type opaque +%Callable = type opaque %Qubit = type opaque %Array = type opaque -%Callable = type opaque +%String = type opaque @ResultZero = external global %Result* @ResultOne = external global %Result* @@ -16,111 +17,14 @@ @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] - -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__body(%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__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 void @__quantum__rt__array_update_alias_count(%Array*, i64) - -declare void @__quantum__qis__k__ctl(%Array*, %Qubit*) - -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 %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qb) { -entry: - %bases__inline__1 = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 1) - %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %bases__inline__1, 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__inline__1, i64 1) - %qubits__inline__1 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %3 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits__inline__1, i64 0) - %4 = bitcast i8* %3 to %Qubit** - store %Qubit* %qb, %Qubit** %4 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits__inline__1, i64 1) - %5 = call %Result* @__quantum__qis__measure__body(%Array* %bases__inline__1, %Array* %qubits__inline__1) - call void @__quantum__rt__array_update_alias_count(%Array* %bases__inline__1, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits__inline__1, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %bases__inline__1, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qubits__inline__1, i64 -1) - ret %Result* %5 -} - -declare %Array* @__quantum__rt__array_create_1d(i32, i64) - -declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) - -declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) - -declare void @__quantum__rt__array_update_reference_count(%Array*, i64) - -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 -} - -define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__x__body(%Qubit* %qb) - ret void -} - -declare void @__quantum__qis__x__body(%Qubit*) - -define void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__x__body(%Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__x__ctl(%Array* %__controlQubits__, %Qubit* %qb) - 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* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__x__ctl(%Array* %__controlQubits__, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} +@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] +@0 = internal constant [20 x i8] c"Pauli value: PauliI\00" +@1 = internal constant [14 x i8] c"Pauli value: \00" +@2 = internal constant [7 x i8] c"PauliX\00" +@3 = internal constant [7 x i8] c"PauliY\00" +@4 = internal constant [7 x i8] c"PauliZ\00" define i64 @Microsoft__Quantum__Testing__QIR__TestControlled__body() { entry: @@ -633,17 +537,128 @@ 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* %qb) { +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* %qb, %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 %Array* @__quantum__rt__array_create_1d(i32, i64) + +declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) + declare void @__quantum__rt__qubit_release(%Qubit*) declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) +declare void @__quantum__rt__array_update_reference_count(%Array*, i64) + declare void @__quantum__rt__result_update_reference_count(%Result*, i64) -define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %array, i64 %index, i64 %val, i1 %dummy) { +define i64 @Microsoft__Quantum__Testing__QIR__Subtract__body(i64 %from, i64 %what) { +entry: + %0 = sub i64 %from, %what + ret i64 %0 +} + +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: + %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 +} + +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 { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 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__rt__array_update_alias_count(%Array*, i64) + +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 { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 0, i32 0 + %q = load %Qubit*, %Qubit** %1 + %2 = getelementptr { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 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* %__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) + br label %continue__1 + +continue__1: ; preds = %then0__1, %entry + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +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* @@ -699,11 +714,16 @@ exiting__1: ; preds = %body__1 br label %header__1 exit__1: ; preds = %header__1 - br i1 %dummy, label %then0__1, label %continue__1 + br i1 %compilerDecoy, label %then0__1, label %continue__1 then0__1: ; preds = %exit__1 %res1 = call i64 @Microsoft__Quantum__Testing__QIR__TestControlled__body() + %res2 = call i64 @Microsoft__Quantum__Testing__QIR__TestPartials__body(i64 17, i64 42) %res3 = call i1 @Microsoft__Quantum__Testing__QIR__Test_Qubit_Result_Management__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() br label %continue__1 continue__1: ; preds = %then0__1, %exit__1 @@ -730,14 +750,44 @@ 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 { %Callable*, i64 }, { %Callable*, i64 }* %1, i64 0, i32 0 + %3 = getelementptr { %Callable*, i64 }, { %Callable*, i64 }* %1, i64 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 { i64 }, { i64 }* %6, i64 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 { i64 }, { i64 }* %9, i64 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 i1 @Microsoft__Quantum__Testing__QIR__Test_Qubit_Result_Management__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** - %qb__inline__1 = load %Qubit*, %Qubit** %1 - call void @__quantum__qis__x__body(%Qubit* %qb__inline__1) + %qb = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__x__body(%Qubit* %qb) %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** @@ -769,81 +819,550 @@ continue__1: ; preds = %then0__1, %entry ret i1 %14 } -define void @Microsoft__Quantum__Testing__QIR__Qop__body(%Qubit* %q, i64 %n) { +define i64 @Microsoft__Quantum__Testing__QIR__Math__SqrtTest__body() { entry: - %0 = srem i64 %n, 2 - %1 = icmp eq i64 %0, 1 + %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 - call void @__quantum__qis__k__body(%Qubit* %q) - br label %continue__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 + +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 -continue__1: ; preds = %then0__1, %entry - ret void +then0__6: ; preds = %continue__5 + ret i64 6 + +continue__6: ; preds = %continue__5 + ret i64 0 } -define void @Microsoft__Quantum__Testing__QIR__Qop__adj(%Qubit* %q, i64 %n) { +define i64 @Microsoft__Quantum__Testing__QIR__Math__LogTest__body() { entry: - %0 = srem i64 %n, 2 - %1 = icmp eq i64 %0, 1 + %d = call double @Microsoft__Quantum__Math__E__body() + %0 = call double @__quantum__qis__log__body(double %d) + %1 = fcmp one double 1.000000e+00, %0 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 + ret i64 1 + +continue__1: ; preds = %entry + %2 = call double @Microsoft__Quantum__Math__E__body() + %3 = call double @Microsoft__Quantum__Math__E__body() + %d__1 = fmul double %2, %3 + %4 = call double @__quantum__qis__log__body(double %d__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__3 = call double @__quantum__qis__log__body(double 0.000000e+00) + %6 = call i1 @__quantum__qis__isnegativeinfinity__body(double %d__3) + %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__5 = call double @__quantum__qis__log__body(double -5.000000e+00) + %8 = call i1 @__quantum__qis__isnan__body(double %d__5) + %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 + %d__6 = call double @__quantum__qis__nan__body() + %d__7 = call double @__quantum__qis__log__body(double %d__6) + %10 = call i1 @__quantum__qis__isnan__body(double %d__7) + %11 = xor i1 %10, true + br i1 %11, label %then0__5, label %continue__5 -continue__1: ; preds = %then0__1, %entry - ret void +then0__5: ; preds = %continue__4 + ret i64 5 + +continue__5: ; preds = %continue__4 + %d__8 = call double @__quantum__qis__infinity__body() + %d__9 = call double @__quantum__qis__log__body(double %d__8) + %12 = call i1 @__quantum__qis__isinf__body(double %d__9) + %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 void @Microsoft__Quantum__Testing__QIR__Qop__ctl(%Array* %ctrls, { %Qubit*, i64 }* %0) { +define i64 @Microsoft__Quantum__Testing__QIR__Math__ArcTan2Test__body() { entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 1) - %1 = getelementptr { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 0, i32 0 - %q = load %Qubit*, %Qubit** %1 - %2 = getelementptr { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 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 + %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__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 + 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 +} -continue__1: ; preds = %then0__1, %entry - call void @__quantum__rt__array_update_alias_count(%Array* %ctrls, i64 -1) +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]* @0, i32 0, i32 0)) + %1 = call %String* @__quantum__rt__string_create(i32 13, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @1, 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]* @2, 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]* @3, 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]* @4, 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 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 { i64, i64 }, { i64, i64 }* %0, i64 0, i32 0 + %2 = getelementptr { i64, i64 }, { i64, i64 }* %0, i64 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 { i64 }, { i64 }* %6, i64 0, i32 0 + store i64 %5, i64* %7 ret void } -define void @Microsoft__Quantum__Testing__QIR__Qop__ctladj(%Array* %__controlQubits__, { %Qubit*, i64 }* %0) { +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 { %Callable*, i64 }, { %Callable*, i64 }* %0, i64 0, i32 1 + %2 = load i64, i64* %1 + %3 = bitcast %Tuple* %arg-tuple to { i64 }* + %4 = getelementptr { i64 }, { i64 }* %3, i64 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 { i64, i64 }, { i64, i64 }* %7, i64 0, i32 0 + %9 = getelementptr { i64, i64 }, { i64, i64 }* %7, i64 0, i32 1 + store i64 %2, i64* %8 + store i64 %5, i64* %9 + %10 = getelementptr { %Callable*, i64 }, { %Callable*, i64 }* %0, i64 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 { %Callable*, i64 }, { %Callable*, i64 }* %0, i64 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 { %Callable*, i64 }, { %Callable*, i64 }* %0, i64 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__qis__x__body(%Qubit*) + +declare void @__quantum__rt__qubit_release_array(%Array*) + +declare %Result* @__quantum__qis__measure__body(%Array*, %Array*) + +define double @Microsoft__Quantum__Intrinsic__ArcTan2__body(double %y, double %x) { +entry: + %0 = call double @__quantum__qis__arctan2__body(double %y, double %x) + ret double %0 +} + +declare double @__quantum__qis__arctan2__body(double, double) + +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) - %1 = getelementptr { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 0, i32 0 - %q = load %Qubit*, %Qubit** %1 - %2 = getelementptr { %Qubit*, i64 }, { %Qubit*, i64 }* %0, i64 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__qis__k__ctl(%Array* %__controlQubits__, %Qubit* %q) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} -then0__1: ; preds = %entry +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) - br label %continue__1 + ret void +} -continue__1: ; preds = %then0__1, %entry +define double @Microsoft__Quantum__Intrinsic__Sqrt__body(double %d) { +entry: + %0 = call double @__quantum__qis__sqrt__body(double %d) + ret double %0 +} + +declare double @__quantum__qis__sqrt__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 void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__x__body(%Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__x__body(%Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__x__ctl(%Array* %__controlQubits__, %Qubit* %qb) call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) ret void } -declare void @__quantum__rt__qubit_release_array(%Array*) +declare void @__quantum__qis__x__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__X__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__x__ctl(%Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +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 %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 +} + +define double @Microsoft__Quantum__Intrinsic__Log__body(double %d) { +entry: + %0 = call double @__quantum__qis__log__body(double %d) + ret double %0 +} + +declare double @__quantum__qis__log__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 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 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 double @Microsoft__Quantum__Math__E__body() { +entry: + ret double 0x4005BF0A8B145769 +} + +define double @Microsoft__Quantum__Math__PI__body() { +entry: + ret double 0x400921FB54442D18 +} + +declare %String* @__quantum__rt__string_create(i32, i8*) + +declare %String* @__quantum__rt__pauli_to_string(i2) + +declare %String* @__quantum__rt__string_concatenate(%String*, %String*) + +declare void @__quantum__rt__string_update_reference_count(%String*, i64) + +declare i1 @__quantum__rt__string_equal(%String*, %String*) -define i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays(i64 %array__count, i64* %array, i64 %index, i64 %val, i1 %dummy) #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 @@ -856,7 +1375,7 @@ copy: ; preds = %entry br label %next next: ; preds = %copy, %entry - %4 = call i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %0, i64 %index, i64 %val, i1 %dummy) + %4 = call i64 @Microsoft__Quantum__Testing__QIR__Test_Arrays__body(%Array* %0, i64 %index, i64 %val, i1 %compilerDecoy) ret i64 %4 } diff --git a/src/QirRuntime/test/QIR-static/qir-test-qubits-results.qs b/src/QirRuntime/test/QIR-static/qir-test-qubits-results.qs index 600ecb7379b..9c4f2e5493f 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-qubits-results.qs +++ b/src/QirRuntime/test/QIR-static/qir-test-qubits-results.qs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. namespace Microsoft.Quantum.Testing.QIR { open Microsoft.Quantum.Intrinsic; diff --git a/src/QirRuntime/test/QIR-static/qir-test-strings.cpp b/src/QirRuntime/test/QIR-static/qir-test-strings.cpp new file mode 100644 index 00000000000..7cbe6c3592e --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-test-strings.cpp @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include + +#include "catch.hpp" + + +extern "C" uint64_t Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body(); // NOLINT + + +TEST_CASE("QIR: Strings", "[qir.Str][qir.Str.PauliToString]") +{ + REQUIRE(0 == Microsoft__Quantum__Testing__QIR__Str__PauliToStringTest__body()); +} + diff --git a/src/QirRuntime/test/QIR-static/qir-test-strings.qs b/src/QirRuntime/test/QIR-static/qir-test-strings.qs new file mode 100644 index 00000000000..6046ce6ab0d --- /dev/null +++ b/src/QirRuntime/test/QIR-static/qir-test-strings.qs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Testing.QIR.Str { + + open Microsoft.Quantum.Intrinsic; + + function PauliToStringTest() : Int { + + if "Pauli value: PauliI" != + $"Pauli value: {PauliI}" { return 1; } // The return value indicates which test case has failed. + if "PauliX" != $"{PauliX}" { return 2; } + if "PauliY" != $"{PauliY}" { return 3; } + if "PauliZ" != $"{PauliZ}" { return 4; } + + return 0; + } + +} +