From d4ff2889b543cadbb9c89b6e02ad3ecb40e97bfe Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Fri, 5 Mar 2021 19:06:48 +0000 Subject: [PATCH 01/31] Refactor cmakelists into common modules --- src/QirRuntime/CMakeLists.txt | 83 +------------------- src/QirRuntime/cmake/qir_cmake_include.cmake | 56 +++++++++++++ src/QirRuntime/cmake/unit_test_include.cmake | 23 ++++++ src/QirRuntime/test/CMakeLists.txt | 2 + 4 files changed, 82 insertions(+), 82 deletions(-) create mode 100644 src/QirRuntime/cmake/qir_cmake_include.cmake create mode 100644 src/QirRuntime/cmake/unit_test_include.cmake diff --git a/src/QirRuntime/CMakeLists.txt b/src/QirRuntime/CMakeLists.txt index 63221cd4d5b..e0d8ecf35d8 100644 --- a/src/QirRuntime/CMakeLists.txt +++ b/src/QirRuntime/CMakeLists.txt @@ -27,89 +27,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") set(public_includes "${PROJECT_SOURCE_DIR}/public") -set(test_includes "${PROJECT_SOURCE_DIR}/externals/catch2" "${PROJECT_SOURCE_DIR}/test") -#=============================================================================== -# testing related -# -include(CTest) -macro(add_unit_test target) - add_test( - NAME ${target} - COMMAND ${target} ~[skip] -o "${target}_results.xml" -r junit - ) - - # set the environment path for loading shared libs the tests are using - if(DEFINED ENV{NATIVE_SIMULATOR}) - set(TEST_DEPS1 $ENV{NATIVE_SIMULATOR}) - else() - set(TEST_DEPS1 "${PROJECT_SOURCE_DIR}/../Simulation/native/build/${CMAKE_BUILD_TYPE}") - endif() - - set(TEST_DEPS2 "${CMAKE_BINARY_DIR}/bin") - set_property(TEST ${target} PROPERTY ENVIRONMENT - "LD_LIBRARY_PATH=${TEST_DEPS1}:${TEST_DEPS2}:${LD_LIBRARY_PATH}" - "PATH=${TEST_DEPS1}\;${TEST_DEPS2}\;${PATH}" - "DYLD_LIBRARY_PATH=${TEST_DEPS1}:${TEST_DEPS2}:${DYLD_LIBRARY_PATH}" - ) -endmacro(add_unit_test) - -#=============================================================================== -# compiling from IR -# -# CMake doesn't support LLVM IR files as sources so we compile them with custom -# commands, which produce UTILITY libs that can only be linked in using abs paths -# (rather than the target name): -# Target "qir_bridge_qis" of type UTILITY may not be linked into another -# target. One may link only to INTERFACE, OBJECT, STATIC or SHARED -# libraries, or to executables with the ENABLE_EXPORTS property set. -# -macro(compile_from_qir source_file target) - set(CLANG_ARGS "-c") - if (CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CLANG_ARGS - "${CLANG_ARGS}" - "-O0" - "-D_DEBUG" - ) - endif() - - set(INFILE - "${CMAKE_CURRENT_SOURCE_DIR}/${source_file}.ll" - ) - set(OBJFILE - "${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj" - ) - - set(OBJFILE_COMPILE "${source_file}-compile") - add_custom_command(OUTPUT ${OBJFILE_COMPILE} - COMMAND ${CMAKE_CXX_COMPILER} - ARGS ${CLANG_ARGS} ${INFILE} "-o" ${OBJFILE} - DEPENDS ${INFILE} - COMMENT "Compiling ${source_file}.ll" - VERBATIM - ) - - add_custom_target(${source_file}_compile DEPENDS ${OBJFILE_COMPILE}) - - if (WIN32) - set(QIR_UTILITY_LIB "${CMAKE_CURRENT_BINARY_DIR}/${source_file}-u.lib" ) - else() - set(QIR_UTILITY_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib${source_file}-u.a") - endif() - - add_custom_command(OUTPUT ${QIR_UTILITY_LIB} - COMMAND ${CMAKE_AR} - ARGS "rc" ${QIR_UTILITY_LIB} ${OBJFILE} - DEPENDS ${source_file}_compile ${INFILE} - COMMENT "Creating a lib from ${source_file}.ll" - VERBATIM - ) - - if (NOT ${target} STREQUAL "") - add_custom_target(${target} DEPENDS ${QIR_UTILITY_LIB}) - endif() -endmacro(compile_from_qir) +include(qir_cmake_include) if (WIN32) set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-rt-u.lib") diff --git a/src/QirRuntime/cmake/qir_cmake_include.cmake b/src/QirRuntime/cmake/qir_cmake_include.cmake new file mode 100644 index 00000000000..a3e820c4074 --- /dev/null +++ b/src/QirRuntime/cmake/qir_cmake_include.cmake @@ -0,0 +1,56 @@ +#=============================================================================== +# compiling from IR +# +# CMake doesn't support LLVM IR files as sources so we compile them with custom +# commands, which produce UTILITY libs that can only be linked in using abs paths +# (rather than the target name): +# Target "qir_bridge_qis" of type UTILITY may not be linked into another +# target. One may link only to INTERFACE, OBJECT, STATIC or SHARED +# libraries, or to executables with the ENABLE_EXPORTS property set. +# +macro(compile_from_qir source_file target) + set(CLANG_ARGS "-c") + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CLANG_ARGS + "${CLANG_ARGS}" + "-O0" + "-D_DEBUG" + ) + endif() + + set(INFILE + "${CMAKE_CURRENT_SOURCE_DIR}/${source_file}.ll" + ) + set(OBJFILE + "${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj" + ) + + set(OBJFILE_COMPILE "${source_file}-compile") + add_custom_command(OUTPUT ${OBJFILE_COMPILE} + COMMAND ${CMAKE_CXX_COMPILER} + ARGS ${CLANG_ARGS} ${INFILE} "-o" ${OBJFILE} + DEPENDS ${INFILE} + COMMENT "Compiling ${source_file}.ll" + VERBATIM + ) + + add_custom_target(${source_file}_compile DEPENDS ${OBJFILE_COMPILE}) + + if (WIN32) + set(QIR_UTILITY_LIB "${CMAKE_CURRENT_BINARY_DIR}/${source_file}-u.lib" ) + else() + set(QIR_UTILITY_LIB "${CMAKE_CURRENT_BINARY_DIR}/lib${source_file}-u.a") + endif() + + add_custom_command(OUTPUT ${QIR_UTILITY_LIB} + COMMAND ${CMAKE_AR} + ARGS "rc" ${QIR_UTILITY_LIB} ${OBJFILE} + DEPENDS ${source_file}_compile ${INFILE} + COMMENT "Creating a lib from ${source_file}.ll" + VERBATIM + ) + + if (NOT ${target} STREQUAL "") + add_custom_target(${target} DEPENDS ${QIR_UTILITY_LIB}) + endif() +endmacro(compile_from_qir) diff --git a/src/QirRuntime/cmake/unit_test_include.cmake b/src/QirRuntime/cmake/unit_test_include.cmake new file mode 100644 index 00000000000..b4ac9de981e --- /dev/null +++ b/src/QirRuntime/cmake/unit_test_include.cmake @@ -0,0 +1,23 @@ +set(test_includes "${PROJECT_SOURCE_DIR}/externals/catch2" "${PROJECT_SOURCE_DIR}/test") + +include(CTest) +macro(add_unit_test target) + add_test( + NAME ${target} + COMMAND ${target} ~[skip] -o "${target}_results.xml" -r junit + ) + + # set the environment path for loading shared libs the tests are using + if(DEFINED ENV{NATIVE_SIMULATOR}) + set(TEST_DEPS1 $ENV{NATIVE_SIMULATOR}) + else() + set(TEST_DEPS1 "${PROJECT_SOURCE_DIR}/../Simulation/native/build/${CMAKE_BUILD_TYPE}") + endif() + + set(TEST_DEPS2 "${CMAKE_BINARY_DIR}/bin") + set_property(TEST ${target} PROPERTY ENVIRONMENT + "LD_LIBRARY_PATH=${TEST_DEPS1}:${TEST_DEPS2}:${LD_LIBRARY_PATH}" + "PATH=${TEST_DEPS1}\;${TEST_DEPS2}\;${PATH}" + "DYLD_LIBRARY_PATH=${TEST_DEPS1}:${TEST_DEPS2}:${DYLD_LIBRARY_PATH}" + ) +endmacro(add_unit_test) diff --git a/src/QirRuntime/test/CMakeLists.txt b/src/QirRuntime/test/CMakeLists.txt index e5541f78589..aaeee4ad5a7 100644 --- a/src/QirRuntime/test/CMakeLists.txt +++ b/src/QirRuntime/test/CMakeLists.txt @@ -1,3 +1,5 @@ +include(unit_test_include) + add_subdirectory(FullstateSimulator) add_subdirectory(QIR-dynamic) add_subdirectory(QIR-static) From a6ad046796e6a5e749b5b6f77aec949c93870b60 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sat, 6 Mar 2021 09:11:22 +0000 Subject: [PATCH 02/31] Split out QSharpCore lib --- src/QirRuntime/CMakeLists.txt | 2 + src/QirRuntime/lib/CMakeLists.txt | 2 +- src/QirRuntime/lib/QIR/CMakeLists.txt | 36 +- src/QirRuntime/lib/QIR/bridge-qis.ll | 248 ------------ src/QirRuntime/lib/QIR/quantum__qis.hpp | 27 -- src/QirRuntime/lib/QSharpCore/.clang-tidy | 1 + src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 52 +++ .../lib/{QIR => QSharpCore}/intrinsics.cpp | 362 +++++++++--------- .../lib/QSharpCore/qsharp-core-qis.ll | 280 ++++++++++++++ .../lib/QSharpCore/qsharp__core__qis.hpp | 63 +++ src/QirRuntime/lib/Simulators/CMakeLists.txt | 1 + .../lib/{qdk/qdk.cpp => Simulators/setup.cpp} | 34 +- src/QirRuntime/lib/qdk/CMakeLists.txt | 28 -- src/QirRuntime/test-qir-runtime.ps1 | 2 +- .../test/FullstateSimulator/CMakeLists.txt | 2 + .../test/QIR-dynamic/CMakeLists.txt | 19 +- .../test/QIR-dynamic/qir-test-random-win.ll | 142 ------- ...-test-random-lnx.ll => qir-test-random.ll} | 284 +++++++------- src/QirRuntime/test/QIR-static/CMakeLists.txt | 2 + src/QirRuntime/test/QIR-tracer/CMakeLists.txt | 2 + src/QirRuntime/test/unittests/CMakeLists.txt | 6 +- .../test/unittests/QirRuntimeTests.cpp | 1 + 22 files changed, 787 insertions(+), 809 deletions(-) create mode 100644 src/QirRuntime/lib/QSharpCore/.clang-tidy create mode 100644 src/QirRuntime/lib/QSharpCore/CMakeLists.txt rename src/QirRuntime/lib/{QIR => QSharpCore}/intrinsics.cpp (96%) create mode 100644 src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll create mode 100644 src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp rename src/QirRuntime/lib/{qdk/qdk.cpp => Simulators/setup.cpp} (97%) delete mode 100644 src/QirRuntime/lib/qdk/CMakeLists.txt delete mode 100644 src/QirRuntime/test/QIR-dynamic/qir-test-random-win.ll rename src/QirRuntime/test/QIR-dynamic/{qir-test-random-lnx.ll => qir-test-random.ll} (97%) diff --git a/src/QirRuntime/CMakeLists.txt b/src/QirRuntime/CMakeLists.txt index e0d8ecf35d8..bc1e94abe98 100644 --- a/src/QirRuntime/CMakeLists.txt +++ b/src/QirRuntime/CMakeLists.txt @@ -33,10 +33,12 @@ include(qir_cmake_include) if (WIN32) set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-rt-u.lib") set(QIR_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-qis-u.lib") + set(QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpCore/qsharp-core-qis-u.lib") set(QIR_BRIDGE_TRACER_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/Tracer/tracer-bridge-u.lib") else() set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/libbridge-rt-u.a") set(QIR_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/libbridge-qis-u.a") + set(QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpCore/libqsharp-core-qis-u.a") set(QIR_BRIDGE_TRACER_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/Tracer/libtracer-bridge-u.a") endif() diff --git a/src/QirRuntime/lib/CMakeLists.txt b/src/QirRuntime/lib/CMakeLists.txt index ad1361d4074..f578ad66163 100644 --- a/src/QirRuntime/lib/CMakeLists.txt +++ b/src/QirRuntime/lib/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(QIR) +add_subdirectory(QSharpCore) add_subdirectory(Simulators) add_subdirectory(Tracer) -add_subdirectory(qdk) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index 16d1634b935..3d538ec9cac 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -15,13 +15,13 @@ compile_from_qir(bridge-rt ${bridge_rt_target}) # create qir-rt-support lib from the C++ sources # set(rt_sup_source_files - "allocationsTracker.cpp" - "arrays.cpp" - "callables.cpp" - "context.cpp" - "delegated.cpp" - "strings.cpp" - "utils.cpp" + allocationsTracker.cpp + arrays.cpp + callables.cpp + context.cpp + delegated.cpp + strings.cpp + utils.cpp ) add_library(qir-rt-support ${rt_sup_source_files}) @@ -50,7 +50,6 @@ compile_from_qir(bridge-qis ${bridge_qis_target}) # set(qis_sup_source_files conditionals.cpp - intrinsics.cpp intrinsicsMath.cpp intrinsicsOut.cpp ) @@ -66,5 +65,26 @@ set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) add_dependencies(qir-qis-support ${bridge_qis_target}) +#=============================================================================== +# Produce the qir dynamic library +# +add_library(qir SHARED) + +target_link_libraries(qir + ${QIR_BRIDGE_UTILITY_LIB} + ${QIR_BRIDGE_QIS_UTILITY_LIB} + ${CMAKE_DL_LIBS} + qir-rt-support-obj + qir-qis-support-obj +) +target_include_directories(qir PUBLIC + ${public_includes} +) + +set_property(TARGET qir PROPERTY POSITION_INDEPENDENT_CODE ON) +install(TARGETS qir + RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" + LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" +) diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index e841bb18dd2..56540c53dc9 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -31,256 +31,8 @@ %struct.QirString = type opaque %PauliId = type i32 -;=============================================================================== -; declarations of the native methods this bridge delegates to -; -declare void @quantum__qis__exp__body(%struct.QirArray*, double, %struct.QirArray*) -declare void @quantum__qis__exp__adj(%struct.QirArray*, double, %struct.QirArray*) -declare void @quantum__qis__exp__ctl(%struct.QirArray*, %struct.QirArray*, double, %struct.QirArray*) -declare void @quantum__qis__exp__ctladj(%struct.QirArray*, %struct.QirArray*, double, %struct.QirArray*) -declare void @quantum__qis__h__body(%class.QUBIT*) -declare void @quantum__qis__h__ctl(%struct.QirArray*, %class.QUBIT*) -declare %class.RESULT* @quantum__qis__measure__body(%struct.QirArray*, %struct.QirArray*) -declare void @quantum__qis__r__body(i32, double, %class.QUBIT*) -declare void @quantum__qis__r__adj(i32, double, %class.QUBIT*) -declare void @quantum__qis__r__ctl(%struct.QirArray*, i32, double, %class.QUBIT*) -declare void @quantum__qis__r__ctladj(%struct.QirArray*, i32, double, %class.QUBIT*) -declare void @quantum__qis__s__body(%class.QUBIT*) -declare void @quantum__qis__s__adj(%class.QUBIT*) -declare void @quantum__qis__s__ctl(%struct.QirArray*, %class.QUBIT*) -declare void @quantum__qis__s__ctladj(%struct.QirArray*, %class.QUBIT*) -declare void @quantum__qis__t__body(%class.QUBIT*) -declare void @quantum__qis__t__adj(%class.QUBIT*) -declare void @quantum__qis__t__ctl(%struct.QirArray*, %class.QUBIT*) -declare void @quantum__qis__t__ctladj(%struct.QirArray*, %class.QUBIT*) -declare void @quantum__qis__x__body(%class.QUBIT*) -declare void @quantum__qis__x__ctl(%struct.QirArray*, %class.QUBIT*) -declare void @quantum__qis__y__body(%class.QUBIT*) -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 -; - -define void @__quantum__qis__exp__body(%Array* %.paulis, double %angle, %Array* %.qubits) { - %paulis = bitcast %Array* %.paulis to %struct.QirArray* - %qubits = bitcast %Array* %.qubits to %struct.QirArray* - call void @quantum__qis__exp__body(%struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) - ret void -} - -define void @__quantum__qis__exp__adj(%Array* %.paulis, double %angle, %Array* %.qubits) { - %paulis = bitcast %Array* %.paulis to %struct.QirArray* - %qubits = bitcast %Array* %.qubits to %struct.QirArray* - call void @quantum__qis__exp__adj(%struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) - ret void -} - -define void @__quantum__qis__exp__ctl(%Array* %.ctls, {%Array*, double, %Array*}* %.args) { - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - - %.ppaulis = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 0 - %.paulis = load %Array*, %Array** %.ppaulis - %paulis = bitcast %Array* %.paulis to %struct.QirArray* - - %.pangle = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 1 - %angle = load double, double* %.pangle - - %.pqubits = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 2 - %.qubits = load %Array*, %Array** %.pqubits - %qubits = bitcast %Array* %.qubits to %struct.QirArray* - - call void @quantum__qis__exp__ctl( - %struct.QirArray* %ctls, %struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) - ret void -} - -define void @__quantum__qis__exp__ctladj(%Array* %.ctls, { %Array*, double, %Array* }* %.args) { - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - - %.ppaulis = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 0 - %.paulis = load %Array*, %Array** %.ppaulis - %paulis = bitcast %Array* %.paulis to %struct.QirArray* - - %.pangle = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 1 - %angle = load double, double* %.pangle - - %.pqubits = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 2 - %.qubits = load %Array*, %Array** %.pqubits - %qubits = bitcast %Array* %.qubits to %struct.QirArray* - - call void @quantum__qis__exp__ctladj( - %struct.QirArray* %ctls, %struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) - ret void -} - -define void @__quantum__qis__h__body(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__h__body(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__h__ctl(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__h__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define %Result* @__quantum__qis__measure__body(%Array* %.paulis, %Array* %.qubits) { - %paulis = bitcast %Array* %.paulis to %struct.QirArray* - %qubits = bitcast %Array* %.qubits to %struct.QirArray* - %r = call %class.RESULT* @quantum__qis__measure__body(%struct.QirArray* %paulis, %struct.QirArray* %qubits) - %.r = bitcast %class.RESULT* %r to %Result* - ret %Result* %.r -} - -define void @__quantum__qis__r__body(%Pauli %.pauli, double %theta, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %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(%Pauli %.pauli, double %theta, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %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, {%Pauli, double, %Qubit*}* %.args) { - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - - %.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 {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 1 - %theta = load double, double* %.ptheta - - %.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, %PauliId %pauli, double %theta, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__r__ctladj(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - - %.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 {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 1 - %theta = load double, double* %.ptheta - - %.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, %PauliId %pauli, double %theta, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__s__body(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__s__body(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__s__adj(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__s__adj(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__s__ctl(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__s__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__s__ctladj(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__s__ctladj(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__t__body(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__t__body(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__t__adj(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__t__adj(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__t__ctl(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__t__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__t__ctladj(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__t__ctladj(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__x__body(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__x__body(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__x__ctl(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__x__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__y__body(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__y__body(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__y__ctl(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__y__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__z__body(%Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - call void @quantum__qis__z__body(%class.QUBIT* %q) - ret void -} - -define void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) { - %q = bitcast %Qubit* %.q to %class.QUBIT* - %ctls = bitcast %Array* %.ctls to %struct.QirArray* - call void @quantum__qis__z__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) - ret void -} - - ;=============================================================================== ; define void @__quantum__qis__message__body(%String* %.str) { diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QIR/quantum__qis.hpp index c7f5a108ea8..0c50cabd171 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis.hpp @@ -33,33 +33,6 @@ namespace Quantum */ extern "C" { - // Q# Gate Set - QIR_SHARED_API void quantum__qis__exp__body(QirArray*, double, QirArray*); // NOLINT - QIR_SHARED_API void quantum__qis__exp__adj(QirArray*, double, QirArray*); // NOLINT - QIR_SHARED_API void quantum__qis__exp__ctl(QirArray*, QirArray*, double, QirArray*); // NOLINT - QIR_SHARED_API void quantum__qis__exp__ctladj(QirArray*, QirArray*, double, QirArray*); // NOLINT - QIR_SHARED_API void quantum__qis__h__body(QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__h__ctl(QirArray*, QUBIT*); // NOLINT - QIR_SHARED_API RESULT* quantum__qis__measure__body(QirArray*, QirArray*); // NOLINT - QIR_SHARED_API void quantum__qis__r__body(PauliId, double, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__r__adj(PauliId, double, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__r__ctl(QirArray*, PauliId, double, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__r__ctladj(QirArray*, PauliId, double, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__s__body(QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__s__adj(QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__s__ctl(QirArray*, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__s__ctladj(QirArray*, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__t__body(QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__t__adj(QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__t__ctl(QirArray*, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__t__ctladj(QirArray*, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__x__body(QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__x__ctl(QirArray*, QUBIT*); // NOLINT - QIR_SHARED_API void quantum__qis__y__body(QUBIT*); // NOLINT - 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 void quantum__qis__message__body(QirString* qstr); // NOLINT // Q# Math: diff --git a/src/QirRuntime/lib/QSharpCore/.clang-tidy b/src/QirRuntime/lib/QSharpCore/.clang-tidy new file mode 100644 index 00000000000..8268b75c21d --- /dev/null +++ b/src/QirRuntime/lib/QSharpCore/.clang-tidy @@ -0,0 +1 @@ +Checks: '-*,bugprone-*' \ No newline at end of file diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt new file mode 100644 index 00000000000..4169cbe2265 --- /dev/null +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -0,0 +1,52 @@ +#+++++++++++++++++++++++++++++++++++++ +# qsharp-core-qis +#+++++++++++++++++++++++++++++++++++++ + +#=============================================================================== +# create a utility lib from qsharp-core-qis.ll +# +set(qsharp_core_qis_target "qsharp_core_qis_target") +compile_from_qir(qsharp-core-qis ${qsharp_core_qis_target}) + +#=============================================================================== +# create qsharp-core-qis-support lib from the C++ sources +# +set(qsharp_core_sup_source_files + intrinsics.cpp +) + +add_library(qsharp-core-qis-support ${qsharp_core_sup_source_files}) + +target_include_directories(qsharp-core-qis-support PUBLIC ${public_includes}) + +# Produce object lib we'll use to create a shared lib (so/dll) later on +add_library(qsharp-core-qis-support-obj OBJECT ${qsharp_core_sup_source_files}) +target_include_directories(qsharp-core-qis-support-obj PUBLIC ${public_includes}) +set_property(TARGET qsharp-core-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) + +add_dependencies(qsharp-core-qis-support ${qsharp_core_qis_target}) + +#=============================================================================== +# Produce the QSharpCore dynamic library +# +add_library(QSharpCore SHARED + $ + $ +) + +target_link_libraries(QSharpCore + ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} + ${CMAKE_DL_LIBS} +) + +target_include_directories(QSharpCore PUBLIC + ${public_includes} +) + +set_property(TARGET QSharpCore PROPERTY POSITION_INDEPENDENT_CODE ON) + +install(TARGETS QSharpCore + RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" + LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" +) + diff --git a/src/QirRuntime/lib/QIR/intrinsics.cpp b/src/QirRuntime/lib/QSharpCore/intrinsics.cpp similarity index 96% rename from src/QirRuntime/lib/QIR/intrinsics.cpp rename to src/QirRuntime/lib/QSharpCore/intrinsics.cpp index 4e20bc4d0b5..ea9bf3a2129 100644 --- a/src/QirRuntime/lib/QIR/intrinsics.cpp +++ b/src/QirRuntime/lib/QSharpCore/intrinsics.cpp @@ -1,182 +1,182 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -/*============================================================================= - QIR assumes a single global execution context. - To support the dispatch over the qir-bridge, the clients must register their - Microsoft::Quantum::ISimulator* first. -=============================================================================*/ -#include -#include - -#include "quantum__qis.hpp" - -#include "QuantumApi_I.hpp" -#include "QirContext.hpp" -#include "QirTypes.hpp" - -// Pauli consts are {i2} in QIR, likely stored as {i8} in arrays, but we are using the standard C++ enum type based on -// {i32} so cannot pass through the buffer and have to allocate a new one instead and copy. -static std::vector ExtractPauliIds(QirArray* paulis) -{ - const long count = paulis->count; - std::vector pauliIds; - pauliIds.reserve(count); - for (long i = 0; i < count; i++) - { - pauliIds.push_back(static_cast(*paulis->GetItemPointer(i))); - } - return pauliIds; -} - -extern "C" -{ - void quantum__qis__exp__body(QirArray* paulis, double angle, QirArray* qubits) - { - assert(paulis->count == qubits->count); - - std::vector pauliIds = ExtractPauliIds(paulis); - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Exp( - paulis->count, reinterpret_cast(pauliIds.data()), reinterpret_cast(qubits->buffer), - angle); - } - - void quantum__qis__exp__adj(QirArray* paulis, double angle, QirArray* qubits) - { - quantum__qis__exp__body(paulis, -angle, qubits); - } - - void quantum__qis__exp__ctl(QirArray* ctls, QirArray* paulis, double angle, QirArray* qubits) - { - assert(paulis->count == qubits->count); - - std::vector pauliIds = ExtractPauliIds(paulis); - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledExp( - ctls->count, reinterpret_cast(ctls->buffer), paulis->count, - reinterpret_cast(pauliIds.data()), reinterpret_cast(qubits->buffer), angle); - } - - void quantum__qis__exp__ctladj(QirArray* ctls, QirArray* paulis, double angle, QirArray* qubits) - { - quantum__qis__exp__ctl(ctls, paulis, -angle, qubits); - } - - void quantum__qis__h__body(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->H(qubit); - } - - void quantum__qis__h__ctl(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledH( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - Result quantum__qis__measure__body(QirArray* paulis, QirArray* qubits) - { - const long count = qubits->count; - assert(count == paulis->count); - - std::vector pauliIds = ExtractPauliIds(paulis); - return Microsoft::Quantum::g_context->simulator->Measure( - count, reinterpret_cast(pauliIds.data()), count, reinterpret_cast(qubits->buffer)); - } - - void quantum__qis__r__body(PauliId axis, double angle, QUBIT* qubit) - { - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->R(axis, qubit, angle); - } - - void quantum__qis__r__adj(PauliId axis, double angle, QUBIT* qubit) - { - quantum__qis__r__body(axis, -angle, qubit); - } - - void quantum__qis__r__ctl(QirArray* ctls, PauliId axis, double angle, QUBIT* qubit) - { - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledR( - ctls->count, reinterpret_cast(ctls->buffer), axis, qubit, angle); - } - - void quantum__qis__r__ctladj(QirArray* ctls, PauliId axis, double angle, QUBIT* qubit) - { - quantum__qis__r__ctl(ctls, axis, -angle, qubit); - } - - void quantum__qis__s__body(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->S(qubit); - } - - void quantum__qis__s__adj(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->AdjointS(qubit); - } - - void quantum__qis__s__ctl(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledS( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - void quantum__qis__s__ctladj(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledAdjointS( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - void quantum__qis__t__body(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->T(qubit); - } - - void quantum__qis__t__adj(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->AdjointT(qubit); - } - - void quantum__qis__t__ctl(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledT( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - void quantum__qis__t__ctladj(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledAdjointT( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - void quantum__qis__x__body(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->X(qubit); - } - - void quantum__qis__x__ctl(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledX( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - void quantum__qis__y__body(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Y(qubit); - } - - void quantum__qis__y__ctl(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledY( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } - - void quantum__qis__z__body(Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Z(qubit); - } - - void quantum__qis__z__ctl(QirArray* ctls, Qubit qubit) - { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledZ( - ctls->count, reinterpret_cast(ctls->buffer), qubit); - } +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/*============================================================================= + QIR assumes a single global execution context. + To support the dispatch over the qir-bridge, the clients must register their + Microsoft::Quantum::ISimulator* first. +=============================================================================*/ +#include +#include + +#include "qsharp__core__qis.hpp" + +#include "QuantumApi_I.hpp" +#include "QirContext.hpp" +#include "QirTypes.hpp" + +// Pauli consts are {i2} in QIR, likely stored as {i8} in arrays, but we are using the standard C++ enum type based on +// {i32} so cannot pass through the buffer and have to allocate a new one instead and copy. +static std::vector ExtractPauliIds(QirArray* paulis) +{ + const long count = paulis->count; + std::vector pauliIds; + pauliIds.reserve(count); + for (long i = 0; i < count; i++) + { + pauliIds.push_back(static_cast(*paulis->GetItemPointer(i))); + } + return pauliIds; +} + +extern "C" +{ + void quantum__qis__exp__body(QirArray* paulis, double angle, QirArray* qubits) + { + assert(paulis->count == qubits->count); + + std::vector pauliIds = ExtractPauliIds(paulis); + return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Exp( + paulis->count, reinterpret_cast(pauliIds.data()), reinterpret_cast(qubits->buffer), + angle); + } + + void quantum__qis__exp__adj(QirArray* paulis, double angle, QirArray* qubits) + { + quantum__qis__exp__body(paulis, -angle, qubits); + } + + void quantum__qis__exp__ctl(QirArray* ctls, QirArray* paulis, double angle, QirArray* qubits) + { + assert(paulis->count == qubits->count); + + std::vector pauliIds = ExtractPauliIds(paulis); + return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledExp( + ctls->count, reinterpret_cast(ctls->buffer), paulis->count, + reinterpret_cast(pauliIds.data()), reinterpret_cast(qubits->buffer), angle); + } + + void quantum__qis__exp__ctladj(QirArray* ctls, QirArray* paulis, double angle, QirArray* qubits) + { + quantum__qis__exp__ctl(ctls, paulis, -angle, qubits); + } + + void quantum__qis__h__body(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->H(qubit); + } + + void quantum__qis__h__ctl(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledH( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + Result quantum__qis__measure__body(QirArray* paulis, QirArray* qubits) + { + const long count = qubits->count; + assert(count == paulis->count); + + std::vector pauliIds = ExtractPauliIds(paulis); + return Microsoft::Quantum::g_context->simulator->Measure( + count, reinterpret_cast(pauliIds.data()), count, reinterpret_cast(qubits->buffer)); + } + + void quantum__qis__r__body(PauliId axis, double angle, QUBIT* qubit) + { + return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->R(axis, qubit, angle); + } + + void quantum__qis__r__adj(PauliId axis, double angle, QUBIT* qubit) + { + quantum__qis__r__body(axis, -angle, qubit); + } + + void quantum__qis__r__ctl(QirArray* ctls, PauliId axis, double angle, QUBIT* qubit) + { + return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledR( + ctls->count, reinterpret_cast(ctls->buffer), axis, qubit, angle); + } + + void quantum__qis__r__ctladj(QirArray* ctls, PauliId axis, double angle, QUBIT* qubit) + { + quantum__qis__r__ctl(ctls, axis, -angle, qubit); + } + + void quantum__qis__s__body(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->S(qubit); + } + + void quantum__qis__s__adj(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->AdjointS(qubit); + } + + void quantum__qis__s__ctl(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledS( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + void quantum__qis__s__ctladj(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledAdjointS( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + void quantum__qis__t__body(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->T(qubit); + } + + void quantum__qis__t__adj(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->AdjointT(qubit); + } + + void quantum__qis__t__ctl(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledT( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + void quantum__qis__t__ctladj(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledAdjointT( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + void quantum__qis__x__body(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->X(qubit); + } + + void quantum__qis__x__ctl(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledX( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + void quantum__qis__y__body(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Y(qubit); + } + + void quantum__qis__y__ctl(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledY( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } + + void quantum__qis__z__body(Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Z(qubit); + } + + void quantum__qis__z__ctl(QirArray* ctls, Qubit qubit) + { + Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledZ( + ctls->count, reinterpret_cast(ctls->buffer), qubit); + } } \ No newline at end of file diff --git a/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll b/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll new file mode 100644 index 00000000000..c7bf2c25ec5 --- /dev/null +++ b/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll @@ -0,0 +1,280 @@ +; Copyright (c) Microsoft Corporation. +; Licensed under the MIT License. + +;======================================================================================================================= +; QIR types +; +%Array = type opaque +%Callable = type opaque +%Qubit = type opaque +%Range = type { i64, i64, i64 } +%Result = type opaque +%String = type opaque +%Pauli = type i2 + +;======================================================================================================================= +; Native types +; NB: there is no overloading at IR level, so a call/invoke will be made even +; if the definition of the function mismatches the declaration of the arguments. +; It means we could declare here the bridge's C-functions using QIR types +; and avoid bitcasts. However, it seems prudent to be more explicit about +; what's going on and declare the true signatures, as generated by Clang. +; +%class.QUBIT = type opaque +%class.RESULT = type opaque +%struct.QirArray = type opaque +%struct.QirCallable = type opaque +%struct.QirRange = type { i64, i64, i64 } +%struct.QirString = type opaque +%PauliId = type i32 + +; The __quantum__qis__* definitions should be automatically generated by QIR, depending on the specific target. +; However, for simulator targets we provide an optional simple bridge that covers commonly used intrinsics. + +;=============================================================================== +; declarations of the native methods this bridge delegates to +; +declare void @quantum__qis__exp__body(%struct.QirArray*, double, %struct.QirArray*) +declare void @quantum__qis__exp__adj(%struct.QirArray*, double, %struct.QirArray*) +declare void @quantum__qis__exp__ctl(%struct.QirArray*, %struct.QirArray*, double, %struct.QirArray*) +declare void @quantum__qis__exp__ctladj(%struct.QirArray*, %struct.QirArray*, double, %struct.QirArray*) +declare void @quantum__qis__h__body(%class.QUBIT*) +declare void @quantum__qis__h__ctl(%struct.QirArray*, %class.QUBIT*) +declare %class.RESULT* @quantum__qis__measure__body(%struct.QirArray*, %struct.QirArray*) +declare void @quantum__qis__r__body(i32, double, %class.QUBIT*) +declare void @quantum__qis__r__adj(i32, double, %class.QUBIT*) +declare void @quantum__qis__r__ctl(%struct.QirArray*, i32, double, %class.QUBIT*) +declare void @quantum__qis__r__ctladj(%struct.QirArray*, i32, double, %class.QUBIT*) +declare void @quantum__qis__s__body(%class.QUBIT*) +declare void @quantum__qis__s__adj(%class.QUBIT*) +declare void @quantum__qis__s__ctl(%struct.QirArray*, %class.QUBIT*) +declare void @quantum__qis__s__ctladj(%struct.QirArray*, %class.QUBIT*) +declare void @quantum__qis__t__body(%class.QUBIT*) +declare void @quantum__qis__t__adj(%class.QUBIT*) +declare void @quantum__qis__t__ctl(%struct.QirArray*, %class.QUBIT*) +declare void @quantum__qis__t__ctladj(%struct.QirArray*, %class.QUBIT*) +declare void @quantum__qis__x__body(%class.QUBIT*) +declare void @quantum__qis__x__ctl(%struct.QirArray*, %class.QUBIT*) +declare void @quantum__qis__y__body(%class.QUBIT*) +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*) + +;=============================================================================== +; quantum.qis namespace implementations +; + +define void @__quantum__qis__exp__body(%Array* %.paulis, double %angle, %Array* %.qubits) { + %paulis = bitcast %Array* %.paulis to %struct.QirArray* + %qubits = bitcast %Array* %.qubits to %struct.QirArray* + call void @quantum__qis__exp__body(%struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) + ret void +} + +define void @__quantum__qis__exp__adj(%Array* %.paulis, double %angle, %Array* %.qubits) { + %paulis = bitcast %Array* %.paulis to %struct.QirArray* + %qubits = bitcast %Array* %.qubits to %struct.QirArray* + call void @quantum__qis__exp__adj(%struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) + ret void +} + +define void @__quantum__qis__exp__ctl(%Array* %.ctls, {%Array*, double, %Array*}* %.args) { + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + + %.ppaulis = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 0 + %.paulis = load %Array*, %Array** %.ppaulis + %paulis = bitcast %Array* %.paulis to %struct.QirArray* + + %.pangle = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 1 + %angle = load double, double* %.pangle + + %.pqubits = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 2 + %.qubits = load %Array*, %Array** %.pqubits + %qubits = bitcast %Array* %.qubits to %struct.QirArray* + + call void @quantum__qis__exp__ctl( + %struct.QirArray* %ctls, %struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) + ret void +} + +define void @__quantum__qis__exp__ctladj(%Array* %.ctls, { %Array*, double, %Array* }* %.args) { + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + + %.ppaulis = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 0 + %.paulis = load %Array*, %Array** %.ppaulis + %paulis = bitcast %Array* %.paulis to %struct.QirArray* + + %.pangle = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 1 + %angle = load double, double* %.pangle + + %.pqubits = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 2 + %.qubits = load %Array*, %Array** %.pqubits + %qubits = bitcast %Array* %.qubits to %struct.QirArray* + + call void @quantum__qis__exp__ctladj( + %struct.QirArray* %ctls, %struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) + ret void +} + +define void @__quantum__qis__h__body(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__h__body(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__h__ctl(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__h__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define %Result* @__quantum__qis__measure__body(%Array* %.paulis, %Array* %.qubits) { + %paulis = bitcast %Array* %.paulis to %struct.QirArray* + %qubits = bitcast %Array* %.qubits to %struct.QirArray* + %r = call %class.RESULT* @quantum__qis__measure__body(%struct.QirArray* %paulis, %struct.QirArray* %qubits) + %.r = bitcast %class.RESULT* %r to %Result* + ret %Result* %.r +} + +define void @__quantum__qis__r__body(%Pauli %.pauli, double %theta, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %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(%Pauli %.pauli, double %theta, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %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, {%Pauli, double, %Qubit*}* %.args) { + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + + %.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 {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 1 + %theta = load double, double* %.ptheta + + %.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, %PauliId %pauli, double %theta, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__r__ctladj(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + + %.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 {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 1 + %theta = load double, double* %.ptheta + + %.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, %PauliId %pauli, double %theta, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__s__body(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__s__body(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__s__adj(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__s__adj(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__s__ctl(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__s__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__s__ctladj(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__s__ctladj(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__t__body(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__t__body(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__t__adj(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__t__adj(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__t__ctl(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__t__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__t__ctladj(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__t__ctladj(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__x__body(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__x__body(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__x__ctl(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__x__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__y__body(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__y__body(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__y__ctl(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__y__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__z__body(%Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + call void @quantum__qis__z__body(%class.QUBIT* %q) + ret void +} + +define void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) { + %q = bitcast %Qubit* %.q to %class.QUBIT* + %ctls = bitcast %Array* %.ctls to %struct.QirArray* + call void @quantum__qis__z__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) + ret void +} + diff --git a/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp b/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp new file mode 100644 index 00000000000..0f99ab34d24 --- /dev/null +++ b/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include + +#include "CoreTypes.hpp" + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#ifdef _WIN32 +#define QIR_SHARED_API __declspec(dllexport) +#else +#define QIR_SHARED_API +#endif + +struct QirArray; +struct QirCallable; +struct QirString; +struct QirBigInt; + +namespace Microsoft +{ +namespace Quantum +{ + struct IQuantumGateSet; +} +} // namespace Microsoft + +/* + Methods from __quantum__qis namespace are specific to the target. When QIR is generated it might limit or extend + the set of intrinsics, supported by the target (known to QIR generator at compile time). This provides the + implementation of the QSharp.Core intrinsics that redirect to IQuantumGateSet. +*/ +extern "C" +{ + // Q# Gate Set + QIR_SHARED_API void quantum__qis__exp__body(QirArray*, double, QirArray*); // NOLINT + QIR_SHARED_API void quantum__qis__exp__adj(QirArray*, double, QirArray*); // NOLINT + QIR_SHARED_API void quantum__qis__exp__ctl(QirArray*, QirArray*, double, QirArray*); // NOLINT + QIR_SHARED_API void quantum__qis__exp__ctladj(QirArray*, QirArray*, double, QirArray*); // NOLINT + QIR_SHARED_API void quantum__qis__h__body(QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__h__ctl(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API RESULT* quantum__qis__measure__body(QirArray*, QirArray*); // NOLINT + QIR_SHARED_API void quantum__qis__r__body(PauliId, double, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__r__adj(PauliId, double, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__r__ctl(QirArray*, PauliId, double, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__r__ctladj(QirArray*, PauliId, double, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__s__body(QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__s__adj(QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__s__ctl(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__s__ctladj(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__t__body(QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__t__adj(QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__t__ctl(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__t__ctladj(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__x__body(QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__x__ctl(QirArray*, QUBIT*); // NOLINT + QIR_SHARED_API void quantum__qis__y__body(QUBIT*); // NOLINT + 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 + +} \ No newline at end of file diff --git a/src/QirRuntime/lib/Simulators/CMakeLists.txt b/src/QirRuntime/lib/Simulators/CMakeLists.txt index 190117a6304..d1a110c7c74 100644 --- a/src/QirRuntime/lib/Simulators/CMakeLists.txt +++ b/src/QirRuntime/lib/Simulators/CMakeLists.txt @@ -2,6 +2,7 @@ set(component_name "simulators") set(source_files "FullstateSimulator.cpp" + "setup.cpp" "ToffoliSimulator.cpp" ) diff --git a/src/QirRuntime/lib/qdk/qdk.cpp b/src/QirRuntime/lib/Simulators/setup.cpp similarity index 97% rename from src/QirRuntime/lib/qdk/qdk.cpp rename to src/QirRuntime/lib/Simulators/setup.cpp index 41d1c13088b..7d5800b596c 100644 --- a/src/QirRuntime/lib/qdk/qdk.cpp +++ b/src/QirRuntime/lib/Simulators/setup.cpp @@ -1,18 +1,18 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "QuantumApi_I.hpp" -#include "SimFactory.hpp" -#include "QirContext.hpp" -#include "QirTypes.hpp" - -#ifdef _WIN32 -#define EXPORTAPI extern "C" __declspec(dllexport) -#else -#define EXPORTAPI extern "C" -#endif -EXPORTAPI void SetupQirToRunOnFullStateSimulator() -{ - // Leak the simulator, because the QIR only creates one and it will exist for the duration of the session - InitializeQirContext(Microsoft::Quantum::CreateFullstateSimulator().release(), false /*trackAllocatedObjects*/); +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "QuantumApi_I.hpp" +#include "SimFactory.hpp" +#include "QirContext.hpp" +#include "QirTypes.hpp" + +#ifdef _WIN32 +#define EXPORTAPI extern "C" __declspec(dllexport) +#else +#define EXPORTAPI extern "C" +#endif +EXPORTAPI void SetupQirToRunOnFullStateSimulator() +{ + // Leak the simulator, because the QIR only creates one and it will exist for the duration of the session + InitializeQirContext(Microsoft::Quantum::CreateFullstateSimulator().release(), false /*trackAllocatedObjects*/); } \ No newline at end of file diff --git a/src/QirRuntime/lib/qdk/CMakeLists.txt b/src/QirRuntime/lib/qdk/CMakeLists.txt deleted file mode 100644 index 45a4709da06..00000000000 --- a/src/QirRuntime/lib/qdk/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -#=============================================================================== -# Produce the qdk dynamic library -# -add_library(qdk SHARED - qdk.cpp - $ - $ - $ -) - -target_link_libraries(qdk - ${QIR_BRIDGE_UTILITY_LIB} - ${QIR_BRIDGE_QIS_UTILITY_LIB} - ${CMAKE_DL_LIBS} -) - -target_include_directories(qdk PUBLIC - ${public_includes} -) - -set_property(TARGET qdk PROPERTY POSITION_INDEPENDENT_CODE ON) - -install(TARGETS qdk - RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" - LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" -) - - diff --git a/src/QirRuntime/test-qir-runtime.ps1 b/src/QirRuntime/test-qir-runtime.ps1 index 70af4018b70..c8cd5ffd121 100644 --- a/src/QirRuntime/test-qir-runtime.ps1 +++ b/src/QirRuntime/test-qir-runtime.ps1 @@ -5,7 +5,7 @@ if ($Env:ENABLE_NATIVE -ne "false") { if ($Env:ENABLE_QIRRUNTIME -eq "true") { Write-Host "##[info]Test QIR Runtime" - Push-Location (Join-Path $PSScriptRoot "build\$Env:BUILD_CONFIGURATION") + Push-Location (Join-Path $PSScriptRoot build $Env:BUILD_CONFIGURATION test) ctest --verbose diff --git a/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt b/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt index 6b790d80390..21fd019a272 100644 --- a/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt +++ b/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt @@ -8,8 +8,10 @@ target_link_libraries(fullstate-simulator-tests PUBLIC ${QIR_UTILITY_LIB} # created by compile_from_qir ${QIR_BRIDGE_UTILITY_LIB} ${QIR_BRIDGE_QIS_UTILITY_LIB} + ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} qir-rt-support qir-qis-support + qsharp-core-qis-support simulators ) diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index 2f0ebd7d3f8..346d5e2f057 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -8,15 +8,9 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") ) endif() -if (WIN32) - set(TEST_FILES - qir-test-random-win - ) -else() - set(TEST_FILES - qir-test-random-lnx - ) -endif() +set(TEST_FILES + qir-test-random +) foreach(file ${TEST_FILES}) compile_from_qir(${file} "") # don't create a target per file @@ -26,8 +20,8 @@ endforeach() add_custom_target(qir_dynamic_test_lib DEPENDS ${QIR_TESTS_LIBS}) #============================================================================== -# This executable target links test code against the dynamic QDK library rather than the explicit -# static QIR/RT libs (qdk will statically link in the bridge via transitivity of target_link_libraries). +# This executable target links test code against the dynamic QIR and QSharpCore libraries rather than the explicit +# static QIR/RT libs (qir will statically link in the bridge via transitivity of target_link_libraries). # add_executable(qir-dynamic-tests qir-driver.cpp @@ -35,7 +29,8 @@ add_executable(qir-dynamic-tests target_link_libraries(qir-dynamic-tests PUBLIC ${QIR_TESTS_LIBS} - qdk + qir + QSharpCore ) target_include_directories(qir-dynamic-tests PUBLIC diff --git a/src/QirRuntime/test/QIR-dynamic/qir-test-random-win.ll b/src/QirRuntime/test/QIR-dynamic/qir-test-random-win.ll deleted file mode 100644 index d662a2ace52..00000000000 --- a/src/QirRuntime/test/QIR-dynamic/qir-test-random-win.ll +++ /dev/null @@ -1,142 +0,0 @@ - -%Result = type opaque -%Range = type { i64, i64, i64 } -%Qubit = type opaque -%Array = type opaque - -@ResultZero = external dllimport global %Result* -@ResultOne = external dllimport 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__QuantumRandomNumberGenerator = alias i64 (), i64 ()* @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body - -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 void @__quantum__rt__array_update_alias_count(%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__H__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__h__body(%Qubit* %qb) - ret void -} - -declare void @__quantum__qis__h__body(%Qubit*) - -define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__h__body(%Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -declare void @__quantum__qis__h__ctl(%Array*, %Qubit*) - -define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -define i64 @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body() #0 { -entry: - %randomNumber = alloca i64 - store i64 0, i64* %randomNumber - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %i = phi i64 [ 1, %entry ], [ %8, %exiting__1 ] - %0 = icmp sle i64 %i, 64 - br i1 %0, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %q = call %Qubit* @__quantum__rt__qubit_allocate() - call void @__quantum__qis__h__body(%Qubit* %q) - %1 = load i64, i64* %randomNumber - %2 = shl i64 %1, 1 - store i64 %2, i64* %randomNumber - %3 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) - %4 = load %Result*, %Result** @ResultOne - %5 = call i1 @__quantum__rt__result_equal(%Result* %3, %Result* %4) - br i1 %5, label %then0__1, label %continue__1 - -then0__1: ; preds = %body__1 - %6 = load i64, i64* %randomNumber - %7 = add i64 %6, 1 - store i64 %7, i64* %randomNumber - br label %continue__1 - -continue__1: ; preds = %then0__1, %body__1 - call void @__quantum__rt__qubit_release(%Qubit* %q) - call void @__quantum__rt__result_update_reference_count(%Result* %3, i64 -1) - br label %exiting__1 - -exiting__1: ; preds = %continue__1 - %8 = add i64 %i, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - %9 = load i64, i64* %randomNumber - ret i64 %9 -} - -declare %Qubit* @__quantum__rt__qubit_allocate() - -declare %Array* @__quantum__rt__qubit_allocate_array(i64) - -declare i1 @__quantum__rt__result_equal(%Result*, %Result*) - -declare void @__quantum__rt__qubit_release(%Qubit*) - -declare void @__quantum__rt__result_update_reference_count(%Result*, i64) - -attributes #0 = { "EntryPoint" } diff --git a/src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll b/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll similarity index 97% rename from src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll rename to src/QirRuntime/test/QIR-dynamic/qir-test-random.ll index a3edd062c11..cccc97ec31d 100644 --- a/src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll +++ b/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll @@ -1,142 +1,142 @@ - -%Result = type opaque -%Range = type { i64, i64, i64 } -%Qubit = 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__QuantumRandomNumberGenerator = alias i64 (), i64 ()* @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body - -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 void @__quantum__rt__array_update_alias_count(%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__H__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__h__body(%Qubit* %qb) - ret void -} - -declare void @__quantum__qis__h__body(%Qubit*) - -define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__h__body(%Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -declare void @__quantum__qis__h__ctl(%Array*, %Qubit*) - -define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -define i64 @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body() #0 { -entry: - %randomNumber = alloca i64 - store i64 0, i64* %randomNumber - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %i = phi i64 [ 1, %entry ], [ %8, %exiting__1 ] - %0 = icmp sle i64 %i, 64 - br i1 %0, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %q = call %Qubit* @__quantum__rt__qubit_allocate() - call void @__quantum__qis__h__body(%Qubit* %q) - %1 = load i64, i64* %randomNumber - %2 = shl i64 %1, 1 - store i64 %2, i64* %randomNumber - %3 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) - %4 = load %Result*, %Result** @ResultOne - %5 = call i1 @__quantum__rt__result_equal(%Result* %3, %Result* %4) - br i1 %5, label %then0__1, label %continue__1 - -then0__1: ; preds = %body__1 - %6 = load i64, i64* %randomNumber - %7 = add i64 %6, 1 - store i64 %7, i64* %randomNumber - br label %continue__1 - -continue__1: ; preds = %then0__1, %body__1 - call void @__quantum__rt__qubit_release(%Qubit* %q) - call void @__quantum__rt__result_update_reference_count(%Result* %3, i64 -1) - br label %exiting__1 - -exiting__1: ; preds = %continue__1 - %8 = add i64 %i, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - %9 = load i64, i64* %randomNumber - ret i64 %9 -} - -declare %Qubit* @__quantum__rt__qubit_allocate() - -declare %Array* @__quantum__rt__qubit_allocate_array(i64) - -declare i1 @__quantum__rt__result_equal(%Result*, %Result*) - -declare void @__quantum__rt__qubit_release(%Qubit*) - -declare void @__quantum__rt__result_update_reference_count(%Result*, i64) - -attributes #0 = { "EntryPoint" } + +%Result = type opaque +%Range = type { i64, i64, i64 } +%Qubit = 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__QuantumRandomNumberGenerator = alias i64 (), i64 ()* @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body + +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 void @__quantum__rt__array_update_alias_count(%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__H__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__h__body(%Qubit* %qb) + ret void +} + +declare void @__quantum__qis__h__body(%Qubit*) + +define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__h__body(%Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +declare void @__quantum__qis__h__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define i64 @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body() #0 { +entry: + %randomNumber = alloca i64 + store i64 0, i64* %randomNumber + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 1, %entry ], [ %8, %exiting__1 ] + %0 = icmp sle i64 %i, 64 + br i1 %0, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %q = call %Qubit* @__quantum__rt__qubit_allocate() + call void @__quantum__qis__h__body(%Qubit* %q) + %1 = load i64, i64* %randomNumber + %2 = shl i64 %1, 1 + store i64 %2, i64* %randomNumber + %3 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) + %4 = load %Result*, %Result** @ResultOne + %5 = call i1 @__quantum__rt__result_equal(%Result* %3, %Result* %4) + br i1 %5, label %then0__1, label %continue__1 + +then0__1: ; preds = %body__1 + %6 = load i64, i64* %randomNumber + %7 = add i64 %6, 1 + store i64 %7, i64* %randomNumber + br label %continue__1 + +continue__1: ; preds = %then0__1, %body__1 + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__result_update_reference_count(%Result* %3, i64 -1) + br label %exiting__1 + +exiting__1: ; preds = %continue__1 + %8 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + %9 = load i64, i64* %randomNumber + ret i64 %9 +} + +declare %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare i1 @__quantum__rt__result_equal(%Result*, %Result*) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +attributes #0 = { "EntryPoint" } diff --git a/src/QirRuntime/test/QIR-static/CMakeLists.txt b/src/QirRuntime/test/QIR-static/CMakeLists.txt index f82e0b7a928..a0dc155fe43 100644 --- a/src/QirRuntime/test/QIR-static/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-static/CMakeLists.txt @@ -28,8 +28,10 @@ target_link_libraries(qir-static-tests PUBLIC ${QIR_TESTS_LIBS} ${QIR_BRIDGE_UTILITY_LIB} ${QIR_BRIDGE_QIS_UTILITY_LIB} + ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} qir-rt-support qir-qis-support + qsharp-core-qis-support simulators ) diff --git a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt index 8f1835140a9..5cf37e8505e 100644 --- a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt @@ -14,9 +14,11 @@ target_link_libraries(qir-tracer-tests PUBLIC ${QIR_BRIDGE_UTILITY_LIB} ${QIR_BRIDGE_TRACER_UTILITY_LIB} ${QIR_BRIDGE_QIS_UTILITY_LIB} + ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} tracer qir-rt-support qir-qis-support + qsharp-core-qis-support ) target_include_directories(qir-tracer-tests PUBLIC diff --git a/src/QirRuntime/test/unittests/CMakeLists.txt b/src/QirRuntime/test/unittests/CMakeLists.txt index 22b2bc2802f..6ee69ff4378 100644 --- a/src/QirRuntime/test/unittests/CMakeLists.txt +++ b/src/QirRuntime/test/unittests/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable(qir-runtime-unittests target_link_libraries(qir-runtime-unittests PUBLIC qir-rt-support qir-qis-support + qsharp-core-qis-support simulators tracer ) @@ -18,8 +19,9 @@ target_link_libraries(qir-runtime-unittests PUBLIC target_include_directories(qir-runtime-unittests PUBLIC "${test_includes}" ${public_includes} - "${PROJECT_SOURCE_DIR}/lib/QIR" - "${PROJECT_SOURCE_DIR}/lib/Tracer" + "${PROJECT_SOURCE_DIR}/lib/QIR" + "${PROJECT_SOURCE_DIR}/lib/QSharpCore" + "${PROJECT_SOURCE_DIR}/lib/Tracer" ) install(TARGETS qir-runtime-unittests RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin") add_unit_test(qir-runtime-unittests) diff --git a/src/QirRuntime/test/unittests/QirRuntimeTests.cpp b/src/QirRuntime/test/unittests/QirRuntimeTests.cpp index 2b0037aa4b5..b52554ad898 100644 --- a/src/QirRuntime/test/unittests/QirRuntimeTests.cpp +++ b/src/QirRuntime/test/unittests/QirRuntimeTests.cpp @@ -11,6 +11,7 @@ #include "QirTypes.hpp" #include "quantum__qis.hpp" +#include "qsharp__core__qis.hpp" #include "quantum__rt.hpp" #include "BitStates.hpp" From 072c41d9ff14213024543544ba43ed2fa125feec Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 05:03:52 +0000 Subject: [PATCH 03/31] Create full dynamic libs, including tracer --- src/QirRuntime/build-qir-runtime.ps1 | 1 + src/QirRuntime/cmake/qir_cmake_include.cmake | 12 +++++++ src/QirRuntime/lib/QIR/CMakeLists.txt | 13 +++----- src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 14 +++----- src/QirRuntime/lib/Tracer/CMakeLists.txt | 33 ++++++++++++++++--- .../test/QIR-dynamic/CMakeLists.txt | 10 ------ src/QirRuntime/test/QIR-tracer/CMakeLists.txt | 10 ++---- 7 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/QirRuntime/build-qir-runtime.ps1 b/src/QirRuntime/build-qir-runtime.ps1 index dfa07616fc1..a0b3a5e379b 100644 --- a/src/QirRuntime/build-qir-runtime.ps1 +++ b/src/QirRuntime/build-qir-runtime.ps1 @@ -2,6 +2,7 @@ # Licensed under the MIT License. if ($Env:ENABLE_QIRRUNTIME -eq "true") { + & (Join-Path $PSScriptRoot .. .. build set-env.ps1) Write-Host "##[info]Compile Q# Projects into QIR" $qirStaticPath = Join-Path $PSScriptRoot test QIR-static qsharp dotnet build $qirStaticPath -c $Env:BUILD_CONFIGURATION -v $Env:BUILD_VERBOSITY diff --git a/src/QirRuntime/cmake/qir_cmake_include.cmake b/src/QirRuntime/cmake/qir_cmake_include.cmake index a3e820c4074..ba3e78eb7f9 100644 --- a/src/QirRuntime/cmake/qir_cmake_include.cmake +++ b/src/QirRuntime/cmake/qir_cmake_include.cmake @@ -54,3 +54,15 @@ macro(compile_from_qir source_file target) add_custom_target(${target} DEPENDS ${QIR_UTILITY_LIB}) endif() endmacro(compile_from_qir) + +macro(target_source_from_qir_obj target_name source_file) + target_sources(${target_name} PUBLIC + "${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj" + ) + SET_SOURCE_FILES_PROPERTIES( + "${source_file}.obj" + PROPERTIES + EXTERNAL_OBJECT true + GENERATED true + ) +endmacro() \ No newline at end of file diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index 3d538ec9cac..822c40117ab 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -25,16 +25,15 @@ set(rt_sup_source_files ) add_library(qir-rt-support ${rt_sup_source_files}) - target_include_directories(qir-rt-support PUBLIC ${public_includes}) +add_dependencies(qir-rt-support ${bridge_rt_target}) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qir-rt-support-obj OBJECT ${rt_sup_source_files}) +target_source_from_qir_obj(qir-rt-support-obj bridge-rt) target_include_directories(qir-rt-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-rt-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -add_dependencies(qir-rt-support ${bridge_rt_target}) - #+++++++++++++++++++++++++++++++++++++ # qir-qis #+++++++++++++++++++++++++++++++++++++ @@ -55,24 +54,21 @@ set(qis_sup_source_files ) add_library(qir-qis-support ${qis_sup_source_files}) - target_include_directories(qir-qis-support PUBLIC ${public_includes}) +add_dependencies(qir-qis-support ${bridge_qis_target}) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qir-qis-support-obj OBJECT ${qis_sup_source_files}) +target_source_from_qir_obj(qir-qis-support-obj bridge-qis) target_include_directories(qir-qis-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -add_dependencies(qir-qis-support ${bridge_qis_target}) - #=============================================================================== # Produce the qir dynamic library # add_library(qir SHARED) target_link_libraries(qir - ${QIR_BRIDGE_UTILITY_LIB} - ${QIR_BRIDGE_QIS_UTILITY_LIB} ${CMAKE_DL_LIBS} qir-rt-support-obj qir-qis-support-obj @@ -85,6 +81,5 @@ target_include_directories(qir PUBLIC set_property(TARGET qir PROPERTY POSITION_INDEPENDENT_CODE ON) install(TARGETS qir - RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index 4169cbe2265..639a974162a 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -16,27 +16,24 @@ set(qsharp_core_sup_source_files ) add_library(qsharp-core-qis-support ${qsharp_core_sup_source_files}) - target_include_directories(qsharp-core-qis-support PUBLIC ${public_includes}) +add_dependencies(qsharp-core-qis-support ${qsharp_core_qis_target}) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qsharp-core-qis-support-obj OBJECT ${qsharp_core_sup_source_files}) +target_source_from_qir_obj(qsharp-core-qis-support-obj qsharp-core-qis) target_include_directories(qsharp-core-qis-support-obj PUBLIC ${public_includes}) set_property(TARGET qsharp-core-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -add_dependencies(qsharp-core-qis-support ${qsharp_core_qis_target}) - #=============================================================================== # Produce the QSharpCore dynamic library # -add_library(QSharpCore SHARED - $ - $ -) +add_library(QSharpCore SHARED) target_link_libraries(QSharpCore - ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} ${CMAKE_DL_LIBS} + qsharp-core-qis-support-obj + simulators-obj ) target_include_directories(QSharpCore PUBLIC @@ -46,7 +43,6 @@ target_include_directories(QSharpCore PUBLIC set_property(TARGET QSharpCore PROPERTY POSITION_INDEPENDENT_CODE ON) install(TARGETS QSharpCore - RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/lib/Tracer/CMakeLists.txt b/src/QirRuntime/lib/Tracer/CMakeLists.txt index 78b5adf145b..db524d1482c 100644 --- a/src/QirRuntime/lib/Tracer/CMakeLists.txt +++ b/src/QirRuntime/lib/Tracer/CMakeLists.txt @@ -2,8 +2,6 @@ compile_from_qir(tracer-bridge tracer-bridge) # build the native part of the tracer -set(component_name "tracer") - set(source_files "tracer-qis.cpp" "tracer.cpp" @@ -14,7 +12,32 @@ set(includes "${PROJECT_SOURCE_DIR}/lib/QIR" ) -add_library(${component_name} STATIC ${source_files}) -target_include_directories(${component_name} PUBLIC ${includes}) +add_library(tracer STATIC ${source_files}) +target_include_directories(tracer PUBLIC ${includes}) +add_dependencies(tracer tracer-bridge) + +# Produce object lib we'll use to create a shared lib (so/dll) later on +add_library(tracer-obj OBJECT ${source_files}) +target_source_from_qir_obj(tracer-obj tracer-bridge) +target_include_directories(tracer-obj PUBLIC ${includes}) +set_property(TARGET tracer-obj PROPERTY POSITION_INDEPENDENT_CODE ON) + +#=============================================================================== +# Produce the qirtracer dynamic library +# +add_library(qirtracer SHARED) + +target_link_libraries(qirtracer + ${CMAKE_DL_LIBS} + tracer-obj +) -add_dependencies(${component_name} tracer-bridge) +target_include_directories(qirtracer PUBLIC + ${includes} +) + +set_property(TARGET qirtracer PROPERTY POSITION_INDEPENDENT_CODE ON) + +install(TARGETS qirtracer + LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" +) diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index 346d5e2f057..78b0435e46a 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -1,13 +1,3 @@ -# compile test ll files into a library, have to use custom commands for this -set(CLANG_ARGS "-c") -if (CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CLANG_ARGS - "${CLANG_ARGS}" - "-O0" - "-D_DEBUG" - ) -endif() - set(TEST_FILES qir-test-random ) diff --git a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt index 5cf37e8505e..348db4e9206 100644 --- a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt @@ -11,14 +11,8 @@ add_executable(qir-tracer-tests target_link_libraries(qir-tracer-tests PUBLIC ${QIR_UTILITY_LIB} # set by compile_from_qir - ${QIR_BRIDGE_UTILITY_LIB} - ${QIR_BRIDGE_TRACER_UTILITY_LIB} - ${QIR_BRIDGE_QIS_UTILITY_LIB} - ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} - tracer - qir-rt-support - qir-qis-support - qsharp-core-qis-support + qir + qirtracer ) target_include_directories(qir-tracer-tests PUBLIC From 12ec703b39d362d0b4215790152c43b3451ac6e3 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 05:39:57 +0000 Subject: [PATCH 04/31] Produce QIR dll pipeline artifacts --- src/QirRuntime/build-qir-runtime.ps1 | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/QirRuntime/build-qir-runtime.ps1 b/src/QirRuntime/build-qir-runtime.ps1 index a0b3a5e379b..010c6d04a3b 100644 --- a/src/QirRuntime/build-qir-runtime.ps1 +++ b/src/QirRuntime/build-qir-runtime.ps1 @@ -53,17 +53,34 @@ if ($Env:ENABLE_QIRRUNTIME -eq "true") { Push-Location $qirRuntimeBuildFolder cmake -G Ninja $clangTidy -D CMAKE_BUILD_TYPE="$Env:BUILD_CONFIGURATION" ../.. + if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to generate QIR Runtime." + } cmake --build . --target install + if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to build QIR Runtime." + } + + $os = "win32" + $pattern = "*.dll" + if ($IsMacOS) { + $os = "osx" + $pattern = "*.dylib" + } elseif ($IsLinux) { + $os = "linux" + $pattern = "*.so" + } + $osQirDropFolder = Join-Path $Env:DROPS_DIR QIR $os + if (!(Test-Path $osQirDropFolder)) { + New-Item -Path $osQirDropFolder -ItemType "directory" + } + Copy-Item (Join-Path . bin $pattern) $osQirDropFolder Pop-Location $env:CC = $oldCC $env:CXX = $oldCXX $env:RC = $oldRC - - if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to build QIR Runtime." - } } else { Write-Host "To enable build of QIR Runtime set ENABLE_QIRRUNTIME environment variable to 'true'" } From 079f87e085a73fe83ed8ddeee34dd16dd08a325a Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 05:54:10 +0000 Subject: [PATCH 05/31] Fix cmake existence check for generated obj --- src/QirRuntime/cmake/qir_cmake_include.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/QirRuntime/cmake/qir_cmake_include.cmake b/src/QirRuntime/cmake/qir_cmake_include.cmake index ba3e78eb7f9..71212e8d699 100644 --- a/src/QirRuntime/cmake/qir_cmake_include.cmake +++ b/src/QirRuntime/cmake/qir_cmake_include.cmake @@ -56,13 +56,13 @@ macro(compile_from_qir source_file target) endmacro(compile_from_qir) macro(target_source_from_qir_obj target_name source_file) - target_sources(${target_name} PUBLIC - "${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj" - ) SET_SOURCE_FILES_PROPERTIES( "${source_file}.obj" PROPERTIES EXTERNAL_OBJECT true GENERATED true ) + target_sources(${target_name} PUBLIC + "${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj" + ) endmacro() \ No newline at end of file From 841552902f6490e6c7a1e6c838ac536e1b862151 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 09:00:34 +0000 Subject: [PATCH 06/31] Fix dynamic lib linking in tests --- src/QirRuntime/cmake/qir_cmake_include.cmake | 4 ++-- src/QirRuntime/test/QIR-dynamic/CMakeLists.txt | 6 ++++-- src/QirRuntime/test/QIR-tracer/CMakeLists.txt | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/QirRuntime/cmake/qir_cmake_include.cmake b/src/QirRuntime/cmake/qir_cmake_include.cmake index 71212e8d699..7328a745ee0 100644 --- a/src/QirRuntime/cmake/qir_cmake_include.cmake +++ b/src/QirRuntime/cmake/qir_cmake_include.cmake @@ -30,6 +30,7 @@ macro(compile_from_qir source_file target) COMMAND ${CMAKE_CXX_COMPILER} ARGS ${CLANG_ARGS} ${INFILE} "-o" ${OBJFILE} DEPENDS ${INFILE} + BYPRODUCTS ${OBJFILE} COMMENT "Compiling ${source_file}.ll" VERBATIM ) @@ -56,11 +57,10 @@ macro(compile_from_qir source_file target) endmacro(compile_from_qir) macro(target_source_from_qir_obj target_name source_file) - SET_SOURCE_FILES_PROPERTIES( + set_source_files_properties( "${source_file}.obj" PROPERTIES EXTERNAL_OBJECT true - GENERATED true ) target_sources(${target_name} PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/${source_file}.obj" diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index 78b0435e46a..f46af9d6272 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -19,8 +19,10 @@ add_executable(qir-dynamic-tests target_link_libraries(qir-dynamic-tests PUBLIC ${QIR_TESTS_LIBS} - qir - QSharpCore + "-L${CMAKE_BINARY_DIR}/lib/QIR" + -lqir + "-L${CMAKE_BINARY_DIR}/lib/QSharpCore" + -lQSharpCore ) target_include_directories(qir-dynamic-tests PUBLIC diff --git a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt index 348db4e9206..0998b416e7c 100644 --- a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt @@ -11,8 +11,10 @@ add_executable(qir-tracer-tests target_link_libraries(qir-tracer-tests PUBLIC ${QIR_UTILITY_LIB} # set by compile_from_qir - qir - qirtracer + "-L${CMAKE_BINARY_DIR}/lib/QIR" + -lqir + "-L${CMAKE_BINARY_DIR}/lib/Tracer" + -lqirtracer ) target_include_directories(qir-tracer-tests PUBLIC From f473cc43ef2d21a00913aa4aafb4ff7b65c9a5e0 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 09:31:03 +0000 Subject: [PATCH 07/31] Use dynamic dependency for non-test libs too --- src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 2 ++ src/QirRuntime/lib/Tracer/CMakeLists.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index 639a974162a..2fd4b1981d4 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -34,6 +34,8 @@ target_link_libraries(QSharpCore ${CMAKE_DL_LIBS} qsharp-core-qis-support-obj simulators-obj + "-L${CMAKE_BINARY_DIR}/lib/QIR" + -lqir ) target_include_directories(QSharpCore PUBLIC diff --git a/src/QirRuntime/lib/Tracer/CMakeLists.txt b/src/QirRuntime/lib/Tracer/CMakeLists.txt index db524d1482c..40388c317f3 100644 --- a/src/QirRuntime/lib/Tracer/CMakeLists.txt +++ b/src/QirRuntime/lib/Tracer/CMakeLists.txt @@ -30,6 +30,8 @@ add_library(qirtracer SHARED) target_link_libraries(qirtracer ${CMAKE_DL_LIBS} tracer-obj + "-L${CMAKE_BINARY_DIR}/lib/QIR" + -lqir ) target_include_directories(qirtracer PUBLIC From ab5f85970579311eca4126d90db091dbd83d4b60 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 09:35:14 +0000 Subject: [PATCH 08/31] Clean up simulators CMakeLists --- src/QirRuntime/lib/Simulators/CMakeLists.txt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/QirRuntime/lib/Simulators/CMakeLists.txt b/src/QirRuntime/lib/Simulators/CMakeLists.txt index d1a110c7c74..f2faa58b05f 100644 --- a/src/QirRuntime/lib/Simulators/CMakeLists.txt +++ b/src/QirRuntime/lib/Simulators/CMakeLists.txt @@ -1,5 +1,3 @@ -set(component_name "simulators") - set(source_files "FullstateSimulator.cpp" "setup.cpp" @@ -14,14 +12,13 @@ set(includes #=============================================================================== # Produce static lib for users to link directly to -add_library(${component_name} STATIC ${source_files}) -target_include_directories(${component_name} PUBLIC ${includes}) -target_link_libraries(${component_name} ${CMAKE_DL_LIBS}) +add_library(simulators STATIC ${source_files}) +target_include_directories(simulators PUBLIC ${includes}) +target_link_libraries(simulators ${CMAKE_DL_LIBS}) #=============================================================================== # Produce object lib we'll use to create a shared lib (so/dll) later on -set(component_name_obj "${component_name}-obj") -add_library(${component_name_obj} OBJECT ${source_files}) -target_include_directories(${component_name_obj} PUBLIC ${includes}) -set_property(TARGET ${component_name_obj} PROPERTY POSITION_INDEPENDENT_CODE ON) +add_library(simulators-obj OBJECT ${source_files}) +target_include_directories(simulators-obj PUBLIC ${includes}) +set_property(TARGET simulators-obj PROPERTY POSITION_INDEPENDENT_CODE ON) From 5be4f015060157747953e19b66f720c6e1aa234d Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 21:04:15 +0000 Subject: [PATCH 09/31] Expand use of dllexport to support Windows --- src/QirRuntime/lib/QIR/CMakeLists.txt | 2 ++ src/QirRuntime/lib/QIR/context.cpp | 6 ------ src/QirRuntime/lib/QIR/quantum__qis.hpp | 6 ------ src/QirRuntime/lib/QIR/quantum__qis_internal.hpp | 6 ------ src/QirRuntime/lib/QIR/quantum__rt.hpp | 6 ------ src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 1 + src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp | 6 ------ src/QirRuntime/public/BitStates.hpp | 4 +++- src/QirRuntime/public/CoreTypes.hpp | 10 ++++++++++ src/QirRuntime/public/QirContext.hpp | 6 +++--- src/QirRuntime/public/QirTypes.hpp | 12 +++++++----- src/QirRuntime/public/QuantumApi_I.hpp | 6 +++--- src/QirRuntime/public/SimFactory.hpp | 4 ++-- src/QirRuntime/public/TracerTypes.hpp | 6 ++++-- 14 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index 822c40117ab..51009c0f4d7 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -33,6 +33,7 @@ add_library(qir-rt-support-obj OBJECT ${rt_sup_source_files}) target_source_from_qir_obj(qir-rt-support-obj bridge-rt) target_include_directories(qir-rt-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-rt-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) +target_compile_definitions(qir-rt-support-obj PUBLIC EXPORT_QIR_API) #+++++++++++++++++++++++++++++++++++++ # qir-qis @@ -62,6 +63,7 @@ add_library(qir-qis-support-obj OBJECT ${qis_sup_source_files}) target_source_from_qir_obj(qir-qis-support-obj bridge-qis) target_include_directories(qir-qis-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) +target_compile_definitions(qir-qis-support-obj PUBLIC EXPORT_QIR_API) #=============================================================================== # Produce the qir dynamic library diff --git a/src/QirRuntime/lib/QIR/context.cpp b/src/QirRuntime/lib/QIR/context.cpp index 11c7fcdcc38..7e10e02eab3 100644 --- a/src/QirRuntime/lib/QIR/context.cpp +++ b/src/QirRuntime/lib/QIR/context.cpp @@ -9,12 +9,6 @@ #include "QuantumApi_I.hpp" #include "allocationsTracker.hpp" -#ifdef _WIN32 -#define QIR_SHARED_API __declspec(dllexport) -#else -#define QIR_SHARED_API -#endif - // These two globals are used in QIR _directly_ so have to define them outside of the context. extern "C" QIR_SHARED_API Result ResultOne = nullptr; extern "C" QIR_SHARED_API Result ResultZero = nullptr; diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QIR/quantum__qis.hpp index 0c50cabd171..961d07fd2e8 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis.hpp @@ -7,12 +7,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#ifdef _WIN32 -#define QIR_SHARED_API __declspec(dllexport) -#else -#define QIR_SHARED_API -#endif - struct QirArray; struct QirCallable; struct QirString; diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp index 52335f32027..673b41d28e3 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp +++ b/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp @@ -6,12 +6,6 @@ // 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 - // For test purposes only: namespace Quantum // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. { diff --git a/src/QirRuntime/lib/QIR/quantum__rt.hpp b/src/QirRuntime/lib/QIR/quantum__rt.hpp index de3c64876a3..4cb5aae9163 100644 --- a/src/QirRuntime/lib/QIR/quantum__rt.hpp +++ b/src/QirRuntime/lib/QIR/quantum__rt.hpp @@ -14,12 +14,6 @@ struct QirCallable; struct QirString; struct QirBigInt; -#ifdef _WIN32 -#define QIR_SHARED_API __declspec(dllexport) -#else -#define QIR_SHARED_API -#endif - extern "C" { struct QirRange diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index 2fd4b1981d4..56d05dee099 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -24,6 +24,7 @@ add_library(qsharp-core-qis-support-obj OBJECT ${qsharp_core_sup_source_files}) target_source_from_qir_obj(qsharp-core-qis-support-obj qsharp-core-qis) target_include_directories(qsharp-core-qis-support-obj PUBLIC ${public_includes}) set_property(TARGET qsharp-core-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) +target_compile_definitions(qsharp-core-qis-support-obj PUBLIC EXPORT_QIR_API) #=============================================================================== # Produce the QSharpCore dynamic library diff --git a/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp b/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp index 0f99ab34d24..fa8c3cc120e 100644 --- a/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp +++ b/src/QirRuntime/lib/QSharpCore/qsharp__core__qis.hpp @@ -7,12 +7,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#ifdef _WIN32 -#define QIR_SHARED_API __declspec(dllexport) -#else -#define QIR_SHARED_API -#endif - struct QirArray; struct QirCallable; struct QirString; diff --git a/src/QirRuntime/public/BitStates.hpp b/src/QirRuntime/public/BitStates.hpp index 8888f35c85c..f95d0ce6719 100644 --- a/src/QirRuntime/public/BitStates.hpp +++ b/src/QirRuntime/public/BitStates.hpp @@ -3,6 +3,8 @@ #include #include +#include "CoreTypes.hpp" + namespace Microsoft { namespace Quantum @@ -10,7 +12,7 @@ namespace Quantum /*============================================================================== Provides dynamically extendable storage for packed bits ==============================================================================*/ - struct BitStates + struct QIR_SHARED_API BitStates { typedef uint64_t TSLOT; static constexpr int slotSizeBits = sizeof(TSLOT) * 8; diff --git a/src/QirRuntime/public/CoreTypes.hpp b/src/QirRuntime/public/CoreTypes.hpp index 28abfb2a9eb..57f38a993e9 100644 --- a/src/QirRuntime/public/CoreTypes.hpp +++ b/src/QirRuntime/public/CoreTypes.hpp @@ -2,6 +2,16 @@ #include +#ifdef _WIN32 +#ifdef EXPORT_QIR_API +#define QIR_SHARED_API __declspec(dllexport) +#else +#define QIR_SHARED_API __declspec(dllimport) +#endif +#else +#define QIR_SHARED_API +#endif + // The core types will be exposed in the C-interfaces for interop, thus no // namespaces or scoped enums can be used to define them. diff --git a/src/QirRuntime/public/QirContext.hpp b/src/QirRuntime/public/QirContext.hpp index 672eef42660..a6c2f218f81 100644 --- a/src/QirRuntime/public/QirContext.hpp +++ b/src/QirRuntime/public/QirContext.hpp @@ -14,7 +14,7 @@ namespace Quantum void ReleaseQirContext(); struct AllocationsTracker; - struct QirExecutionContext + struct QIR_SHARED_API QirExecutionContext { ISimulator* simulator = nullptr; bool trackAllocatedObjects = false; @@ -23,9 +23,9 @@ namespace Quantum QirExecutionContext(ISimulator* sim, bool trackAllocatedObjects); ~QirExecutionContext(); }; - extern thread_local std::unique_ptr g_context; + extern QIR_SHARED_API thread_local std::unique_ptr g_context; - struct QirContextScope + struct QIR_SHARED_API QirContextScope { QirContextScope(ISimulator* sim, bool trackAllocatedObjects = false) { diff --git a/src/QirRuntime/public/QirTypes.hpp b/src/QirRuntime/public/QirTypes.hpp index dc0313995dc..6b144975346 100644 --- a/src/QirRuntime/public/QirTypes.hpp +++ b/src/QirRuntime/public/QirTypes.hpp @@ -6,10 +6,12 @@ #include #include +#include "CoreTypes.hpp" + /*====================================================================================================================== QirArray ======================================================================================================================*/ -struct QirArray +struct QIR_SHARED_API QirArray { int64_t count = 0; // overall size of the array across all dimensions const int itemSizeInBytes = 0; @@ -41,7 +43,7 @@ struct QirArray /*====================================================================================================================== QirString is just a wrapper around std::string ======================================================================================================================*/ -struct QirString +struct QIR_SHARED_API QirString { long refCount = 1; std::string str; @@ -57,7 +59,7 @@ struct QirString tuple is created. ======================================================================================================================*/ using PTuple = char*; -struct QirTupleHeader +struct QIR_SHARED_API QirTupleHeader { int32_t refCount = 0; int32_t aliasCount = 0; // used to enable copy elision, see the QIR specifications for details @@ -86,7 +88,7 @@ struct QirTupleHeader /*====================================================================================================================== A helper type for unpacking tuples used by multi-level controlled callables ======================================================================================================================*/ -struct TupleWithControls +struct QIR_SHARED_API TupleWithControls { QirArray* controls; TupleWithControls* innerTuple; @@ -120,7 +122,7 @@ static_assert( ======================================================================================================================*/ typedef void (*t_CallableEntry)(PTuple, PTuple, PTuple); typedef void (*t_CaptureCallback)(PTuple, int64_t); -struct QirCallable +struct QIR_SHARED_API QirCallable { static int constexpr Adjoint = 1; static int constexpr Controlled = 1 << 1; diff --git a/src/QirRuntime/public/QuantumApi_I.hpp b/src/QirRuntime/public/QuantumApi_I.hpp index d1a998b3f4b..74b35c49d94 100644 --- a/src/QirRuntime/public/QuantumApi_I.hpp +++ b/src/QirRuntime/public/QuantumApi_I.hpp @@ -8,7 +8,7 @@ namespace Microsoft { namespace Quantum { - struct IQuantumGateSet + struct QIR_SHARED_API IQuantumGateSet { virtual ~IQuantumGateSet() {} @@ -45,7 +45,7 @@ namespace Quantum virtual void ControlledAdjointT(long numControls, Qubit controls[], Qubit target) = 0; }; - struct IDiagnostics + struct QIR_SHARED_API IDiagnostics { virtual ~IDiagnostics() {} @@ -71,7 +71,7 @@ namespace Quantum const char* failureMessage) = 0; }; - struct ISimulator + struct QIR_SHARED_API ISimulator { virtual ~ISimulator() {} diff --git a/src/QirRuntime/public/SimFactory.hpp b/src/QirRuntime/public/SimFactory.hpp index dacedc4c423..f2e31a40dec 100644 --- a/src/QirRuntime/public/SimFactory.hpp +++ b/src/QirRuntime/public/SimFactory.hpp @@ -10,10 +10,10 @@ namespace Microsoft namespace Quantum { // Toffoli Simulator - std::unique_ptr CreateToffoliSimulator(); + QIR_SHARED_API std::unique_ptr CreateToffoliSimulator(); // Full State Simulator - std::unique_ptr CreateFullstateSimulator(); + QIR_SHARED_API std::unique_ptr CreateFullstateSimulator(); } // namespace Quantum } // namespace Microsoft \ No newline at end of file diff --git a/src/QirRuntime/public/TracerTypes.hpp b/src/QirRuntime/public/TracerTypes.hpp index 77e4565e974..7a95a3b81cf 100644 --- a/src/QirRuntime/public/TracerTypes.hpp +++ b/src/QirRuntime/public/TracerTypes.hpp @@ -3,6 +3,8 @@ #pragma once #include +#include "CoreTypes.hpp" + namespace Microsoft { namespace Quantum @@ -12,7 +14,7 @@ namespace Quantum using Duration = int; using LayerId = int64_t; - constexpr LayerId INVALID = std::numeric_limits::min(); - constexpr LayerId REQUESTNEW = std::numeric_limits::max(); + constexpr QIR_SHARED_API LayerId INVALID = std::numeric_limits::min(); + constexpr QIR_SHARED_API LayerId REQUESTNEW = std::numeric_limits::max(); } } \ No newline at end of file From e8c3f68a64eaa1e195de9869dd1d9e4aaf492c5c Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 21:19:32 +0000 Subject: [PATCH 10/31] Fix missing include --- src/QirRuntime/public/QirContext.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/QirRuntime/public/QirContext.hpp b/src/QirRuntime/public/QirContext.hpp index a6c2f218f81..f48119660d5 100644 --- a/src/QirRuntime/public/QirContext.hpp +++ b/src/QirRuntime/public/QirContext.hpp @@ -5,6 +5,8 @@ #include +#include "CoreTypes.hpp" + namespace Microsoft { namespace Quantum From 24834faabc2034760159999d3c02e8687404d693 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 22:01:51 +0000 Subject: [PATCH 11/31] Add thread_local global context exported accessor --- src/QirRuntime/lib/QSharpCore/intrinsics.cpp | 42 ++++++++++---------- src/QirRuntime/public/QirContext.hpp | 3 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/QirRuntime/lib/QSharpCore/intrinsics.cpp b/src/QirRuntime/lib/QSharpCore/intrinsics.cpp index ea9bf3a2129..38fd66aa31e 100644 --- a/src/QirRuntime/lib/QSharpCore/intrinsics.cpp +++ b/src/QirRuntime/lib/QSharpCore/intrinsics.cpp @@ -36,7 +36,7 @@ extern "C" assert(paulis->count == qubits->count); std::vector pauliIds = ExtractPauliIds(paulis); - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Exp( + return Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->Exp( paulis->count, reinterpret_cast(pauliIds.data()), reinterpret_cast(qubits->buffer), angle); } @@ -51,7 +51,7 @@ extern "C" assert(paulis->count == qubits->count); std::vector pauliIds = ExtractPauliIds(paulis); - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledExp( + return Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledExp( ctls->count, reinterpret_cast(ctls->buffer), paulis->count, reinterpret_cast(pauliIds.data()), reinterpret_cast(qubits->buffer), angle); } @@ -63,12 +63,12 @@ extern "C" void quantum__qis__h__body(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->H(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->H(qubit); } void quantum__qis__h__ctl(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledH( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledH( ctls->count, reinterpret_cast(ctls->buffer), qubit); } @@ -78,13 +78,13 @@ extern "C" assert(count == paulis->count); std::vector pauliIds = ExtractPauliIds(paulis); - return Microsoft::Quantum::g_context->simulator->Measure( + return Microsoft::Quantum::GlobalContext()->simulator->Measure( count, reinterpret_cast(pauliIds.data()), count, reinterpret_cast(qubits->buffer)); } void quantum__qis__r__body(PauliId axis, double angle, QUBIT* qubit) { - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->R(axis, qubit, angle); + return Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->R(axis, qubit, angle); } void quantum__qis__r__adj(PauliId axis, double angle, QUBIT* qubit) @@ -94,7 +94,7 @@ extern "C" void quantum__qis__r__ctl(QirArray* ctls, PauliId axis, double angle, QUBIT* qubit) { - return Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledR( + return Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledR( ctls->count, reinterpret_cast(ctls->buffer), axis, qubit, angle); } @@ -105,78 +105,78 @@ extern "C" void quantum__qis__s__body(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->S(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->S(qubit); } void quantum__qis__s__adj(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->AdjointS(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->AdjointS(qubit); } void quantum__qis__s__ctl(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledS( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledS( ctls->count, reinterpret_cast(ctls->buffer), qubit); } void quantum__qis__s__ctladj(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledAdjointS( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledAdjointS( ctls->count, reinterpret_cast(ctls->buffer), qubit); } void quantum__qis__t__body(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->T(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->T(qubit); } void quantum__qis__t__adj(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->AdjointT(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->AdjointT(qubit); } void quantum__qis__t__ctl(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledT( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledT( ctls->count, reinterpret_cast(ctls->buffer), qubit); } void quantum__qis__t__ctladj(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledAdjointT( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledAdjointT( ctls->count, reinterpret_cast(ctls->buffer), qubit); } void quantum__qis__x__body(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->X(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->X(qubit); } void quantum__qis__x__ctl(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledX( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledX( ctls->count, reinterpret_cast(ctls->buffer), qubit); } void quantum__qis__y__body(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Y(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->Y(qubit); } void quantum__qis__y__ctl(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledY( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledY( ctls->count, reinterpret_cast(ctls->buffer), qubit); } void quantum__qis__z__body(Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->Z(qubit); + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->Z(qubit); } void quantum__qis__z__ctl(QirArray* ctls, Qubit qubit) { - Microsoft::Quantum::g_context->simulator->AsQuantumGateSet()->ControlledZ( + Microsoft::Quantum::GlobalContext()->simulator->AsQuantumGateSet()->ControlledZ( ctls->count, reinterpret_cast(ctls->buffer), qubit); } } \ No newline at end of file diff --git a/src/QirRuntime/public/QirContext.hpp b/src/QirRuntime/public/QirContext.hpp index f48119660d5..149d91a50ba 100644 --- a/src/QirRuntime/public/QirContext.hpp +++ b/src/QirRuntime/public/QirContext.hpp @@ -25,7 +25,8 @@ namespace Quantum QirExecutionContext(ISimulator* sim, bool trackAllocatedObjects); ~QirExecutionContext(); }; - extern QIR_SHARED_API thread_local std::unique_ptr g_context; + extern thread_local std::unique_ptr g_context; + extern QIR_SHARED_API std::unique_ptr& GlobalContext() { return g_context; } struct QIR_SHARED_API QirContextScope { From 1d6cfdf94a43f3f784579d40bad0c6b230dcc6a6 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 22:24:32 +0000 Subject: [PATCH 12/31] Move implementaiton out of header --- src/QirRuntime/lib/QIR/context.cpp | 2 ++ src/QirRuntime/public/QirContext.hpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/QirRuntime/lib/QIR/context.cpp b/src/QirRuntime/lib/QIR/context.cpp index 7e10e02eab3..ff166a76f19 100644 --- a/src/QirRuntime/lib/QIR/context.cpp +++ b/src/QirRuntime/lib/QIR/context.cpp @@ -18,6 +18,8 @@ namespace Microsoft namespace Quantum { thread_local std::unique_ptr g_context = nullptr; + std::unique_ptr& GlobalContext() { return g_context; } + void InitializeQirContext(ISimulator* sim, bool trackAllocatedObjects) { assert(g_context == nullptr); diff --git a/src/QirRuntime/public/QirContext.hpp b/src/QirRuntime/public/QirContext.hpp index 149d91a50ba..b96a27c7378 100644 --- a/src/QirRuntime/public/QirContext.hpp +++ b/src/QirRuntime/public/QirContext.hpp @@ -26,7 +26,7 @@ namespace Quantum ~QirExecutionContext(); }; extern thread_local std::unique_ptr g_context; - extern QIR_SHARED_API std::unique_ptr& GlobalContext() { return g_context; } + extern QIR_SHARED_API std::unique_ptr& GlobalContext(); struct QIR_SHARED_API QirContextScope { From 2ed8c91df4c3a48bfbeadfc7f19bd3cc142020f9 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 23:47:08 +0000 Subject: [PATCH 13/31] Fix target_compile_definitions --- src/QirRuntime/lib/QIR/CMakeLists.txt | 11 ++++++----- src/QirRuntime/lib/QIR/allocationsTracker.hpp | 4 +++- src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 6 +++--- src/QirRuntime/public/QirContext.hpp | 6 +++--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index 51009c0f4d7..aa6efadd14b 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -27,13 +27,14 @@ set(rt_sup_source_files add_library(qir-rt-support ${rt_sup_source_files}) target_include_directories(qir-rt-support PUBLIC ${public_includes}) add_dependencies(qir-rt-support ${bridge_rt_target}) +target_compile_definitions(qir-rt-support-obj PRIVATE EXPORT_QIR_API=1) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qir-rt-support-obj OBJECT ${rt_sup_source_files}) target_source_from_qir_obj(qir-rt-support-obj bridge-rt) target_include_directories(qir-rt-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-rt-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_compile_definitions(qir-rt-support-obj PUBLIC EXPORT_QIR_API) +target_compile_definitions(qir-rt-support-obj PRIVATE EXPORT_QIR_API=1) #+++++++++++++++++++++++++++++++++++++ # qir-qis @@ -57,13 +58,14 @@ set(qis_sup_source_files add_library(qir-qis-support ${qis_sup_source_files}) target_include_directories(qir-qis-support PUBLIC ${public_includes}) add_dependencies(qir-qis-support ${bridge_qis_target}) +target_compile_definitions(qir-qis-support PRIVATE EXPORT_QIR_API=1) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qir-qis-support-obj OBJECT ${qis_sup_source_files}) target_source_from_qir_obj(qir-qis-support-obj bridge-qis) target_include_directories(qir-qis-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_compile_definitions(qir-qis-support-obj PUBLIC EXPORT_QIR_API) +target_compile_definitions(qir-qis-support-obj PRIVATE EXPORT_QIR_API=1) #=============================================================================== # Produce the qir dynamic library @@ -76,9 +78,8 @@ target_link_libraries(qir qir-qis-support-obj ) -target_include_directories(qir PUBLIC - ${public_includes} -) +target_include_directories(qir PUBLIC ${public_includes}) +target_compile_definitions(qir PRIVATE EXPORT_QIR_API=1) set_property(TARGET qir PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/QirRuntime/lib/QIR/allocationsTracker.hpp b/src/QirRuntime/lib/QIR/allocationsTracker.hpp index b5621ed2850..b587d18ab68 100644 --- a/src/QirRuntime/lib/QIR/allocationsTracker.hpp +++ b/src/QirRuntime/lib/QIR/allocationsTracker.hpp @@ -5,6 +5,8 @@ #include +#include "CoreTypes.hpp" + namespace Microsoft { namespace Quantum @@ -12,7 +14,7 @@ namespace Quantum // The tracker keeps a list of pointers to all qir objects that have been allocated during the lifetime of an // execution context and their reference counts, which allows us to check for double-releases and leaks when the // actual objects have been released. - struct AllocationsTracker + struct QIR_SHARED_API AllocationsTracker { std::unordered_map allocatedObjects; diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index 56d05dee099..4c6acacee25 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -18,6 +18,7 @@ set(qsharp_core_sup_source_files add_library(qsharp-core-qis-support ${qsharp_core_sup_source_files}) target_include_directories(qsharp-core-qis-support PUBLIC ${public_includes}) add_dependencies(qsharp-core-qis-support ${qsharp_core_qis_target}) +target_compile_definitions(qsharp-core-qis-support-obj PRIVATE EXPORT_QIR_API=1) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qsharp-core-qis-support-obj OBJECT ${qsharp_core_sup_source_files}) @@ -39,9 +40,8 @@ target_link_libraries(QSharpCore -lqir ) -target_include_directories(QSharpCore PUBLIC - ${public_includes} -) +target_include_directories(QSharpCore PUBLIC ${public_includes}) +target_compile_definitions(QSharpCore PRIVATE EXPORT_QIR_API=1) set_property(TARGET QSharpCore PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/QirRuntime/public/QirContext.hpp b/src/QirRuntime/public/QirContext.hpp index b96a27c7378..2fe786455cd 100644 --- a/src/QirRuntime/public/QirContext.hpp +++ b/src/QirRuntime/public/QirContext.hpp @@ -12,10 +12,10 @@ namespace Microsoft namespace Quantum { struct ISimulator; - void InitializeQirContext(ISimulator* sim, bool trackAllocatedObjects = false); - void ReleaseQirContext(); - struct AllocationsTracker; + + QIR_SHARED_API void InitializeQirContext(ISimulator* sim, bool trackAllocatedObjects = false); + QIR_SHARED_API void ReleaseQirContext(); struct QIR_SHARED_API QirExecutionContext { ISimulator* simulator = nullptr; From bf4c7f44ea675f8570fea0f8bb5fb57856eecef7 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Sun, 7 Mar 2021 23:56:29 +0000 Subject: [PATCH 14/31] Fix typos --- src/QirRuntime/lib/QIR/CMakeLists.txt | 10 +++++----- src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index aa6efadd14b..b96b16459b8 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -27,14 +27,14 @@ set(rt_sup_source_files add_library(qir-rt-support ${rt_sup_source_files}) target_include_directories(qir-rt-support PUBLIC ${public_includes}) add_dependencies(qir-rt-support ${bridge_rt_target}) -target_compile_definitions(qir-rt-support-obj PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(qir-rt-support PRIVATE EXPORT_QIR_API) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qir-rt-support-obj OBJECT ${rt_sup_source_files}) target_source_from_qir_obj(qir-rt-support-obj bridge-rt) target_include_directories(qir-rt-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-rt-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_compile_definitions(qir-rt-support-obj PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(qir-rt-support-obj PRIVATE EXPORT_QIR_API) #+++++++++++++++++++++++++++++++++++++ # qir-qis @@ -58,14 +58,14 @@ set(qis_sup_source_files add_library(qir-qis-support ${qis_sup_source_files}) target_include_directories(qir-qis-support PUBLIC ${public_includes}) add_dependencies(qir-qis-support ${bridge_qis_target}) -target_compile_definitions(qir-qis-support PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(qir-qis-support PRIVATE EXPORT_QIR_API) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qir-qis-support-obj OBJECT ${qis_sup_source_files}) target_source_from_qir_obj(qir-qis-support-obj bridge-qis) target_include_directories(qir-qis-support-obj PUBLIC ${public_includes}) set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_compile_definitions(qir-qis-support-obj PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(qir-qis-support-obj PRIVATE EXPORT_QIR_API) #=============================================================================== # Produce the qir dynamic library @@ -79,7 +79,7 @@ target_link_libraries(qir ) target_include_directories(qir PUBLIC ${public_includes}) -target_compile_definitions(qir PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(qir PRIVATE EXPORT_QIR_API) set_property(TARGET qir PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index 4c6acacee25..75aba17048e 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -18,7 +18,7 @@ set(qsharp_core_sup_source_files add_library(qsharp-core-qis-support ${qsharp_core_sup_source_files}) target_include_directories(qsharp-core-qis-support PUBLIC ${public_includes}) add_dependencies(qsharp-core-qis-support ${qsharp_core_qis_target}) -target_compile_definitions(qsharp-core-qis-support-obj PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(qsharp-core-qis-support PRIVATE EXPORT_QIR_API) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(qsharp-core-qis-support-obj OBJECT ${qsharp_core_sup_source_files}) @@ -41,7 +41,7 @@ target_link_libraries(QSharpCore ) target_include_directories(QSharpCore PUBLIC ${public_includes}) -target_compile_definitions(QSharpCore PRIVATE EXPORT_QIR_API=1) +target_compile_definitions(QSharpCore PRIVATE EXPORT_QIR_API) set_property(TARGET QSharpCore PROPERTY POSITION_INDEPENDENT_CODE ON) From d4bc49651b707105c7c7f6684970b91bbfba6bad Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 02:07:56 +0000 Subject: [PATCH 15/31] More compile definitions --- src/QirRuntime/lib/Simulators/CMakeLists.txt | 2 ++ src/QirRuntime/lib/Tracer/CMakeLists.txt | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/QirRuntime/lib/Simulators/CMakeLists.txt b/src/QirRuntime/lib/Simulators/CMakeLists.txt index f2faa58b05f..abbceb8e16e 100644 --- a/src/QirRuntime/lib/Simulators/CMakeLists.txt +++ b/src/QirRuntime/lib/Simulators/CMakeLists.txt @@ -15,6 +15,7 @@ set(includes add_library(simulators STATIC ${source_files}) target_include_directories(simulators PUBLIC ${includes}) target_link_libraries(simulators ${CMAKE_DL_LIBS}) +target_compile_definitions(simulators PRIVATE EXPORT_QIR_API) #=============================================================================== # Produce object lib we'll use to create a shared lib (so/dll) later on @@ -22,3 +23,4 @@ target_link_libraries(simulators ${CMAKE_DL_LIBS}) add_library(simulators-obj OBJECT ${source_files}) target_include_directories(simulators-obj PUBLIC ${includes}) set_property(TARGET simulators-obj PROPERTY POSITION_INDEPENDENT_CODE ON) +target_compile_definitions(simulators-obj PRIVATE EXPORT_QIR_API) diff --git a/src/QirRuntime/lib/Tracer/CMakeLists.txt b/src/QirRuntime/lib/Tracer/CMakeLists.txt index 40388c317f3..64f838b4d4f 100644 --- a/src/QirRuntime/lib/Tracer/CMakeLists.txt +++ b/src/QirRuntime/lib/Tracer/CMakeLists.txt @@ -15,12 +15,14 @@ set(includes add_library(tracer STATIC ${source_files}) target_include_directories(tracer PUBLIC ${includes}) add_dependencies(tracer tracer-bridge) +target_compile_definitions(tracer PRIVATE EXPORT_QIR_API) # Produce object lib we'll use to create a shared lib (so/dll) later on add_library(tracer-obj OBJECT ${source_files}) target_source_from_qir_obj(tracer-obj tracer-bridge) target_include_directories(tracer-obj PUBLIC ${includes}) set_property(TARGET tracer-obj PROPERTY POSITION_INDEPENDENT_CODE ON) +target_compile_definitions(tracer-obj PRIVATE EXPORT_QIR_API) #=============================================================================== # Produce the qirtracer dynamic library @@ -34,9 +36,8 @@ target_link_libraries(qirtracer -lqir ) -target_include_directories(qirtracer PUBLIC - ${includes} -) +target_include_directories(qirtracer PUBLIC ${includes}) +target_compile_definitions(qirtracer PRIVATE EXPORT_QIR_API) set_property(TARGET qirtracer PROPERTY POSITION_INDEPENDENT_CODE ON) From 9cc3e7f4c437fdcc597ae5a3f5c7ab94e4fe5461 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 02:50:23 +0000 Subject: [PATCH 16/31] Use tracer types differently --- src/QirRuntime/public/TracerTypes.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/QirRuntime/public/TracerTypes.hpp b/src/QirRuntime/public/TracerTypes.hpp index 7a95a3b81cf..82e5655fd82 100644 --- a/src/QirRuntime/public/TracerTypes.hpp +++ b/src/QirRuntime/public/TracerTypes.hpp @@ -3,7 +3,6 @@ #pragma once #include -#include "CoreTypes.hpp" namespace Microsoft { @@ -14,7 +13,7 @@ namespace Quantum using Duration = int; using LayerId = int64_t; - constexpr QIR_SHARED_API LayerId INVALID = std::numeric_limits::min(); - constexpr QIR_SHARED_API LayerId REQUESTNEW = std::numeric_limits::max(); + constexpr LayerId INVALID = std::numeric_limits::min(); + constexpr LayerId REQUESTNEW = std::numeric_limits::max(); } } \ No newline at end of file From b78ec6bff418588db8a13221a8076bbc57a7ee1f Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 03:46:45 +0000 Subject: [PATCH 17/31] Add dllexport to IR --- src/QirRuntime/lib/QIR/bridge-qis.ll | 44 +++--- src/QirRuntime/lib/QIR/bridge-rt.ll | 138 +++++++++--------- .../lib/QSharpCore/qsharp-core-qis.ll | 50 +++---- src/QirRuntime/lib/Tracer/tracer-bridge.ll | 16 +- 4 files changed, 124 insertions(+), 124 deletions(-) diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QIR/bridge-qis.ll index 56540c53dc9..b1cce0ca990 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QIR/bridge-qis.ll @@ -35,7 +35,7 @@ declare void @quantum__qis__message__body(%struct.QirString* %str) ;=============================================================================== ; -define void @__quantum__qis__message__body(%String* %.str) { +define dllexport 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 @@ -65,44 +65,44 @@ declare double @quantum__qis__ieeeremainder__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/ +define dllexport 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/ +define dllexport 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 +define dllexport 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 +define dllexport 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 +define dllexport 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 +define dllexport 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 +define dllexport 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 +define dllexport 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 @@ -110,21 +110,21 @@ define double @__quantum__qis__arctan2__body(double %y, double %x) { ; Q#: func ; function Sin (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sin -define double @__quantum__qis__sin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sin +define dllexport double @__quantum__qis__sin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sin %result = call double @llvm.sin.f64(double %theta) ; https://llvm.org/docs/LangRef.html#llvm-sin-intrinsic ret double %result } ; function Cos (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.cos -define double @__quantum__qis__cos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cos +define dllexport double @__quantum__qis__cos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cos %result = call double @llvm.cos.f64(double %theta) ; https://llvm.org/docs/LangRef.html#llvm-cos-intrinsic ret double %result } ; function Tan (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.tan -define double @__quantum__qis__tan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tan +define dllexport double @__quantum__qis__tan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tan %sin = call double @llvm.sin.f64(double %theta) %cos = call double @llvm.cos.f64(double %theta) %result = fdiv double %sin, %cos ; tg(x) = sin(x) / cos(x) @@ -133,21 +133,21 @@ define double @__quantum__qis__tan__body(double %theta) { ; https://en.cpp ; function Sinh (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sinh -define double @__quantum__qis__sinh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sinh +define dllexport double @__quantum__qis__sinh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sinh %result = call double @quantum__qis__sinh__body(double %theta) ret double %result } ; function Cosh (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.cosh -define double @__quantum__qis__cosh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cosh +define dllexport double @__quantum__qis__cosh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cosh %result = call double @quantum__qis__cosh__body(double %theta) ret double %result } ; function Tanh (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.tanh -define double @__quantum__qis__tanh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tanh +define dllexport double @__quantum__qis__tanh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tanh %sin = call double @__quantum__qis__sinh__body(double %theta) %cos = call double @__quantum__qis__cosh__body(double %theta) %result = fdiv double %sin, %cos ; tanh(x) = sinh(x) / cosh(x) @@ -156,28 +156,28 @@ define double @__quantum__qis__tanh__body(double %theta) { ; https://en.cpp ; function ArcSin (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arcsin -define double @__quantum__qis__arcsin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/asin +define dllexport double @__quantum__qis__arcsin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/asin %result = call double @quantum__qis__arcsin__body(double %theta) ret double %result } ; function ArcCos (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos -define double @__quantum__qis__arccos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/acos +define dllexport double @__quantum__qis__arccos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/acos %result = call double @quantum__qis__arccos__body(double %theta) ret double %result } ; function ArcTan (theta : Double) : Double ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan -define double @__quantum__qis__arctan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/atan +define dllexport double @__quantum__qis__arctan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/atan %result = call double @quantum__qis__arctan__body(double %theta) ret double %result } ; function IEEERemainder(x : Double, y : Double) : Double -define double @__quantum__qis__ieeeremainder__body(double %x, double %y) { +define dllexport double @__quantum__qis__ieeeremainder__body(double %x, double %y) { %result = call double @quantum__qis__ieeeremainder__body(double %x, double %y) ret double %result } @@ -185,7 +185,7 @@ define double @__quantum__qis__ieeeremainder__body(double %x, double %y) { ; operation DrawRandomInt (min : Int, max : Int) : Int ; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint -define i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { +define dllexport i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { %result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) ret i64 %result } @@ -197,7 +197,7 @@ declare void @quantum__qis__applyifelseintrinsic__body(%class.RESULT*, %struct.Q declare void @quantum__qis__applyconditionallyintrinsic__body( %struct.QirArray*, %struct.QirArray*, %struct.QirCallable*, %struct.QirCallable*) -define void @__quantum__qis__applyifelseintrinsic__body( +define dllexport void @__quantum__qis__applyifelseintrinsic__body( %Result* %.r, %Callable* %.clb_on_zero, %Callable* %.clb_on_one) { %r = bitcast %Result* %.r to %class.RESULT* @@ -208,7 +208,7 @@ define void @__quantum__qis__applyifelseintrinsic__body( ret void } -define void @__quantum__qis__applyconditionallyintrinsic__body( +define dllexport void @__quantum__qis__applyconditionallyintrinsic__body( %Array* %.rs1, %Array* %.rs2, %Callable* %.clb_on_equal, %Callable* %.clb_on_different) { %rs1 = bitcast %Array* %.rs1 to %struct.QirArray* diff --git a/src/QirRuntime/lib/QIR/bridge-rt.ll b/src/QirRuntime/lib/QIR/bridge-rt.ll index d7712b0d8d8..f27357e918c 100644 --- a/src/QirRuntime/lib/QIR/bridge-rt.ll +++ b/src/QirRuntime/lib/QIR/bridge-rt.ll @@ -111,17 +111,17 @@ declare %"struct.QirString"* @quantum__rt__range_to_string(%"struct.QirRange"* d ;------------------------------------------------------------------------------ ; classical bridge ; -define i8* @__quantum__rt__heap_alloc(i32 %size) { +define dllexport i8* @__quantum__rt__heap_alloc(i32 %size) { %mem = call i8* @quantum__rt__heap_alloc(i32 %size) ret i8* %mem } -define void @__quantum__rt__heap_free(i8* %mem) { +define dllexport void @__quantum__rt__heap_free(i8* %mem) { call void @quantum__rt__heap_free(i8* %mem) ret void } -define void @__quantum__rt__fail(%String* %.str) { +define dllexport void @__quantum__rt__fail(%String* %.str) { %str = bitcast %String* %.str to %"struct.QirString"* call void @quantum__rt__fail(%"struct.QirString"* %str) ret void @@ -132,30 +132,30 @@ define void @__quantum__rt__fail(%String* %.str) { ; qubits bridge ; ; NYI: -;define %Qubit* @__quantum__rt__qubit_borrow() -;define void @__quantum__rt__qubit_return(%Qubit*) -;define %Array* @__quantum__rt__qubit_borrow_array(i64) -;define void @__quantum__rt__qubit_return_array(%Array*) +;define dllexport %Qubit* @__quantum__rt__qubit_borrow() +;define dllexport void @__quantum__rt__qubit_return(%Qubit*) +;define dllexport %Array* @__quantum__rt__qubit_borrow_array(i64) +;define dllexport void @__quantum__rt__qubit_return_array(%Array*) ; -define %Qubit* @__quantum__rt__qubit_allocate() { +define dllexport %Qubit* @__quantum__rt__qubit_allocate() { %q = call %class.QUBIT* @quantum__rt__qubit_allocate() %.q = bitcast %class.QUBIT* %q to %Qubit* ret %Qubit* %.q } -define void @__quantum__rt__qubit_release(%Qubit* %.q) { +define dllexport void @__quantum__rt__qubit_release(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__rt__qubit_release(%class.QUBIT* %q) ret void } -define %Array* @__quantum__rt__qubit_allocate_array(i64 %n) { +define dllexport %Array* @__quantum__rt__qubit_allocate_array(i64 %n) { %qa = call %"struct.QirArray"* @quantum__rt__qubit_allocate_array(i64 %n) %.qa = bitcast %"struct.QirArray"* %qa to %Array* ret %Array* %.qa } -define void @__quantum__rt__qubit_release_array(%Array* %.qa) { +define dllexport void @__quantum__rt__qubit_release_array(%Array* %.qa) { %qa = bitcast %Array* %.qa to %"struct.QirArray"* call void @quantum__rt__qubit_release_array(%"struct.QirArray"* %qa) ret void @@ -165,14 +165,14 @@ define void @__quantum__rt__qubit_release_array(%Array* %.qa) { ;------------------------------------------------------------------------------ ; results bridge ; -define i1 @__quantum__rt__result_equal(%Result* %.r1, %Result* %.r2) { +define dllexport i1 @__quantum__rt__result_equal(%Result* %.r1, %Result* %.r2) { %r1 = bitcast %Result* %.r1 to %class.RESULT* %r2 = bitcast %Result* %.r2 to %class.RESULT* %c = call i1 @quantum__rt__result_equal(%class.RESULT* %r1, %class.RESULT* %r2) ret i1 %c } -define void @__quantum__rt__result_update_reference_count(%Result* %.r, i64 %.c) { +define dllexport void @__quantum__rt__result_update_reference_count(%Result* %.r, i64 %.c) { %r = bitcast %Result* %.r to %class.RESULT* %c = trunc i64 %.c to i32 call void @quantum__rt__result_update_reference_count(%class.RESULT* %r, i32 %c) @@ -183,7 +183,7 @@ define void @__quantum__rt__result_update_reference_count(%Result* %.r, i64 %.c) ; ----------------------------------------------------------------------------- ; arrays bridge ; -define %Array* @__quantum__rt__array_concatenate(%Array* %.head, %Array* %.tail) { +define dllexport %Array* @__quantum__rt__array_concatenate(%Array* %.head, %Array* %.tail) { %head = bitcast %Array* %.head to %"struct.QirArray"* %tail = bitcast %Array* %.tail to %"struct.QirArray"* %con = call %"struct.QirArray"* @quantum__rt__array_concatenate(%"struct.QirArray"* %head, %"struct.QirArray"* %tail) @@ -191,7 +191,7 @@ define %Array* @__quantum__rt__array_concatenate(%Array* %.head, %Array* %.tail) ret %Array* %.con } -define %Array* @__quantum__rt__array_copy(%Array* %.ar, i1 %force) { +define dllexport %Array* @__quantum__rt__array_copy(%Array* %.ar, i1 %force) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %ar_copy = call %"struct.QirArray"* @quantum__rt__array_copy(%"struct.QirArray"* %ar, i1 %force) %.ar_copy = bitcast %"struct.QirArray"* %ar_copy to %Array* @@ -201,7 +201,7 @@ define %Array* @__quantum__rt__array_copy(%Array* %.ar, i1 %force) { ; TODO: This bridge isn't cross-platform! ; it works on Windows but on Linux %args ends up not being a valid pointer. declare void @DebugLogPtr(i8*) -define %Array* @__quantum__rt__array_create(i32 %item_size, i32 %dim_count, ...) { +define dllexport %Array* @__quantum__rt__array_create(i32 %item_size, i32 %dim_count, ...) { %args1 = alloca i8*, align 8 %args2 = bitcast i8** %args1 to i8* call void @llvm.va_start(i8* %args2) @@ -213,19 +213,19 @@ define %Array* @__quantum__rt__array_create(i32 %item_size, i32 %dim_count, ...) ret %Array* %.ar } -define %Array* @__quantum__rt__array_create_1d(i32 %item_size, i64 %count) { +define dllexport %Array* @__quantum__rt__array_create_1d(i32 %item_size, i64 %count) { %ar = call %"struct.QirArray"* @quantum__rt__array_create_1d(i32 %item_size, i64 %count) %.ar = bitcast %"struct.QirArray"* %ar to %Array* ret %Array* %.ar } -define i32 @__quantum__rt__array_get_dim(%Array* %.ar) { +define dllexport i32 @__quantum__rt__array_get_dim(%Array* %.ar) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %dim_count = call i32 @quantum__rt__array_get_dim(%"struct.QirArray"* %ar) ret i32 %dim_count } -define i8* @__quantum__rt__array_get_element_ptr(%Array* %.ar, ...) { +define dllexport i8* @__quantum__rt__array_get_element_ptr(%Array* %.ar, ...) { %args1 = alloca i8*, align 8 %args2 = bitcast i8** %args1 to i8* call void @llvm.va_start(i8* %args2) @@ -235,32 +235,32 @@ define i8* @__quantum__rt__array_get_element_ptr(%Array* %.ar, ...) { ret i8* %ptr } -define i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %.ar, i64 %i) { +define dllexport i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %.ar, i64 %i) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %item = call i8* @quantum__rt__array_get_element_ptr_1d(%"struct.QirArray"* %ar, i64 %i) ret i8* %item } -define i64 @__quantum__rt__array_get_size(%Array* %.ar, i32 %dim) { +define dllexport i64 @__quantum__rt__array_get_size(%Array* %.ar, i32 %dim) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %l = call i64 @quantum__rt__array_get_size(%"struct.QirArray"* %ar, i32 %dim) ret i64 %l } -define i64 @__quantum__rt__array_get_size_1d(%Array* %.ar) { +define dllexport i64 @__quantum__rt__array_get_size_1d(%Array* %.ar) { %l = call i64 @__quantum__rt__array_get_size(%Array* %.ar, i32 0) ret i64 %l } -define %Array* @__quantum__rt__array_project(%Array* %.ar, i32 %dim, i64 %index) { +define dllexport %Array* @__quantum__rt__array_project(%Array* %.ar, i32 %dim, i64 %index) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %project = call %"struct.QirArray"* @quantum__rt__array_project(%"struct.QirArray"* %ar, i32 %dim, i64 %index) %.project = bitcast %"struct.QirArray"* %project to %Array* ret %Array* %.project } -define %Array* @__quantum__rt__array_slice(%Array* %.ar, i32 %dim, %Range %.range) { +define dllexport %Array* @__quantum__rt__array_slice(%Array* %.ar, i32 %dim, %Range %.range) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %.prange = alloca %Range store %Range %.range, %Range* %.prange @@ -271,19 +271,19 @@ define %Array* @__quantum__rt__array_slice(%Array* %.ar, i32 %dim, %Range %.rang ret %Array* %.slice } -define %Array* @__quantum__rt__array_slice_1d(%Array* %.ar, %Range %.range) { +define dllexport %Array* @__quantum__rt__array_slice_1d(%Array* %.ar, %Range %.range) { %.slice = call %Array* @__quantum__rt__array_slice(%Array* %.ar, i32 0, %Range %.range) ret %Array* %.slice } -define void @__quantum__rt__array_update_reference_count(%Array* %.ar, i64 %.c) { +define dllexport void @__quantum__rt__array_update_reference_count(%Array* %.ar, i64 %.c) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %c = trunc i64 %.c to i32 call void @quantum__rt__array_update_reference_count(%"struct.QirArray"* %ar, i32 %c) ret void } -define void @__quantum__rt__array_update_alias_count(%Array* %.ar, i64 %.c) { +define dllexport void @__quantum__rt__array_update_alias_count(%Array* %.ar, i64 %.c) { %ar = bitcast %Array* %.ar to %"struct.QirArray"* %c = trunc i64 %.c to i32 call void @quantum__rt__array_update_alias_count(%"struct.QirArray"* %ar, i32 %c) @@ -293,20 +293,20 @@ define void @__quantum__rt__array_update_alias_count(%Array* %.ar, i64 %.c) { ;------------------------------------------------------------------------------ ; tuples bridge ; -define %Tuple* @__quantum__rt__tuple_create(i64 %size) { +define dllexport %Tuple* @__quantum__rt__tuple_create(i64 %size) { %th = call i8* @quantum__rt__tuple_create(i64 %size) %.th = bitcast i8* %th to %Tuple* ret %Tuple* %.th } -define void @__quantum__rt__tuple_update_reference_count(%Tuple* %.th, i64 %.c) { +define dllexport void @__quantum__rt__tuple_update_reference_count(%Tuple* %.th, i64 %.c) { %th = bitcast %Tuple* %.th to i8* %c = trunc i64 %.c to i32 call void @quantum__rt__tuple_update_reference_count(i8* %th, i32 %c) ret void } -define void @__quantum__rt__tuple_update_alias_count(%Tuple* %.th, i64 %.c) { +define dllexport void @__quantum__rt__tuple_update_alias_count(%Tuple* %.th, i64 %.c) { %th = bitcast %Tuple* %.th to i8* %c = trunc i64 %.c to i32 call void @quantum__rt__tuple_update_alias_count(i8* %th, i32 %c) @@ -316,21 +316,21 @@ define void @__quantum__rt__tuple_update_alias_count(%Tuple* %.th, i64 %.c) { ;------------------------------------------------------------------------------ ; callables bridge ; -define void @__quantum__rt__callable_update_reference_count(%Callable* %.clb, i64 %.c) { +define dllexport void @__quantum__rt__callable_update_reference_count(%Callable* %.clb, i64 %.c) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* %c = trunc i64 %.c to i32 call void @quantum__rt__callable_update_reference_count(%"struct.QirCallable"* %clb, i32 %c) ret void } -define void @__quantum__rt__callable_update_alias_count(%Callable* %.clb, i64 %.c) { +define dllexport void @__quantum__rt__callable_update_alias_count(%Callable* %.clb, i64 %.c) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* %c = trunc i64 %.c to i32 call void @quantum__rt__callable_update_alias_count(%"struct.QirCallable"* %clb, i32 %c) ret void } -define %Callable* @__quantum__rt__callable_create( +define dllexport %Callable* @__quantum__rt__callable_create( [4 x void (%Tuple*, %Tuple*, %Tuple*)*]* %.ft, [2 x void (%Tuple*, i64)*]* %.callbacks, %Tuple* %.capture) { %ft = bitcast [4 x void (%Tuple*, %Tuple*, %Tuple*)*]* %.ft to void (i8*, i8*, i8*)** %callbacks = bitcast [2 x void (%Tuple*, i64)*]* %.callbacks to void (i8*, i64)** @@ -341,7 +341,7 @@ define %Callable* @__quantum__rt__callable_create( ret %Callable* %.clb } -define void @__quantum__rt__callable_invoke(%Callable* %.clb, %Tuple* %.args, %Tuple* %.res) { +define dllexport void @__quantum__rt__callable_invoke(%Callable* %.clb, %Tuple* %.args, %Tuple* %.res) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* %args = bitcast %Tuple* %.args to i8* %res = bitcast %Tuple* %.res to i8* @@ -349,28 +349,28 @@ define void @__quantum__rt__callable_invoke(%Callable* %.clb, %Tuple* %.args, %T ret void } -define %Callable* @__quantum__rt__callable_copy(%Callable* %.clb, i1 %force) { +define dllexport %Callable* @__quantum__rt__callable_copy(%Callable* %.clb, i1 %force) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* %clb_copy = call %"struct.QirCallable"* @quantum__rt__callable_copy(%"struct.QirCallable"* %clb, i1 %force) %.clb_copy = bitcast %"struct.QirCallable"* %clb_copy to %Callable* ret %Callable* %.clb_copy } -define %Callable* @__quantum__rt__callable_make_adjoint(%Callable* %.clb) { +define dllexport %Callable* @__quantum__rt__callable_make_adjoint(%Callable* %.clb) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* %clb_adj = call %"struct.QirCallable"* @quantum__rt__callable_make_adjoint(%"struct.QirCallable"* %clb) %.clb_adj = bitcast %"struct.QirCallable"* %clb_adj to %Callable* ret %Callable* %.clb_adj } -define %Callable* @__quantum__rt__callable_make_controlled(%Callable* %.clb) { +define dllexport %Callable* @__quantum__rt__callable_make_controlled(%Callable* %.clb) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* %clb_cnt = call %"struct.QirCallable"* @quantum__rt__callable_make_controlled(%"struct.QirCallable"* %clb) %.clb_cnt = bitcast %"struct.QirCallable"* %clb_cnt to %Callable* ret %Callable* %.clb_cnt } -define void @__quantum__rt__callable_memory_management(i32 %index, %Callable* %.clb, i64 %parameter) { +define dllexport void @__quantum__rt__callable_memory_management(i32 %index, %Callable* %.clb, i64 %parameter) { %clb = bitcast %Callable* %.clb to %"struct.QirCallable"* call void @quantum__rt__callable_memory_management(i32 %index, %"struct.QirCallable"* %clb, i64 %parameter) ret void @@ -379,22 +379,22 @@ define void @__quantum__rt__callable_memory_management(i32 %index, %Callable* %. ; strings bridge ; ; NYI: -;define %String* @__quantum__rt__bigint_to_string(%BigInt*) +;define dllexport %String* @__quantum__rt__bigint_to_string(%BigInt*) -define %String* @__quantum__rt__string_create(i32 %length_ignored, i8* %null_terminated_buffer) { +define dllexport %String* @__quantum__rt__string_create(i32 %length_ignored, 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 } -define void @__quantum__rt__string_update_reference_count(%String* %.str, i64 %.c) { +define dllexport void @__quantum__rt__string_update_reference_count(%String* %.str, i64 %.c) { %str = bitcast %String* %.str to %"struct.QirString"* %c = trunc i64 %.c to i32 call void @quantum__rt__string_update_reference_count(%"struct.QirString"* %str, i32 %c) ret void } -define %String* @__quantum__rt__string_concatenate(%String* %.head, %String* %.tail) { +define dllexport %String* @__quantum__rt__string_concatenate(%String* %.head, %String* %.tail) { %head = bitcast %String* %.head to %"struct.QirString"* %tail = bitcast %String* %.tail to %"struct.QirString"* %str = call %"struct.QirString"* @quantum__rt__string_concatenate( @@ -403,53 +403,53 @@ define %String* @__quantum__rt__string_concatenate(%String* %.head, %String* %.t ret %String* %.str } -define i1 @__quantum__rt__string_equal(%String* %.str1, %String* %.str2) { +define dllexport i1 @__quantum__rt__string_equal(%String* %.str1, %String* %.str2) { %str1 = bitcast %String* %.str1 to %"struct.QirString"* %str2 = bitcast %String* %.str2 to %"struct.QirString"* %eq = call i1 @quantum__rt__string_equal(%"struct.QirString"* %str1, %"struct.QirString"* %str2) ret i1 %eq } -define %String* @__quantum__rt__int_to_string(i64 %val) { +define dllexport %String* @__quantum__rt__int_to_string(i64 %val) { %str = call %"struct.QirString"* @quantum__rt__int_to_string(i64 %val) %.str = bitcast %"struct.QirString"* %str to %String* ret %String* %.str } -define %String* @__quantum__rt__double_to_string(double %val) { +define dllexport %String* @__quantum__rt__double_to_string(double %val) { %str = call %"struct.QirString"* @quantum__rt__double_to_string(double %val) %.str = bitcast %"struct.QirString"* %str to %String* ret %String* %.str } -define %String* @__quantum__rt__bool_to_string(i1 %val) { +define dllexport %String* @__quantum__rt__bool_to_string(i1 %val) { %str = call %"struct.QirString"* @quantum__rt__bool_to_string(i1 %val) %.str = bitcast %"struct.QirString"* %str to %String* ret %String* %.str } -define %String* @__quantum__rt__result_to_string(%Result* %.r) { +define dllexport %String* @__quantum__rt__result_to_string(%Result* %.r) { %r = bitcast %Result* %.r to %"class.RESULT"* %str = call %"struct.QirString"* @quantum__rt__result_to_string(%"class.RESULT"* %r) %.str = bitcast %"struct.QirString"* %str to %String* ret %String* %.str } -define %String* @__quantum__rt__pauli_to_string(%Pauli %.pauli) { +define dllexport %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) { +define dllexport %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) %.str = bitcast %"struct.QirString"* %str to %String* ret %String* %.str } -define %String* @__quantum__rt__range_to_string(%Range %.range) { +define dllexport %String* @__quantum__rt__range_to_string(%Range %.range) { %.prange = alloca %Range store %Range %.range, %Range* %.prange %range = bitcast %Range* %.prange to %"struct.QirRange"* @@ -462,23 +462,23 @@ define %String* @__quantum__rt__range_to_string(%Range %.range) { ; bigints bridge ; ; NYI: -;define %BigInt* @__quantum__rt__bigint_create_i64(i64) -;define %BigInt* @__quantum__rt__bigint_create_array(i32, [0 x i8]) -;define void @__quantum__rt__bigint_update_reference_count(%BigInt*, i64) -;define %BigInt* @__quantum__rt__bigint_negate(%BigInt*) -;define %BigInt* @__quantum__rt__bigint_add(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_subtract(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_multiply(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_divide(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_modulus(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_power(%BigInt*, i32) -;define %BigInt* @__quantum__rt__bigint_bitand(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_bitor(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_bitxor(%BigInt*, %BigInt*) -;define %BigInt* @__quantum__rt__bigint_bitnot(%BigInt*) -;define %BigInt* @__quantum__rt__bigint_shiftleft(%BigInt*, i64) -;define %BigInt* @__quantum__rt__bigint_shiftright(%BigInt*, i64) -;define i1 @__quantum__rt__bigint_equal(%BigInt*, %BigInt*) -;define i1 @__quantum__rt__bigint_greater(%BigInt*, %BigInt*) -;define i1 @__quantum__rt__bigint_greater_eq(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_create_i64(i64) +;define dllexport %BigInt* @__quantum__rt__bigint_create_array(i32, [0 x i8]) +;define dllexport void @__quantum__rt__bigint_update_reference_count(%BigInt*, i64) +;define dllexport %BigInt* @__quantum__rt__bigint_negate(%BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_add(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_subtract(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_multiply(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_divide(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_modulus(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_power(%BigInt*, i32) +;define dllexport %BigInt* @__quantum__rt__bigint_bitand(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_bitor(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_bitxor(%BigInt*, %BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_bitnot(%BigInt*) +;define dllexport %BigInt* @__quantum__rt__bigint_shiftleft(%BigInt*, i64) +;define dllexport %BigInt* @__quantum__rt__bigint_shiftright(%BigInt*, i64) +;define dllexport i1 @__quantum__rt__bigint_equal(%BigInt*, %BigInt*) +;define dllexport i1 @__quantum__rt__bigint_greater(%BigInt*, %BigInt*) +;define dllexport i1 @__quantum__rt__bigint_greater_eq(%BigInt*, %BigInt*) ; \ No newline at end of file diff --git a/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll b/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll index c7bf2c25ec5..f39633e8e78 100644 --- a/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll +++ b/src/QirRuntime/lib/QSharpCore/qsharp-core-qis.ll @@ -64,21 +64,21 @@ declare void @quantum__qis__z__ctl(%struct.QirArray*, %class.QUBIT*) ; quantum.qis namespace implementations ; -define void @__quantum__qis__exp__body(%Array* %.paulis, double %angle, %Array* %.qubits) { +define dllexport void @__quantum__qis__exp__body(%Array* %.paulis, double %angle, %Array* %.qubits) { %paulis = bitcast %Array* %.paulis to %struct.QirArray* %qubits = bitcast %Array* %.qubits to %struct.QirArray* call void @quantum__qis__exp__body(%struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) ret void } -define void @__quantum__qis__exp__adj(%Array* %.paulis, double %angle, %Array* %.qubits) { +define dllexport void @__quantum__qis__exp__adj(%Array* %.paulis, double %angle, %Array* %.qubits) { %paulis = bitcast %Array* %.paulis to %struct.QirArray* %qubits = bitcast %Array* %.qubits to %struct.QirArray* call void @quantum__qis__exp__adj(%struct.QirArray* %paulis, double %angle, %struct.QirArray* %qubits) ret void } -define void @__quantum__qis__exp__ctl(%Array* %.ctls, {%Array*, double, %Array*}* %.args) { +define dllexport void @__quantum__qis__exp__ctl(%Array* %.ctls, {%Array*, double, %Array*}* %.args) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* %.ppaulis = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 0 @@ -97,7 +97,7 @@ define void @__quantum__qis__exp__ctl(%Array* %.ctls, {%Array*, double, %Array*} ret void } -define void @__quantum__qis__exp__ctladj(%Array* %.ctls, { %Array*, double, %Array* }* %.args) { +define dllexport void @__quantum__qis__exp__ctladj(%Array* %.ctls, { %Array*, double, %Array* }* %.args) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* %.ppaulis = getelementptr inbounds {%Array*, double, %Array*}, {%Array*, double, %Array*}* %.args, i32 0, i32 0 @@ -116,20 +116,20 @@ define void @__quantum__qis__exp__ctladj(%Array* %.ctls, { %Array*, double, %Arr ret void } -define void @__quantum__qis__h__body(%Qubit* %.q) { +define dllexport void @__quantum__qis__h__body(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__h__body(%class.QUBIT* %q) ret void } -define void @__quantum__qis__h__ctl(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__h__ctl(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__h__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define %Result* @__quantum__qis__measure__body(%Array* %.paulis, %Array* %.qubits) { +define dllexport %Result* @__quantum__qis__measure__body(%Array* %.paulis, %Array* %.qubits) { %paulis = bitcast %Array* %.paulis to %struct.QirArray* %qubits = bitcast %Array* %.qubits to %struct.QirArray* %r = call %class.RESULT* @quantum__qis__measure__body(%struct.QirArray* %paulis, %struct.QirArray* %qubits) @@ -137,21 +137,21 @@ define %Result* @__quantum__qis__measure__body(%Array* %.paulis, %Array* %.qubit ret %Result* %.r } -define void @__quantum__qis__r__body(%Pauli %.pauli, double %theta, %Qubit* %.q) { +define dllexport void @__quantum__qis__r__body(%Pauli %.pauli, double %theta, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %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(%Pauli %.pauli, double %theta, %Qubit* %.q) { +define dllexport void @__quantum__qis__r__adj(%Pauli %.pauli, double %theta, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %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, {%Pauli, double, %Qubit*}* %.args) { +define dllexport void @__quantum__qis__r__ctl(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* %.ppauli = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 0 @@ -169,7 +169,7 @@ define void @__quantum__qis__r__ctl(%Array* %.ctls, {%Pauli, double, %Qubit*}* % ret void } -define void @__quantum__qis__r__ctladj(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { +define dllexport void @__quantum__qis__r__ctladj(%Array* %.ctls, {%Pauli, double, %Qubit*}* %.args) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* %.ppauli = getelementptr inbounds {%Pauli, double, %Qubit*}, {%Pauli, double, %Qubit*}* %.args, i32 0, i32 0 @@ -187,91 +187,91 @@ define void @__quantum__qis__r__ctladj(%Array* %.ctls, {%Pauli, double, %Qubit*} ret void } -define void @__quantum__qis__s__body(%Qubit* %.q) { +define dllexport void @__quantum__qis__s__body(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__s__body(%class.QUBIT* %q) ret void } -define void @__quantum__qis__s__adj(%Qubit* %.q) { +define dllexport void @__quantum__qis__s__adj(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__s__adj(%class.QUBIT* %q) ret void } -define void @__quantum__qis__s__ctl(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__s__ctl(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__s__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define void @__quantum__qis__s__ctladj(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__s__ctladj(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__s__ctladj(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define void @__quantum__qis__t__body(%Qubit* %.q) { +define dllexport void @__quantum__qis__t__body(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__t__body(%class.QUBIT* %q) ret void } -define void @__quantum__qis__t__adj(%Qubit* %.q) { +define dllexport void @__quantum__qis__t__adj(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__t__adj(%class.QUBIT* %q) ret void } -define void @__quantum__qis__t__ctl(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__t__ctl(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__t__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define void @__quantum__qis__t__ctladj(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__t__ctladj(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__t__ctladj(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define void @__quantum__qis__x__body(%Qubit* %.q) { +define dllexport void @__quantum__qis__x__body(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__x__body(%class.QUBIT* %q) ret void } -define void @__quantum__qis__x__ctl(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__x__ctl(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__x__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define void @__quantum__qis__y__body(%Qubit* %.q) { +define dllexport void @__quantum__qis__y__body(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__y__body(%class.QUBIT* %q) ret void } -define void @__quantum__qis__y__ctl(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__y__ctl(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__y__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) ret void } -define void @__quantum__qis__z__body(%Qubit* %.q) { +define dllexport void @__quantum__qis__z__body(%Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__z__body(%class.QUBIT* %q) ret void } -define void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) { +define dllexport void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* call void @quantum__qis__z__ctl(%struct.QirArray* %ctls, %class.QUBIT* %q) diff --git a/src/QirRuntime/lib/Tracer/tracer-bridge.ll b/src/QirRuntime/lib/Tracer/tracer-bridge.ll index 740ad7970f9..22d39a98a5e 100644 --- a/src/QirRuntime/lib/Tracer/tracer-bridge.ll +++ b/src/QirRuntime/lib/Tracer/tracer-bridge.ll @@ -36,14 +36,14 @@ declare void @quantum__qis__apply_conditionally( ;=============================================================================== ; quantum__trc namespace implementations ; -define void @__quantum__qis__single_qubit_op(i32 %id, i32 %duration, %Qubit* %.q) +define dllexport void @__quantum__qis__single_qubit_op(i32 %id, i32 %duration, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* call void @quantum__qis__single_qubit_op(i32 %id, i32 %duration, %class.QUBIT* %q) ret void } -define void @__quantum__qis__single_qubit_op_ctl(i32 %id, i32 %duration, %Array* %.ctls, %Qubit* %.q) +define dllexport void @__quantum__qis__single_qubit_op_ctl(i32 %id, i32 %duration, %Array* %.ctls, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %ctls = bitcast %Array* %.ctls to %struct.QirArray* @@ -51,14 +51,14 @@ define void @__quantum__qis__single_qubit_op_ctl(i32 %id, i32 %duration, %Array* ret void } -define void @__quantum__qis__multi_qubit_op(i32 %id, i32 %duration, %Array* %.qs) +define dllexport void @__quantum__qis__multi_qubit_op(i32 %id, i32 %duration, %Array* %.qs) { %qs = bitcast %Array* %.qs to %struct.QirArray* call void @quantum__qis__multi_qubit_op(i32 %id, i32 %duration, %struct.QirArray* %qs) ret void } -define void @__quantum__qis__multi_qubit_op_ctl(i32 %id, i32 %duration, %Array* %.ctls, %Array* %.qs) +define dllexport void @__quantum__qis__multi_qubit_op_ctl(i32 %id, i32 %duration, %Array* %.ctls, %Array* %.qs) { %ctls = bitcast %Array* %.ctls to %struct.QirArray* %qs = bitcast %Array* %.qs to %struct.QirArray* @@ -66,13 +66,13 @@ define void @__quantum__qis__multi_qubit_op_ctl(i32 %id, i32 %duration, %Array* ret void } -define void @__quantum__qis__inject_barrier(i32 %id, i32 %duration) +define dllexport void @__quantum__qis__inject_barrier(i32 %id, i32 %duration) { call void @quantum__qis__inject_barrier(i32 %id, i32 %duration) ret void } -define %Result* @__quantum__qis__single_qubit_measure(i32 %id, i32 %duration, %Qubit* %.q) +define dllexport %Result* @__quantum__qis__single_qubit_measure(i32 %id, i32 %duration, %Qubit* %.q) { %q = bitcast %Qubit* %.q to %class.QUBIT* %r = call %class.RESULT* @quantum__qis__single_qubit_measure(i32 %id, i32 %duration, %class.QUBIT* %q) @@ -80,7 +80,7 @@ define %Result* @__quantum__qis__single_qubit_measure(i32 %id, i32 %duration, %Q ret %Result* %.r } -define %Result* @__quantum__qis__joint_measure(i32 %id, i32 %duration, %Array* %.qs) +define dllexport %Result* @__quantum__qis__joint_measure(i32 %id, i32 %duration, %Array* %.qs) { %qs = bitcast %Array* %.qs to %struct.QirArray* %r = call %class.RESULT* @quantum__qis__joint_measure(i32 %id, i32 %duration, %struct.QirArray* %qs) @@ -88,7 +88,7 @@ define %Result* @__quantum__qis__joint_measure(i32 %id, i32 %duration, %Array* % ret %Result* %.r } -define void @__quantum__qis__apply_conditionally( +define dllexport void @__quantum__qis__apply_conditionally( %Array* %.rs1, %Array* %.rs2, %Callable* %.clb_on_equal, %Callable* %.clb_on_different) { %rs1 = bitcast %Array* %.rs1 to %struct.QirArray* From ef1dfed063e8e889b5eaf6bed90e9f9d82351478 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 05:00:21 +0000 Subject: [PATCH 18/31] Update test linkage, ResultOne/Zero def --- src/QirRuntime/lib/QIR/context.cpp | 8 ++++---- src/QirRuntime/public/CoreTypes.hpp | 2 ++ src/QirRuntime/test/FullstateSimulator/CMakeLists.txt | 1 + src/QirRuntime/test/QIR-static/CMakeLists.txt | 1 + src/QirRuntime/test/unittests/CMakeLists.txt | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/QirRuntime/lib/QIR/context.cpp b/src/QirRuntime/lib/QIR/context.cpp index ff166a76f19..3d911d25c03 100644 --- a/src/QirRuntime/lib/QIR/context.cpp +++ b/src/QirRuntime/lib/QIR/context.cpp @@ -10,8 +10,8 @@ #include "allocationsTracker.hpp" // These two globals are used in QIR _directly_ so have to define them outside of the context. -extern "C" QIR_SHARED_API Result ResultOne = nullptr; -extern "C" QIR_SHARED_API Result ResultZero = nullptr; +Result ResultOne = nullptr; +Result ResultZero = nullptr; namespace Microsoft { @@ -46,8 +46,8 @@ namespace Quantum g_context->allocationsTracker->CheckForLeaks(); } - ResultOne = nullptr; - ResultZero = nullptr; + ::ResultOne = nullptr; + ::ResultZero = nullptr; g_context.reset(nullptr); } diff --git a/src/QirRuntime/public/CoreTypes.hpp b/src/QirRuntime/public/CoreTypes.hpp index 57f38a993e9..4bb047e88b4 100644 --- a/src/QirRuntime/public/CoreTypes.hpp +++ b/src/QirRuntime/public/CoreTypes.hpp @@ -27,6 +27,8 @@ typedef QUBIT* Qubit; class RESULT; typedef RESULT* Result; +extern "C" QIR_SHARED_API Result ResultOne; +extern "C" QIR_SHARED_API Result ResultZero; enum ResultValue { diff --git a/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt b/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt index 21fd019a272..6c111cdee40 100644 --- a/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt +++ b/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt @@ -20,6 +20,7 @@ target_include_directories(fullstate-simulator-tests PUBLIC "${public_includes}" "${PROJECT_SOURCE_DIR}/lib/QIR" ) +target_compile_definitions(fullstate-simulator-tests PRIVATE EXPORT_QIR_API) add_dependencies(fullstate-simulator-tests qir_test_simulator_target) install(TARGETS fullstate-simulator-tests RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin") diff --git a/src/QirRuntime/test/QIR-static/CMakeLists.txt b/src/QirRuntime/test/QIR-static/CMakeLists.txt index a0dc155fe43..6d144560779 100644 --- a/src/QirRuntime/test/QIR-static/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-static/CMakeLists.txt @@ -40,6 +40,7 @@ target_include_directories(qir-static-tests PUBLIC "${public_includes}" "${PROJECT_SOURCE_DIR}/lib/QIR" ) +target_compile_definitions(qir-static-tests PRIVATE EXPORT_QIR_API) add_dependencies(qir-static-tests qir_static_test_lib) install(TARGETS qir-static-tests RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin") diff --git a/src/QirRuntime/test/unittests/CMakeLists.txt b/src/QirRuntime/test/unittests/CMakeLists.txt index 6ee69ff4378..dbc96a627ca 100644 --- a/src/QirRuntime/test/unittests/CMakeLists.txt +++ b/src/QirRuntime/test/unittests/CMakeLists.txt @@ -23,5 +23,6 @@ target_include_directories(qir-runtime-unittests PUBLIC "${PROJECT_SOURCE_DIR}/lib/QSharpCore" "${PROJECT_SOURCE_DIR}/lib/Tracer" ) +target_compile_definitions(qir-runtime-unittests PRIVATE EXPORT_QIR_API) install(TARGETS qir-runtime-unittests RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin") add_unit_test(qir-runtime-unittests) From 91acd00c727e77c18dbcca1f93bd42a1789c4ccc Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 05:34:49 +0000 Subject: [PATCH 19/31] Try updating signature of ResultOne/Zero --- src/QirRuntime/lib/QIR/context.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/QirRuntime/lib/QIR/context.cpp b/src/QirRuntime/lib/QIR/context.cpp index 3d911d25c03..334d1b3c8a2 100644 --- a/src/QirRuntime/lib/QIR/context.cpp +++ b/src/QirRuntime/lib/QIR/context.cpp @@ -10,8 +10,8 @@ #include "allocationsTracker.hpp" // These two globals are used in QIR _directly_ so have to define them outside of the context. -Result ResultOne = nullptr; -Result ResultZero = nullptr; +extern "C" Result ResultOne = nullptr; +extern "C" Result ResultZero = nullptr; namespace Microsoft { @@ -46,8 +46,8 @@ namespace Quantum g_context->allocationsTracker->CheckForLeaks(); } - ::ResultOne = nullptr; - ::ResultZero = nullptr; + ResultOne = nullptr; + ResultZero = nullptr; g_context.reset(nullptr); } From ae615f5cb363499016b39df3a36c709afb78024a Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 06:01:01 +0000 Subject: [PATCH 20/31] Try using dllimport for external global IR --- src/QirRuntime/test/QIR-dynamic/qir-test-random.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll b/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll index cccc97ec31d..d83a3f082e4 100644 --- a/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll +++ b/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll @@ -4,8 +4,8 @@ %Qubit = type opaque %Array = type opaque -@ResultZero = external global %Result* -@ResultOne = external global %Result* +@ResultZero = external dllimport global %Result* +@ResultOne = external dllimport global %Result* @PauliI = constant i2 0 @PauliX = constant i2 1 @PauliY = constant i2 -1 From 4dd6875d5b641afe0802aa72622c2944cc8d3280 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 06:33:22 +0000 Subject: [PATCH 21/31] Fix tracer API export --- src/QirRuntime/lib/Tracer/tracer.hpp | 10 +++++----- src/QirRuntime/test/QIR-tracer/tracer-qir.ll | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/QirRuntime/lib/Tracer/tracer.hpp b/src/QirRuntime/lib/Tracer/tracer.hpp index 508d525e68d..59a2a8e7c9c 100644 --- a/src/QirRuntime/lib/Tracer/tracer.hpp +++ b/src/QirRuntime/lib/Tracer/tracer.hpp @@ -19,7 +19,7 @@ namespace Quantum /*================================================================================================================== Layer ==================================================================================================================*/ - struct Layer + struct QIR_SHARED_API Layer { // Start time of the layer. const Time startTime; @@ -43,7 +43,7 @@ namespace Quantum /*================================================================================================================== QubitState ==================================================================================================================*/ - struct QubitState + struct QIR_SHARED_API QubitState { // The last layer this qubit was used in, `INVALID` means the qubit haven't been used yet in any // operations of non-zero duration. @@ -60,7 +60,7 @@ namespace Quantum /*================================================================================================================== The tracer implements resource estimation. See readme in this folder for details. ==================================================================================================================*/ - class CTracer : public ISimulator + class QIR_SHARED_API CTracer : public ISimulator { // For now the tracer assumes no reuse of qubits. std::vector qubits; @@ -225,8 +225,8 @@ namespace Quantum void PrintLayerMetrics(std::ostream& out, const std::string& separator, bool printZeroMetrics) const; }; - std::shared_ptr CreateTracer(int preferredLayerDuration); - std::shared_ptr CreateTracer( + QIR_SHARED_API std::shared_ptr CreateTracer(int preferredLayerDuration); + QIR_SHARED_API std::shared_ptr CreateTracer( int preferredLayerDuration, const std::unordered_map& opNames); diff --git a/src/QirRuntime/test/QIR-tracer/tracer-qir.ll b/src/QirRuntime/test/QIR-tracer/tracer-qir.ll index edf24b70e7c..4200d8b7902 100644 --- a/src/QirRuntime/test/QIR-tracer/tracer-qir.ll +++ b/src/QirRuntime/test/QIR-tracer/tracer-qir.ll @@ -7,8 +7,8 @@ %Qubit = type opaque %String = type opaque -@ResultZero = external global %Result* -@ResultOne = external global %Result* +@ResultZero = external dllimport global %Result* +@ResultOne = external dllimport global %Result* @PauliI = constant i2 0 @PauliX = constant i2 1 @PauliY = constant i2 -1 From a5733e247ccb71073ce02bdc0d8678595c0e2b17 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 07:06:36 +0000 Subject: [PATCH 22/31] Put back cmake install runtime directives --- src/QirRuntime/lib/QIR/CMakeLists.txt | 1 + src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 1 + src/QirRuntime/lib/Tracer/CMakeLists.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index b96b16459b8..0233f5317a0 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -84,5 +84,6 @@ target_compile_definitions(qir PRIVATE EXPORT_QIR_API) set_property(TARGET qir PROPERTY POSITION_INDEPENDENT_CODE ON) install(TARGETS qir + RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index 75aba17048e..a8e2b662a38 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -46,6 +46,7 @@ target_compile_definitions(QSharpCore PRIVATE EXPORT_QIR_API) set_property(TARGET QSharpCore PROPERTY POSITION_INDEPENDENT_CODE ON) install(TARGETS QSharpCore + RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/lib/Tracer/CMakeLists.txt b/src/QirRuntime/lib/Tracer/CMakeLists.txt index 64f838b4d4f..b9ea696fb74 100644 --- a/src/QirRuntime/lib/Tracer/CMakeLists.txt +++ b/src/QirRuntime/lib/Tracer/CMakeLists.txt @@ -42,5 +42,6 @@ target_compile_definitions(qirtracer PRIVATE EXPORT_QIR_API) set_property(TARGET qirtracer PROPERTY POSITION_INDEPENDENT_CODE ON) install(TARGETS qirtracer + RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) From 94f66a52539399feefbf33053be56cbb40bcc1be Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 08:04:14 +0000 Subject: [PATCH 23/31] Return to plat specific handling of Result global --- src/QirRuntime/lib/QIR/context.cpp | 4 +- src/QirRuntime/public/CoreTypes.hpp | 2 - .../test/QIR-dynamic/CMakeLists.txt | 12 +- .../test/QIR-dynamic/qir-test-random-lnx.ll | 142 + ...-test-random.ll => qir-test-random-win.ll} | 0 src/QirRuntime/test/QIR-tracer/CMakeLists.txt | 20 +- .../test/QIR-tracer/tracer-qir-lnx.ll | 2019 +++++++++ .../{tracer-qir.ll => tracer-qir-win.ll} | 4038 ++++++++--------- 8 files changed, 4208 insertions(+), 2029 deletions(-) create mode 100644 src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll rename src/QirRuntime/test/QIR-dynamic/{qir-test-random.ll => qir-test-random-win.ll} (100%) create mode 100644 src/QirRuntime/test/QIR-tracer/tracer-qir-lnx.ll rename src/QirRuntime/test/QIR-tracer/{tracer-qir.ll => tracer-qir-win.ll} (98%) diff --git a/src/QirRuntime/lib/QIR/context.cpp b/src/QirRuntime/lib/QIR/context.cpp index 334d1b3c8a2..ff166a76f19 100644 --- a/src/QirRuntime/lib/QIR/context.cpp +++ b/src/QirRuntime/lib/QIR/context.cpp @@ -10,8 +10,8 @@ #include "allocationsTracker.hpp" // These two globals are used in QIR _directly_ so have to define them outside of the context. -extern "C" Result ResultOne = nullptr; -extern "C" Result ResultZero = nullptr; +extern "C" QIR_SHARED_API Result ResultOne = nullptr; +extern "C" QIR_SHARED_API Result ResultZero = nullptr; namespace Microsoft { diff --git a/src/QirRuntime/public/CoreTypes.hpp b/src/QirRuntime/public/CoreTypes.hpp index 4bb047e88b4..57f38a993e9 100644 --- a/src/QirRuntime/public/CoreTypes.hpp +++ b/src/QirRuntime/public/CoreTypes.hpp @@ -27,8 +27,6 @@ typedef QUBIT* Qubit; class RESULT; typedef RESULT* Result; -extern "C" QIR_SHARED_API Result ResultOne; -extern "C" QIR_SHARED_API Result ResultZero; enum ResultValue { diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index f46af9d6272..852caa18585 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -1,6 +1,12 @@ -set(TEST_FILES - qir-test-random -) +if (WIN32) + set(TEST_FILES + qir-test-random-win + ) +else() + set(TEST_FILES + qir-test-random-lnx + ) +endif() foreach(file ${TEST_FILES}) compile_from_qir(${file} "") # don't create a target per file diff --git a/src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll b/src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll new file mode 100644 index 00000000000..cccc97ec31d --- /dev/null +++ b/src/QirRuntime/test/QIR-dynamic/qir-test-random-lnx.ll @@ -0,0 +1,142 @@ + +%Result = type opaque +%Range = type { i64, i64, i64 } +%Qubit = 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__QuantumRandomNumberGenerator = alias i64 (), i64 ()* @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body + +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 void @__quantum__rt__array_update_alias_count(%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__H__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__h__body(%Qubit* %qb) + ret void +} + +declare void @__quantum__qis__h__body(%Qubit*) + +define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__h__body(%Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +declare void @__quantum__qis__h__ctl(%Array*, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__h__ctl(%Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define i64 @Microsoft__Quantum__Testing__QIR__QuantumRandomNumberGenerator__body() #0 { +entry: + %randomNumber = alloca i64 + store i64 0, i64* %randomNumber + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 1, %entry ], [ %8, %exiting__1 ] + %0 = icmp sle i64 %i, 64 + br i1 %0, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %q = call %Qubit* @__quantum__rt__qubit_allocate() + call void @__quantum__qis__h__body(%Qubit* %q) + %1 = load i64, i64* %randomNumber + %2 = shl i64 %1, 1 + store i64 %2, i64* %randomNumber + %3 = call %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %q) + %4 = load %Result*, %Result** @ResultOne + %5 = call i1 @__quantum__rt__result_equal(%Result* %3, %Result* %4) + br i1 %5, label %then0__1, label %continue__1 + +then0__1: ; preds = %body__1 + %6 = load i64, i64* %randomNumber + %7 = add i64 %6, 1 + store i64 %7, i64* %randomNumber + br label %continue__1 + +continue__1: ; preds = %then0__1, %body__1 + call void @__quantum__rt__qubit_release(%Qubit* %q) + call void @__quantum__rt__result_update_reference_count(%Result* %3, i64 -1) + br label %exiting__1 + +exiting__1: ; preds = %continue__1 + %8 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + %9 = load i64, i64* %randomNumber + ret i64 %9 +} + +declare %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare i1 @__quantum__rt__result_equal(%Result*, %Result*) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +attributes #0 = { "EntryPoint" } diff --git a/src/QirRuntime/test/QIR-dynamic/qir-test-random.ll b/src/QirRuntime/test/QIR-dynamic/qir-test-random-win.ll similarity index 100% rename from src/QirRuntime/test/QIR-dynamic/qir-test-random.ll rename to src/QirRuntime/test/QIR-dynamic/qir-test-random-win.ll diff --git a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt index 0998b416e7c..83fe7496ed4 100644 --- a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt @@ -1,5 +1,19 @@ +if (WIN32) + set(TEST_FILES + tracer-qir-win + ) +else() + set(TEST_FILES + tracer-qir-lnx + ) +endif() -compile_from_qir(tracer-qir tracer_qir) +foreach(file ${TEST_FILES}) + compile_from_qir(${file} "") # don't create a target per file + list(APPEND QIR_TESTS_LIBS ${QIR_UTILITY_LIB}) +endforeach() + +add_custom_target(tracer_qir_test_lib DEPENDS ${QIR_TESTS_LIBS}) #============================================================================== # The executable target for QIR tests triggers the custom actions to compile ll files @@ -10,7 +24,7 @@ add_executable(qir-tracer-tests ) target_link_libraries(qir-tracer-tests PUBLIC - ${QIR_UTILITY_LIB} # set by compile_from_qir + ${QIR_TESTS_LIBS} "-L${CMAKE_BINARY_DIR}/lib/QIR" -lqir "-L${CMAKE_BINARY_DIR}/lib/Tracer" @@ -22,7 +36,7 @@ target_include_directories(qir-tracer-tests PUBLIC "${public_includes}" "${PROJECT_SOURCE_DIR}/lib/Tracer" ) -add_dependencies(qir-tracer-tests tracer_qir) +add_dependencies(qir-tracer-tests tracer_qir_test_lib) install(TARGETS qir-tracer-tests RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin") add_unit_test(qir-tracer-tests) diff --git a/src/QirRuntime/test/QIR-tracer/tracer-qir-lnx.ll b/src/QirRuntime/test/QIR-tracer/tracer-qir-lnx.ll new file mode 100644 index 00000000000..ab33750832b --- /dev/null +++ b/src/QirRuntime/test/QIR-tracer/tracer-qir-lnx.ll @@ -0,0 +1,2019 @@ + +%Result = type opaque +%Range = type { i64, i64, i64 } +%Tuple = type opaque +%Array = type opaque +%Callable = type opaque +%Qubit = type opaque +%String = 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__Tracer__Delay = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__Tracer__Delay__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@Microsoft__Quantum__Intrinsic__X = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__ctladj__wrapper] +@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] +@Microsoft__Quantum__Intrinsic__Y = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__ctladj__wrapper] +@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] +@Microsoft__Quantum__Intrinsic__Z = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__ctladj__wrapper] +@PartialApplication__3 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__3__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@Microsoft__Quantum__Intrinsic__S = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__ctladj__wrapper] +@PartialApplication__4 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__4__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] + +define void @Microsoft__Quantum__Intrinsic__ApplyConditionallyIntrinsic__body(%Array* %measurementResults, %Array* %resultsValues, %Callable* %onEqualOp, %Callable* %onNonEqualOp) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %measurementResults, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %resultsValues, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onEqualOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onEqualOp, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onNonEqualOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onNonEqualOp, i64 1) + call void @__quantum__qis__apply_conditionally(%Array* %measurementResults, %Array* %resultsValues, %Callable* %onEqualOp, %Callable* %onNonEqualOp) + call void @__quantum__rt__array_update_alias_count(%Array* %measurementResults, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %resultsValues, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onEqualOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onEqualOp, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onNonEqualOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onNonEqualOp, i64 -1) + ret void +} + +declare void @__quantum__rt__array_update_alias_count(%Array*, i64) + +declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) + +declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) + +declare void @__quantum__qis__apply_conditionally(%Array*, %Array*, %Callable*, %Callable*) + +define void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %measurementResult, %Callable* %onResultZeroOp, %Callable* %onResultOneOp) { +entry: + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultZeroOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultZeroOp, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultOneOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultOneOp, i64 1) + %0 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %1 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 0) + %2 = bitcast i8* %1 to %Result** + store %Result* %measurementResult, %Result** %2 + %3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 0) + %5 = bitcast i8* %4 to %Result** + %6 = load %Result*, %Result** @ResultZero + store %Result* %6, %Result** %5 + call void @__quantum__qis__apply_conditionally(%Array* %0, %Array* %3, %Callable* %onResultZeroOp, %Callable* %onResultOneOp) + call void @__quantum__rt__result_update_reference_count(%Result* %measurementResult, i64 1) + call void @__quantum__rt__result_update_reference_count(%Result* %6, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultZeroOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultZeroOp, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultOneOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultOneOp, i64 -1) + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %7 = phi i64 [ 0, %entry ], [ %12, %exiting__1 ] + %8 = icmp sle i64 %7, 0 + br i1 %8, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %7) + %10 = bitcast i8* %9 to %Result** + %11 = load %Result*, %Result** %10 + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + br label %exiting__1 + +exiting__1: ; preds = %body__1 + %12 = add i64 %7, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + br label %header__2 + +header__2: ; preds = %exiting__2, %exit__1 + %13 = phi i64 [ 0, %exit__1 ], [ %18, %exiting__2 ] + %14 = icmp sle i64 %13, 0 + br i1 %14, label %body__2, label %exit__2 + +body__2: ; preds = %header__2 + %15 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 %13) + %16 = bitcast i8* %15 to %Result** + %17 = load %Result*, %Result** %16 + call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 -1) + br label %exiting__2 + +exiting__2: ; preds = %body__2 + %18 = add i64 %13, 1 + br label %header__2 + +exit__2: ; preds = %header__2 + call void @__quantum__rt__array_update_reference_count(%Array* %3, i64 -1) + ret void +} + +declare %Array* @__quantum__rt__array_create_1d(i32, i64) + +declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +declare void @__quantum__rt__array_update_reference_count(%Array*, i64) + +define void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %control, %Qubit* %target) { +entry: + %ctls = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls, i64 0) + %1 = bitcast i8* %0 to %Qubit** + store %Qubit* %control, %Qubit** %1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + br i1 true, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %target) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %target) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls, i64 -1) + ret void +} + +declare void @__quantum__qis__single_qubit_op_ctl(i64, i64, %Array*, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__CNOT__adj(%Qubit* %control, %Qubit* %target) { +entry: + call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %control, %Qubit* %target) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__CNOT__ctl(%Array* %ctls, { %Qubit*, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 0 + %control = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 1 + %target = load %Qubit*, %Qubit** %2 + %3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 0) + %5 = bitcast i8* %4 to %Qubit** + store %Qubit* %control, %Qubit** %5 + %ctls__1 = call %Array* @__quantum__rt__array_concatenate(%Array* %ctls, %Array* %3) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 1) + %6 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls__1) + %7 = icmp eq i64 %6, 1 + br i1 %7, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls__1, %Qubit* %target) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls__1, %Qubit* %target) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %3, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__1, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) + +declare i64 @__quantum__rt__array_get_size_1d(%Array*) + +define void @Microsoft__Quantum__Intrinsic__CNOT__ctladj(%Array* %__controlQubits__, { %Qubit*, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %1 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 0 + %control = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 1 + %target = load %Qubit*, %Qubit** %2 + %3 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %4 = bitcast %Tuple* %3 to { %Qubit*, %Qubit* }* + %5 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %4, i32 0, i32 0 + %6 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %4, i32 0, i32 1 + store %Qubit* %control, %Qubit** %5 + store %Qubit* %target, %Qubit** %6 + call void @Microsoft__Quantum__Intrinsic__CNOT__ctl(%Array* %__controlQubits__, { %Qubit*, %Qubit* }* %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 %Tuple* @__quantum__rt__tuple_create(i64) + +declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) + +define void @Microsoft__Quantum__Intrinsic__H__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb) + ret void +} + +declare void @__quantum__qis__single_qubit_op(i64, i64, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qb) { +entry: + %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb) + ret %Result* %0 +} + +declare %Result* @__quantum__qis__single_qubit_measure(i64, i64, %Qubit*) + +define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %paulis, %Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = load %Result*, %Result** @ResultOne + %res = alloca %Result* + store %Result* %0, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %0, i64 1) + %haveY = alloca i1 + store i1 false, i1* %haveY + %1 = call i64 @__quantum__rt__array_get_size_1d(%Array* %paulis) + %2 = sub i64 %1, 1 + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %15, %exiting__1 ] + %3 = icmp sle i64 %i, %2 + br i1 %3, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %5 = bitcast i8* %4 to i2* + %6 = load i2, i2* %5 + %7 = load i2, i2* @PauliY + %8 = icmp eq i2 %6, %7 + %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %10 = bitcast i8* %9 to i2* + %11 = load i2, i2* %10 + %12 = load i2, i2* @PauliI + %13 = icmp eq i2 %11, %12 + %14 = or i1 %8, %13 + br i1 %14, label %then0__1, label %continue__1 + +then0__1: ; preds = %body__1 + store i1 true, i1* %haveY + br label %continue__1 + +continue__1: ; preds = %then0__1, %body__1 + br label %exiting__1 + +exiting__1: ; preds = %continue__1 + %15 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + %16 = load i1, i1* %haveY + br i1 %16, label %then0__2, label %test1__1 + +then0__2: ; preds = %exit__1 + %17 = call %Result* @__quantum__qis__joint_measure(i64 106, i64 1, %Array* %qubits) + call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 1) + store %Result* %17, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %0, i64 -1) + br label %continue__2 + +test1__1: ; preds = %exit__1 + %18 = icmp sgt i64 %1, 2 + br i1 %18, label %then1__1, label %test2__1 + +then1__1: ; preds = %test1__1 + %19 = call %Result* @__quantum__qis__joint_measure(i64 107, i64 1, %Array* %qubits) + call void @__quantum__rt__result_update_reference_count(%Result* %19, i64 1) + %20 = load %Result*, %Result** %res + store %Result* %19, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %19, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %20, i64 -1) + br label %continue__2 + +test2__1: ; preds = %test1__1 + %21 = icmp eq i64 %1, 1 + br i1 %21, label %then2__1, label %test3__1 + +then2__1: ; preds = %test2__1 + %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %23 = bitcast i8* %22 to i2* + %24 = load i2, i2* %23 + %25 = load i2, i2* @PauliX + %26 = icmp eq i2 %24, %25 + br i1 %26, label %then0__3, label %else__1 + +then0__3: ; preds = %then2__1 + %27 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %28 = bitcast i8* %27 to %Qubit** + %qb = load %Qubit*, %Qubit** %28 + %29 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb) + call void @__quantum__rt__result_update_reference_count(%Result* %29, i64 1) + %30 = load %Result*, %Result** %res + store %Result* %29, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %29, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %30, i64 -1) + br label %continue__3 + +else__1: ; preds = %then2__1 + %31 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %32 = bitcast i8* %31 to %Qubit** + %qb__1 = load %Qubit*, %Qubit** %32 + %33 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__1) + call void @__quantum__rt__result_update_reference_count(%Result* %33, i64 1) + %34 = load %Result*, %Result** %res + store %Result* %33, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %34, i64 -1) + br label %continue__3 + +continue__3: ; preds = %else__1, %then0__3 + br label %continue__2 + +test3__1: ; preds = %test2__1 + %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %36 = bitcast i8* %35 to i2* + %37 = load i2, i2* %36 + %38 = load i2, i2* @PauliX + %39 = icmp eq i2 %37, %38 + %40 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %41 = bitcast i8* %40 to i2* + %42 = load i2, i2* %41 + %43 = load i2, i2* @PauliX + %44 = icmp eq i2 %42, %43 + %45 = and i1 %39, %44 + br i1 %45, label %then3__1, label %test4__1 + +then3__1: ; preds = %test3__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %46 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %46, i64 1) + %47 = load %Result*, %Result** %res + store %Result* %46, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %46, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %47, i64 -1) + br label %continue__2 + +test4__1: ; preds = %test3__1 + %48 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %49 = bitcast i8* %48 to i2* + %50 = load i2, i2* %49 + %51 = load i2, i2* @PauliX + %52 = icmp eq i2 %50, %51 + %53 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %54 = bitcast i8* %53 to i2* + %55 = load i2, i2* %54 + %56 = load i2, i2* @PauliZ + %57 = icmp eq i2 %55, %56 + %58 = and i1 %52, %57 + br i1 %58, label %then4__1, label %test5__1 + +then4__1: ; preds = %test4__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %59 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 1) + %60 = load %Result*, %Result** %res + store %Result* %59, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %60, i64 -1) + br label %continue__2 + +test5__1: ; preds = %test4__1 + %61 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %62 = bitcast i8* %61 to i2* + %63 = load i2, i2* %62 + %64 = load i2, i2* @PauliZ + %65 = icmp eq i2 %63, %64 + %66 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %67 = bitcast i8* %66 to i2* + %68 = load i2, i2* %67 + %69 = load i2, i2* @PauliX + %70 = icmp eq i2 %68, %69 + %71 = and i1 %65, %70 + br i1 %71, label %then5__1, label %test6__1 + +then5__1: ; preds = %test5__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %72 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %72, i64 1) + %73 = load %Result*, %Result** %res + store %Result* %72, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %72, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %73, i64 -1) + br label %continue__2 + +test6__1: ; preds = %test5__1 + %74 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %75 = bitcast i8* %74 to i2* + %76 = load i2, i2* %75 + %77 = load i2, i2* @PauliZ + %78 = icmp eq i2 %76, %77 + %79 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %80 = bitcast i8* %79 to i2* + %81 = load i2, i2* %80 + %82 = load i2, i2* @PauliZ + %83 = icmp eq i2 %81, %82 + %84 = and i1 %78, %83 + br i1 %84, label %then6__1, label %continue__2 + +then6__1: ; preds = %test6__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %85 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %85, i64 1) + %86 = load %Result*, %Result** %res + store %Result* %85, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %85, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %86, i64 -1) + br label %continue__2 + +continue__2: ; preds = %then6__1, %test6__1, %then5__1, %then4__1, %then3__1, %continue__3, %then1__1, %then0__2 + %87 = load %Result*, %Result** %res + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %87 +} + +declare %Result* @__quantum__qis__joint_measure(i64, i64, %Array*) + +define void @Microsoft__Quantum__Intrinsic__Rx__body(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rx__adj(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rx__ctl(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rx__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__body(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__adj(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__ctl(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__body(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__adj(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__ctl(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +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__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define %Tuple* @Microsoft__Quantum__Core__Attribute__body() { +entry: + ret %Tuple* null +} + +define %Tuple* @Microsoft__Quantum__Core__EntryPoint__body() { +entry: + ret %Tuple* null +} + +define %Tuple* @Microsoft__Quantum__Core__Inline__body() { +entry: + ret %Tuple* null +} + +define %Result* @Microsoft__Quantum__Instructions__Mx__body(%Qubit* %qb) { +entry: + %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mxx__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mxz__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mz__body(%Qubit* %qb) { +entry: + %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mzx__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mzz__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define void @Microsoft__Quantum__Instructions__Sx__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 17, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sx__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 17, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sx__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 18, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sx__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 18, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 13, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 13, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 14, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 14, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Testing__Tracer__Delay__body(%Callable* %op, %Qubit* %arg, %Tuple* %aux) { +entry: + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %op, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %op, i64 1) + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %Qubit* }* + %2 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %1, i32 0, i32 0 + store %Qubit* %arg, %Qubit** %2 + call void @__quantum__rt__callable_invoke(%Callable* %op, %Tuple* %0, %Tuple* null) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %op, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %op, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %0, i64 -1) + ret void +} + +declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) + +define void @Microsoft__Quantum__Testing__Tracer__TestCoreIntrinsics__body() { +entry: + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 3) + 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 0) + %1 = bitcast i8* %0 to %Qubit** + %qb = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %3 = bitcast i8* %2 to %Qubit** + %qb__1 = load %Qubit*, %Qubit** %3 + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb__1) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %5 = bitcast i8* %4 to %Qubit** + %qb__2 = load %Qubit*, %Qubit** %5 + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb__2) + %6 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %7 = bitcast i8* %6 to %Qubit** + %qb__3 = load %Qubit*, %Qubit** %7 + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb__3) + %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %9 = bitcast i8* %8 to %Qubit** + %10 = load %Qubit*, %Qubit** %9 + %11 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %12 = bitcast i8* %11 to %Qubit** + %13 = load %Qubit*, %Qubit** %12 + call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %10, %Qubit* %13) + %14 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %15 = bitcast i8* %14 to %Qubit** + %qb__4 = load %Qubit*, %Qubit** %15 + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__4) + %16 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %17 = bitcast i8* %16 to %Qubit** + %qb__5 = load %Qubit*, %Qubit** %17 + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb__5) + %18 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %19 = bitcast i8* %18 to %Qubit** + %qb__6 = load %Qubit*, %Qubit** %19 + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb__6) + %20 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %21 = bitcast i8* %20 to %Qubit** + %qb__7 = load %Qubit*, %Qubit** %21 + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb__7) + %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %23 = bitcast i8* %22 to %Qubit** + %qb__9 = load %Qubit*, %Qubit** %23 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__9) + call void @__quantum__qis__inject_barrier(i64 42, i64 0) + %24 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %25 = bitcast i8* %24 to %Qubit** + %qb__11 = load %Qubit*, %Qubit** %25 + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb__11) + %26 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %27 = bitcast i8* %26 to %Qubit** + %qb__13 = load %Qubit*, %Qubit** %27 + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb__13) + %28 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %29 = bitcast i8* %28 to %Qubit** + %qb__15 = load %Qubit*, %Qubit** %29 + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb__15) + %30 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %31 = bitcast i8* %30 to %Qubit** + %qb__17 = load %Qubit*, %Qubit** %31 + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb__17) + %32 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %33 = bitcast i8* %32 to %Qubit** + %34 = load %Qubit*, %Qubit** %33 + %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %36 = bitcast i8* %35 to %Qubit** + %37 = load %Qubit*, %Qubit** %36 + call void @Microsoft__Quantum__Intrinsic__CNOT__adj(%Qubit* %34, %Qubit* %37) + %38 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %39 = bitcast i8* %38 to %Qubit** + %qb__19 = load %Qubit*, %Qubit** %39 + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__19) + %40 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %41 = bitcast i8* %40 to %Qubit** + %qb__20 = load %Qubit*, %Qubit** %41 + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb__20) + %42 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %43 = bitcast i8* %42 to %Qubit** + %qb__21 = load %Qubit*, %Qubit** %43 + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb__21) + %44 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %45 = bitcast i8* %44 to %Qubit** + %qb__22 = load %Qubit*, %Qubit** %45 + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb__22) + %46 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %47 = bitcast i8* %46 to %Qubit** + %qb__24 = load %Qubit*, %Qubit** %47 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__24) + %c = call %Qubit* @__quantum__rt__qubit_allocate() + %ctls = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %48 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls, i64 0) + %49 = bitcast i8* %48 to %Qubit** + store %Qubit* %c, %Qubit** %49 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %50 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %51 = bitcast i8* %50 to %Qubit** + %qb__26 = load %Qubit*, %Qubit** %51 + br i1 true, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %qb__26) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %qb__26) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls, i64 -1) + %ctls__1 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %52 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__1, i64 0) + %53 = bitcast i8* %52 to %Qubit** + store %Qubit* %c, %Qubit** %53 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 1) + %54 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %55 = bitcast i8* %54 to %Qubit** + %qb__27 = load %Qubit*, %Qubit** %55 + br i1 true, label %then0__2, label %else__2 + +then0__2: ; preds = %continue__1 + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %ctls__1, %Qubit* %qb__27) + br label %continue__2 + +else__2: ; preds = %continue__1 + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %ctls__1, %Qubit* %qb__27) + br label %continue__2 + +continue__2: ; preds = %else__2, %then0__2 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__1, i64 -1) + %ctls__2 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %56 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__2, i64 0) + %57 = bitcast i8* %56 to %Qubit** + store %Qubit* %c, %Qubit** %57 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__2, i64 1) + %58 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %59 = bitcast i8* %58 to %Qubit** + %qb__28 = load %Qubit*, %Qubit** %59 + br i1 true, label %then0__3, label %else__3 + +then0__3: ; preds = %continue__2 + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %ctls__2, %Qubit* %qb__28) + br label %continue__3 + +else__3: ; preds = %continue__2 + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %ctls__2, %Qubit* %qb__28) + br label %continue__3 + +continue__3: ; preds = %else__3, %then0__3 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__2, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__2, i64 -1) + %ctls__3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %60 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__3, i64 0) + %61 = bitcast i8* %60 to %Qubit** + store %Qubit* %c, %Qubit** %61 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__3, i64 1) + %62 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %63 = bitcast i8* %62 to %Qubit** + %qb__29 = load %Qubit*, %Qubit** %63 + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %ctls__3, %Qubit* %qb__29) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__3, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__3, i64 -1) + %ctls__4 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %64 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__4, i64 0) + %65 = bitcast i8* %64 to %Qubit** + store %Qubit* %c, %Qubit** %65 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__4, i64 1) + %66 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %67 = bitcast i8* %66 to %Qubit** + %qb__30 = load %Qubit*, %Qubit** %67 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls__4, %Qubit* %qb__30) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__4, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__4, i64 -1) + %ctls__5 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %68 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__5, i64 0) + %69 = bitcast i8* %68 to %Qubit** + store %Qubit* %c, %Qubit** %69 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__5, i64 1) + %70 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %71 = bitcast i8* %70 to %Qubit** + %qb__31 = load %Qubit*, %Qubit** %71 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls__5, %Qubit* %qb__31) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__5, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__5, i64 -1) + %ctls__6 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__6, i64 0) + %73 = bitcast i8* %72 to %Qubit** + store %Qubit* %c, %Qubit** %73 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__6, i64 1) + %74 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %75 = bitcast i8* %74 to %Qubit** + %qb__32 = load %Qubit*, %Qubit** %75 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls__6, %Qubit* %qb__32) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__6, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__6, i64 -1) + %ctls__7 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %76 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__7, i64 0) + %77 = bitcast i8* %76 to %Qubit** + store %Qubit* %c, %Qubit** %77 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 1) + %78 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %79 = bitcast i8* %78 to %Qubit** + %qb__33 = load %Qubit*, %Qubit** %79 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls__7, %Qubit* %qb__33) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__7, i64 -1) + %ctls__9 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %80 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__9, i64 0) + %81 = bitcast i8* %80 to %Qubit** + store %Qubit* %c, %Qubit** %81 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 1) + %82 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %83 = bitcast i8* %82 to %Qubit** + %qb__35 = load %Qubit*, %Qubit** %83 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls__9, %Qubit* %qb__35) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__9, i64 -1) + call void @__quantum__rt__qubit_release(%Qubit* %c) + %cc = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %84 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %85 = bitcast i8* %84 to %Qubit** + %qb__37 = load %Qubit*, %Qubit** %85 + %86 = call i64 @__quantum__rt__array_get_size_1d(%Array* %cc) + %87 = icmp eq i64 %86, 1 + br i1 %87, label %then0__4, label %else__4 + +then0__4: ; preds = %continue__3 + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %cc, %Qubit* %qb__37) + br label %continue__4 + +else__4: ; preds = %continue__3 + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %cc, %Qubit* %qb__37) + br label %continue__4 + +continue__4: ; preds = %else__4, %then0__4 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %88 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %89 = bitcast i8* %88 to %Qubit** + %qb__38 = load %Qubit*, %Qubit** %89 + %90 = icmp eq i64 %86, 1 + br i1 %90, label %then0__5, label %else__5 + +then0__5: ; preds = %continue__4 + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %cc, %Qubit* %qb__38) + br label %continue__5 + +else__5: ; preds = %continue__4 + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %cc, %Qubit* %qb__38) + br label %continue__5 + +continue__5: ; preds = %else__5, %then0__5 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %91 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %92 = bitcast i8* %91 to %Qubit** + %qb__39 = load %Qubit*, %Qubit** %92 + %93 = icmp eq i64 %86, 1 + br i1 %93, label %then0__6, label %else__6 + +then0__6: ; preds = %continue__5 + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %cc, %Qubit* %qb__39) + br label %continue__6 + +else__6: ; preds = %continue__5 + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %cc, %Qubit* %qb__39) + br label %continue__6 + +continue__6: ; preds = %else__6, %then0__6 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %94 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %95 = bitcast i8* %94 to %Qubit** + %qb__40 = load %Qubit*, %Qubit** %95 + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %cc, %Qubit* %qb__40) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %96 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %97 = bitcast i8* %96 to %Qubit** + %qb__41 = load %Qubit*, %Qubit** %97 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %cc, %Qubit* %qb__41) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %98 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %99 = bitcast i8* %98 to %Qubit** + %qb__42 = load %Qubit*, %Qubit** %99 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %cc, %Qubit* %qb__42) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %100 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %101 = bitcast i8* %100 to %Qubit** + %qb__43 = load %Qubit*, %Qubit** %101 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %cc, %Qubit* %qb__43) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %102 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %103 = bitcast i8* %102 to %Qubit** + %qb__44 = load %Qubit*, %Qubit** %103 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %cc, %Qubit* %qb__44) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %104 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %105 = bitcast i8* %104 to %Qubit** + %qb__46 = load %Qubit*, %Qubit** %105 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %cc, %Qubit* %qb__46) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__qubit_release_array(%Array* %cc) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %cc, 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 %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare void @__quantum__qis__inject_barrier(i64, i64) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__qubit_release_array(%Array*) + +define void @Microsoft__Quantum__Testing__Tracer__TestMeasurements__body() { +entry: + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 6) + 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 0) + %1 = bitcast i8* %0 to %Qubit** + %qb = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %3 = bitcast i8* %2 to %Qubit** + %qb__2 = load %Qubit*, %Qubit** %3 + %r0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__2) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %5 = bitcast i8* %4 to %Qubit** + %qb__4 = load %Qubit*, %Qubit** %5 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__4) + %6 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %7 = bitcast i8* %6 to %Qubit** + %8 = load %Qubit*, %Qubit** %7 + %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %10 = bitcast i8* %9 to %Qubit** + %11 = load %Qubit*, %Qubit** %10 + call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %8, %Qubit* %11) + %qs12 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 2) + %12 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) + %13 = bitcast i8* %12 to %Qubit** + %14 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 1) + %15 = bitcast i8* %14 to %Qubit** + %16 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %17 = bitcast i8* %16 to %Qubit** + %18 = load %Qubit*, %Qubit** %17 + %19 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %20 = bitcast i8* %19 to %Qubit** + %21 = load %Qubit*, %Qubit** %20 + store %Qubit* %18, %Qubit** %13 + store %Qubit* %21, %Qubit** %15 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %paulis = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 2) + %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %23 = bitcast i8* %22 to i2* + %24 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %25 = bitcast i8* %24 to i2* + %26 = load i2, i2* @PauliY + %27 = load i2, i2* @PauliX + store i2 %26, i2* %23 + store i2 %27, i2* %25 + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %28 = load %Result*, %Result** @ResultOne + %res = alloca %Result* + store %Result* %28, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 1) + %haveY = alloca i1 + store i1 false, i1* %haveY + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %41, %exiting__1 ] + %29 = icmp sle i64 %i, 1 + br i1 %29, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %30 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %31 = bitcast i8* %30 to i2* + %32 = load i2, i2* %31 + %33 = load i2, i2* @PauliY + %34 = icmp eq i2 %32, %33 + %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %36 = bitcast i8* %35 to i2* + %37 = load i2, i2* %36 + %38 = load i2, i2* @PauliI + %39 = icmp eq i2 %37, %38 + %40 = or i1 %34, %39 + br i1 %40, label %then0__1, label %continue__1 + +then0__1: ; preds = %body__1 + store i1 true, i1* %haveY + br label %continue__1 + +continue__1: ; preds = %then0__1, %body__1 + br label %exiting__1 + +exiting__1: ; preds = %continue__1 + %41 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + %42 = load i1, i1* %haveY + br i1 %42, label %then0__2, label %test1__1 + +then0__2: ; preds = %exit__1 + %43 = call %Result* @__quantum__qis__joint_measure(i64 106, i64 1, %Array* %qs12) + call void @__quantum__rt__result_update_reference_count(%Result* %43, i64 1) + store %Result* %43, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %43, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + br label %continue__2 + +test1__1: ; preds = %exit__1 + br i1 false, label %then1__1, label %test2__1 + +then1__1: ; preds = %test1__1 + %44 = call %Result* @__quantum__qis__joint_measure(i64 107, i64 1, %Array* %qs12) + call void @__quantum__rt__result_update_reference_count(%Result* %44, i64 1) + %45 = load %Result*, %Result** %res + store %Result* %44, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %44, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %45, i64 -1) + br label %continue__2 + +test2__1: ; preds = %test1__1 + br i1 false, label %then2__1, label %test3__1 + +then2__1: ; preds = %test2__1 + %46 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %47 = bitcast i8* %46 to i2* + %48 = load i2, i2* %47 + %49 = load i2, i2* @PauliX + %50 = icmp eq i2 %48, %49 + br i1 %50, label %then0__3, label %else__1 + +then0__3: ; preds = %then2__1 + %51 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) + %52 = bitcast i8* %51 to %Qubit** + %qb__6 = load %Qubit*, %Qubit** %52 + %53 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb__6) + call void @__quantum__rt__result_update_reference_count(%Result* %53, i64 1) + %54 = load %Result*, %Result** %res + store %Result* %53, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %53, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %54, i64 -1) + br label %continue__3 + +else__1: ; preds = %then2__1 + %55 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) + %56 = bitcast i8* %55 to %Qubit** + %qb__7 = load %Qubit*, %Qubit** %56 + %57 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__7) + call void @__quantum__rt__result_update_reference_count(%Result* %57, i64 1) + %58 = load %Result*, %Result** %res + store %Result* %57, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %57, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %58, i64 -1) + br label %continue__3 + +continue__3: ; preds = %else__1, %then0__3 + br label %continue__2 + +test3__1: ; preds = %test2__1 + %59 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %60 = bitcast i8* %59 to i2* + %61 = load i2, i2* %60 + %62 = load i2, i2* @PauliX + %63 = icmp eq i2 %61, %62 + %64 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %65 = bitcast i8* %64 to i2* + %66 = load i2, i2* %65 + %67 = load i2, i2* @PauliX + %68 = icmp eq i2 %66, %67 + %69 = and i1 %63, %68 + br i1 %69, label %then3__1, label %test4__1 + +then3__1: ; preds = %test3__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %70 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %70, i64 1) + %71 = load %Result*, %Result** %res + store %Result* %70, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %70, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %71, i64 -1) + br label %continue__2 + +test4__1: ; preds = %test3__1 + %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %73 = bitcast i8* %72 to i2* + %74 = load i2, i2* %73 + %75 = load i2, i2* @PauliX + %76 = icmp eq i2 %74, %75 + %77 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %78 = bitcast i8* %77 to i2* + %79 = load i2, i2* %78 + %80 = load i2, i2* @PauliZ + %81 = icmp eq i2 %79, %80 + %82 = and i1 %76, %81 + br i1 %82, label %then4__1, label %test5__1 + +then4__1: ; preds = %test4__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %83 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %83, i64 1) + %84 = load %Result*, %Result** %res + store %Result* %83, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %83, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %84, i64 -1) + br label %continue__2 + +test5__1: ; preds = %test4__1 + %85 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %86 = bitcast i8* %85 to i2* + %87 = load i2, i2* %86 + %88 = load i2, i2* @PauliZ + %89 = icmp eq i2 %87, %88 + %90 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %91 = bitcast i8* %90 to i2* + %92 = load i2, i2* %91 + %93 = load i2, i2* @PauliX + %94 = icmp eq i2 %92, %93 + %95 = and i1 %89, %94 + br i1 %95, label %then5__1, label %test6__1 + +then5__1: ; preds = %test5__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %96 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %96, i64 1) + %97 = load %Result*, %Result** %res + store %Result* %96, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %96, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %97, i64 -1) + br label %continue__2 + +test6__1: ; preds = %test5__1 + %98 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %99 = bitcast i8* %98 to i2* + %100 = load i2, i2* %99 + %101 = load i2, i2* @PauliZ + %102 = icmp eq i2 %100, %101 + %103 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %104 = bitcast i8* %103 to i2* + %105 = load i2, i2* %104 + %106 = load i2, i2* @PauliZ + %107 = icmp eq i2 %105, %106 + %108 = and i1 %102, %107 + br i1 %108, label %then6__1, label %continue__2 + +then6__1: ; preds = %test6__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %109 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %109, i64 1) + %110 = load %Result*, %Result** %res + store %Result* %109, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %109, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %110, i64 -1) + br label %continue__2 + +continue__2: ; preds = %then6__1, %test6__1, %then5__1, %then4__1, %then3__1, %continue__3, %then1__1, %then0__2 + %r12 = load %Result*, %Result** %res + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %paulis, i64 -1) + %111 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %112 = bitcast %Tuple* %111 to { %Callable*, %Callable*, %Qubit* }* + %113 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 0 + %114 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 1 + %115 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 2 + %116 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %117 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__X, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %118 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 3) + %119 = bitcast i8* %118 to %Qubit** + %120 = load %Qubit*, %Qubit** %119 + store %Callable* %116, %Callable** %113 + store %Callable* %117, %Callable** %114 + store %Qubit* %120, %Qubit** %115 + %121 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %111) + %122 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %123 = bitcast %Tuple* %122 to { %Callable*, %Callable*, %Qubit* }* + %124 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 0 + %125 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 1 + %126 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 2 + %127 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %128 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__Y, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %129 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 3) + %130 = bitcast i8* %129 to %Qubit** + %131 = load %Qubit*, %Qubit** %130 + store %Callable* %127, %Callable** %124 + store %Callable* %128, %Callable** %125 + store %Qubit* %131, %Qubit** %126 + %132 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %122) + call void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %r0, %Callable* %121, %Callable* %132) + %133 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %134 = bitcast %Tuple* %133 to { %Callable*, %Callable*, %Qubit* }* + %135 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 0 + %136 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 1 + %137 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 2 + %138 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %139 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__Z, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %140 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 4) + %141 = bitcast i8* %140 to %Qubit** + %142 = load %Qubit*, %Qubit** %141 + store %Callable* %138, %Callable** %135 + store %Callable* %139, %Callable** %136 + store %Qubit* %142, %Qubit** %137 + %143 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__3, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %133) + %144 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %145 = bitcast %Tuple* %144 to { %Callable*, %Callable*, %Qubit* }* + %146 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 0 + %147 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 1 + %148 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 2 + %149 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %150 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__S, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %151 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 4) + %152 = bitcast i8* %151 to %Qubit** + %153 = load %Qubit*, %Qubit** %152 + store %Callable* %149, %Callable** %146 + store %Callable* %150, %Callable** %147 + store %Qubit* %153, %Qubit** %148 + %154 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__4, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %144) + call void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %r12, %Callable* %143, %Callable* %154) + %155 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 5) + %156 = bitcast i8* %155 to %Qubit** + %qb__8 = load %Qubit*, %Qubit** %156 + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__8) + 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_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %r0, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %r12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %121, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %121, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %132, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %132, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %143, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %143, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %154, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %154, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Testing__Tracer__Delay__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Callable*, %Qubit*, %Tuple* }* + %1 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 1 + %3 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 2 + %4 = load %Callable*, %Callable** %1 + %5 = load %Qubit*, %Qubit** %2 + %6 = load %Tuple*, %Tuple** %3 + call void @Microsoft__Quantum__Testing__Tracer__Delay__body(%Callable* %4, %Qubit* %5, %Tuple* %6) + ret void +} + +declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__ctladj(%Array* %3, %Qubit* %4) + ret void +} + +define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %4, 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*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %4, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__ctladj(%Array* %3, %Qubit* %4) + 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*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__ctladj(%Array* %3, %Qubit* %4) + ret void +} + +define void @Lifted__PartialApplication__3__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__ctladj(%Array* %3, %Qubit* %4) + ret void +} + +define void @Lifted__PartialApplication__4__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @MemoryManagement__2__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %4, 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*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %4, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) + +define { %String* }* @Microsoft__Quantum__Targeting__TargetInstruction__body(%String* %__Item1__) { +entry: + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %String* }* + %2 = getelementptr inbounds { %String* }, { %String* }* %1, i32 0, i32 0 + store %String* %__Item1__, %String** %2 + call void @__quantum__rt__string_update_reference_count(%String* %__Item1__, i64 1) + ret { %String* }* %1 +} + +declare void @__quantum__rt__string_update_reference_count(%String*, i64) + +declare void @__quantum__rt__tuple_update_alias_count(%Tuple*, i64) diff --git a/src/QirRuntime/test/QIR-tracer/tracer-qir.ll b/src/QirRuntime/test/QIR-tracer/tracer-qir-win.ll similarity index 98% rename from src/QirRuntime/test/QIR-tracer/tracer-qir.ll rename to src/QirRuntime/test/QIR-tracer/tracer-qir-win.ll index 4200d8b7902..c53abaa2d2e 100644 --- a/src/QirRuntime/test/QIR-tracer/tracer-qir.ll +++ b/src/QirRuntime/test/QIR-tracer/tracer-qir-win.ll @@ -1,2019 +1,2019 @@ - -%Result = type opaque -%Range = type { i64, i64, i64 } -%Tuple = type opaque -%Array = type opaque -%Callable = type opaque -%Qubit = type opaque -%String = type opaque - -@ResultZero = external dllimport global %Result* -@ResultOne = external dllimport 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__Tracer__Delay = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__Tracer__Delay__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] -@Microsoft__Quantum__Intrinsic__X = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__ctladj__wrapper] -@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] -@Microsoft__Quantum__Intrinsic__Y = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__ctladj__wrapper] -@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] -@Microsoft__Quantum__Intrinsic__Z = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__ctladj__wrapper] -@PartialApplication__3 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__3__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] -@Microsoft__Quantum__Intrinsic__S = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__ctladj__wrapper] -@PartialApplication__4 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__4__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] - -define void @Microsoft__Quantum__Intrinsic__ApplyConditionallyIntrinsic__body(%Array* %measurementResults, %Array* %resultsValues, %Callable* %onEqualOp, %Callable* %onNonEqualOp) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %measurementResults, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %resultsValues, i64 1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onEqualOp, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onEqualOp, i64 1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onNonEqualOp, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onNonEqualOp, i64 1) - call void @__quantum__qis__apply_conditionally(%Array* %measurementResults, %Array* %resultsValues, %Callable* %onEqualOp, %Callable* %onNonEqualOp) - call void @__quantum__rt__array_update_alias_count(%Array* %measurementResults, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %resultsValues, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onEqualOp, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onEqualOp, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onNonEqualOp, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onNonEqualOp, i64 -1) - ret void -} - -declare void @__quantum__rt__array_update_alias_count(%Array*, i64) - -declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) - -declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) - -declare void @__quantum__qis__apply_conditionally(%Array*, %Array*, %Callable*, %Callable*) - -define void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %measurementResult, %Callable* %onResultZeroOp, %Callable* %onResultOneOp) { -entry: - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultZeroOp, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultZeroOp, i64 1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultOneOp, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultOneOp, i64 1) - %0 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %1 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 0) - %2 = bitcast i8* %1 to %Result** - store %Result* %measurementResult, %Result** %2 - %3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 0) - %5 = bitcast i8* %4 to %Result** - %6 = load %Result*, %Result** @ResultZero - store %Result* %6, %Result** %5 - call void @__quantum__qis__apply_conditionally(%Array* %0, %Array* %3, %Callable* %onResultZeroOp, %Callable* %onResultOneOp) - call void @__quantum__rt__result_update_reference_count(%Result* %measurementResult, i64 1) - call void @__quantum__rt__result_update_reference_count(%Result* %6, i64 1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultZeroOp, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultZeroOp, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultOneOp, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultOneOp, i64 -1) - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %7 = phi i64 [ 0, %entry ], [ %12, %exiting__1 ] - %8 = icmp sle i64 %7, 0 - br i1 %8, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %7) - %10 = bitcast i8* %9 to %Result** - %11 = load %Result*, %Result** %10 - call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) - br label %exiting__1 - -exiting__1: ; preds = %body__1 - %12 = add i64 %7, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) - br label %header__2 - -header__2: ; preds = %exiting__2, %exit__1 - %13 = phi i64 [ 0, %exit__1 ], [ %18, %exiting__2 ] - %14 = icmp sle i64 %13, 0 - br i1 %14, label %body__2, label %exit__2 - -body__2: ; preds = %header__2 - %15 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 %13) - %16 = bitcast i8* %15 to %Result** - %17 = load %Result*, %Result** %16 - call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 -1) - br label %exiting__2 - -exiting__2: ; preds = %body__2 - %18 = add i64 %13, 1 - br label %header__2 - -exit__2: ; preds = %header__2 - call void @__quantum__rt__array_update_reference_count(%Array* %3, i64 -1) - ret void -} - -declare %Array* @__quantum__rt__array_create_1d(i32, i64) - -declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) - -declare void @__quantum__rt__result_update_reference_count(%Result*, i64) - -declare void @__quantum__rt__array_update_reference_count(%Array*, i64) - -define void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %control, %Qubit* %target) { -entry: - %ctls = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls, i64 0) - %1 = bitcast i8* %0 to %Qubit** - store %Qubit* %control, %Qubit** %1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - br i1 true, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %target) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %target) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls, i64 -1) - ret void -} - -declare void @__quantum__qis__single_qubit_op_ctl(i64, i64, %Array*, %Qubit*) - -define void @Microsoft__Quantum__Intrinsic__CNOT__adj(%Qubit* %control, %Qubit* %target) { -entry: - call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %control, %Qubit* %target) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__CNOT__ctl(%Array* %ctls, { %Qubit*, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 0 - %control = load %Qubit*, %Qubit** %1 - %2 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 1 - %target = load %Qubit*, %Qubit** %2 - %3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 0) - %5 = bitcast i8* %4 to %Qubit** - store %Qubit* %control, %Qubit** %5 - %ctls__1 = call %Array* @__quantum__rt__array_concatenate(%Array* %ctls, %Array* %3) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 1) - %6 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls__1) - %7 = icmp eq i64 %6, 1 - br i1 %7, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls__1, %Qubit* %target) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls__1, %Qubit* %target) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %3, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__1, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) - -declare i64 @__quantum__rt__array_get_size_1d(%Array*) - -define void @Microsoft__Quantum__Intrinsic__CNOT__ctladj(%Array* %__controlQubits__, { %Qubit*, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - %1 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 0 - %control = load %Qubit*, %Qubit** %1 - %2 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 1 - %target = load %Qubit*, %Qubit** %2 - %3 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) - %4 = bitcast %Tuple* %3 to { %Qubit*, %Qubit* }* - %5 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %4, i32 0, i32 0 - %6 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %4, i32 0, i32 1 - store %Qubit* %control, %Qubit** %5 - store %Qubit* %target, %Qubit** %6 - call void @Microsoft__Quantum__Intrinsic__CNOT__ctl(%Array* %__controlQubits__, { %Qubit*, %Qubit* }* %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 %Tuple* @__quantum__rt__tuple_create(i64) - -declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) - -define void @Microsoft__Quantum__Intrinsic__H__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb) - ret void -} - -declare void @__quantum__qis__single_qubit_op(i64, i64, %Qubit*) - -define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qb) { -entry: - %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb) - ret %Result* %0 -} - -declare %Result* @__quantum__qis__single_qubit_measure(i64, i64, %Qubit*) - -define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %paulis, %Array* %qubits) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = load %Result*, %Result** @ResultOne - %res = alloca %Result* - store %Result* %0, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %0, i64 1) - %haveY = alloca i1 - store i1 false, i1* %haveY - %1 = call i64 @__quantum__rt__array_get_size_1d(%Array* %paulis) - %2 = sub i64 %1, 1 - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %i = phi i64 [ 0, %entry ], [ %15, %exiting__1 ] - %3 = icmp sle i64 %i, %2 - br i1 %3, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) - %5 = bitcast i8* %4 to i2* - %6 = load i2, i2* %5 - %7 = load i2, i2* @PauliY - %8 = icmp eq i2 %6, %7 - %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) - %10 = bitcast i8* %9 to i2* - %11 = load i2, i2* %10 - %12 = load i2, i2* @PauliI - %13 = icmp eq i2 %11, %12 - %14 = or i1 %8, %13 - br i1 %14, label %then0__1, label %continue__1 - -then0__1: ; preds = %body__1 - store i1 true, i1* %haveY - br label %continue__1 - -continue__1: ; preds = %then0__1, %body__1 - br label %exiting__1 - -exiting__1: ; preds = %continue__1 - %15 = add i64 %i, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - %16 = load i1, i1* %haveY - br i1 %16, label %then0__2, label %test1__1 - -then0__2: ; preds = %exit__1 - %17 = call %Result* @__quantum__qis__joint_measure(i64 106, i64 1, %Array* %qubits) - call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 1) - store %Result* %17, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %0, i64 -1) - br label %continue__2 - -test1__1: ; preds = %exit__1 - %18 = icmp sgt i64 %1, 2 - br i1 %18, label %then1__1, label %test2__1 - -then1__1: ; preds = %test1__1 - %19 = call %Result* @__quantum__qis__joint_measure(i64 107, i64 1, %Array* %qubits) - call void @__quantum__rt__result_update_reference_count(%Result* %19, i64 1) - %20 = load %Result*, %Result** %res - store %Result* %19, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %19, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %20, i64 -1) - br label %continue__2 - -test2__1: ; preds = %test1__1 - %21 = icmp eq i64 %1, 1 - br i1 %21, label %then2__1, label %test3__1 - -then2__1: ; preds = %test2__1 - %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %23 = bitcast i8* %22 to i2* - %24 = load i2, i2* %23 - %25 = load i2, i2* @PauliX - %26 = icmp eq i2 %24, %25 - br i1 %26, label %then0__3, label %else__1 - -then0__3: ; preds = %then2__1 - %27 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) - %28 = bitcast i8* %27 to %Qubit** - %qb = load %Qubit*, %Qubit** %28 - %29 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb) - call void @__quantum__rt__result_update_reference_count(%Result* %29, i64 1) - %30 = load %Result*, %Result** %res - store %Result* %29, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %29, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %30, i64 -1) - br label %continue__3 - -else__1: ; preds = %then2__1 - %31 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) - %32 = bitcast i8* %31 to %Qubit** - %qb__1 = load %Qubit*, %Qubit** %32 - %33 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__1) - call void @__quantum__rt__result_update_reference_count(%Result* %33, i64 1) - %34 = load %Result*, %Result** %res - store %Result* %33, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %33, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %34, i64 -1) - br label %continue__3 - -continue__3: ; preds = %else__1, %then0__3 - br label %continue__2 - -test3__1: ; preds = %test2__1 - %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %36 = bitcast i8* %35 to i2* - %37 = load i2, i2* %36 - %38 = load i2, i2* @PauliX - %39 = icmp eq i2 %37, %38 - %40 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %41 = bitcast i8* %40 to i2* - %42 = load i2, i2* %41 - %43 = load i2, i2* @PauliX - %44 = icmp eq i2 %42, %43 - %45 = and i1 %39, %44 - br i1 %45, label %then3__1, label %test4__1 - -then3__1: ; preds = %test3__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %46 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %46, i64 1) - %47 = load %Result*, %Result** %res - store %Result* %46, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %46, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %47, i64 -1) - br label %continue__2 - -test4__1: ; preds = %test3__1 - %48 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %49 = bitcast i8* %48 to i2* - %50 = load i2, i2* %49 - %51 = load i2, i2* @PauliX - %52 = icmp eq i2 %50, %51 - %53 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %54 = bitcast i8* %53 to i2* - %55 = load i2, i2* %54 - %56 = load i2, i2* @PauliZ - %57 = icmp eq i2 %55, %56 - %58 = and i1 %52, %57 - br i1 %58, label %then4__1, label %test5__1 - -then4__1: ; preds = %test4__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %59 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 1) - %60 = load %Result*, %Result** %res - store %Result* %59, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %60, i64 -1) - br label %continue__2 - -test5__1: ; preds = %test4__1 - %61 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %62 = bitcast i8* %61 to i2* - %63 = load i2, i2* %62 - %64 = load i2, i2* @PauliZ - %65 = icmp eq i2 %63, %64 - %66 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %67 = bitcast i8* %66 to i2* - %68 = load i2, i2* %67 - %69 = load i2, i2* @PauliX - %70 = icmp eq i2 %68, %69 - %71 = and i1 %65, %70 - br i1 %71, label %then5__1, label %test6__1 - -then5__1: ; preds = %test5__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %72 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %72, i64 1) - %73 = load %Result*, %Result** %res - store %Result* %72, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %72, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %73, i64 -1) - br label %continue__2 - -test6__1: ; preds = %test5__1 - %74 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %75 = bitcast i8* %74 to i2* - %76 = load i2, i2* %75 - %77 = load i2, i2* @PauliZ - %78 = icmp eq i2 %76, %77 - %79 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %80 = bitcast i8* %79 to i2* - %81 = load i2, i2* %80 - %82 = load i2, i2* @PauliZ - %83 = icmp eq i2 %81, %82 - %84 = and i1 %78, %83 - br i1 %84, label %then6__1, label %continue__2 - -then6__1: ; preds = %test6__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %85 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %85, i64 1) - %86 = load %Result*, %Result** %res - store %Result* %85, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %85, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %86, i64 -1) - br label %continue__2 - -continue__2: ; preds = %then6__1, %test6__1, %then5__1, %then4__1, %then3__1, %continue__3, %then1__1, %then0__2 - %87 = load %Result*, %Result** %res - call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %87 -} - -declare %Result* @__quantum__qis__joint_measure(i64, i64, %Array*) - -define void @Microsoft__Quantum__Intrinsic__Rx__body(double %theta, %Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rx__adj(double %theta, %Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rx__ctl(%Array* %ctls, { double, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 - %theta = load double, double* %1 - %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 - %qb = load %Qubit*, %Qubit** %2 - call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rx__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 - %theta = load double, double* %1 - %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 - %qb = load %Qubit*, %Qubit** %2 - call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Ry__body(double %theta, %Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Ry__adj(double %theta, %Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Ry__ctl(%Array* %ctls, { double, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 - %theta = load double, double* %1 - %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 - %qb = load %Qubit*, %Qubit** %2 - call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Ry__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 - %theta = load double, double* %1 - %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 - %qb = load %Qubit*, %Qubit** %2 - call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rz__body(double %theta, %Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rz__adj(double %theta, %Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rz__ctl(%Array* %ctls, { double, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 - %theta = load double, double* %1 - %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 - %qb = load %Qubit*, %Qubit** %2 - call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Rz__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 - %theta = load double, double* %1 - %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 - %qb = load %Qubit*, %Qubit** %2 - call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__ctladj(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__T__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__T__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__T__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__T__ctladj(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %qb) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %qb) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -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__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %ctls, %Qubit* %qb) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %ctls, %Qubit* %qb) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %ctls, %Qubit* %qb) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %ctls, %Qubit* %qb) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) - %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) - %1 = icmp eq i64 %0, 1 - br i1 %1, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %__controlQubits__, %Qubit* %qb) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) - ret void -} - -define %Tuple* @Microsoft__Quantum__Core__Attribute__body() { -entry: - ret %Tuple* null -} - -define %Tuple* @Microsoft__Quantum__Core__EntryPoint__body() { -entry: - ret %Tuple* null -} - -define %Tuple* @Microsoft__Quantum__Core__Inline__body() { -entry: - ret %Tuple* null -} - -define %Result* @Microsoft__Quantum__Instructions__Mx__body(%Qubit* %qb) { -entry: - %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb) - ret %Result* %0 -} - -define %Result* @Microsoft__Quantum__Instructions__Mxx__body(%Array* %qubits) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %0 -} - -define %Result* @Microsoft__Quantum__Instructions__Mxz__body(%Array* %qubits) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %0 -} - -define %Result* @Microsoft__Quantum__Instructions__Mz__body(%Qubit* %qb) { -entry: - %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb) - ret %Result* %0 -} - -define %Result* @Microsoft__Quantum__Instructions__Mzx__body(%Array* %qubits) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %0 -} - -define %Result* @Microsoft__Quantum__Instructions__Mzz__body(%Array* %qubits) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) - %0 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qubits) - call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) - ret %Result* %0 -} - -define void @Microsoft__Quantum__Instructions__Sx__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 17, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sx__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 17, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sx__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 18, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sx__ctladj(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 18, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sz__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sz__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sz__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Sz__ctladj(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tx__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 13, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tx__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 13, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tx__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 14, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tx__ctladj(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 14, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tz__body(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tz__adj(%Qubit* %qb) { -entry: - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tz__ctl(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Instructions__Tz__ctladj(%Array* %ctls, %Qubit* %qb) { -entry: - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Testing__Tracer__Delay__body(%Callable* %op, %Qubit* %arg, %Tuple* %aux) { -entry: - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %op, i64 1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %op, i64 1) - %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) - %1 = bitcast %Tuple* %0 to { %Qubit* }* - %2 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %1, i32 0, i32 0 - store %Qubit* %arg, %Qubit** %2 - call void @__quantum__rt__callable_invoke(%Callable* %op, %Tuple* %0, %Tuple* null) - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %op, i64 -1) - call void @__quantum__rt__callable_update_alias_count(%Callable* %op, i64 -1) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %0, i64 -1) - ret void -} - -declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) - -define void @Microsoft__Quantum__Testing__Tracer__TestCoreIntrinsics__body() { -entry: - %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 3) - 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 0) - %1 = bitcast i8* %0 to %Qubit** - %qb = load %Qubit*, %Qubit** %1 - call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) - %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %3 = bitcast i8* %2 to %Qubit** - %qb__1 = load %Qubit*, %Qubit** %3 - call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb__1) - %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %5 = bitcast i8* %4 to %Qubit** - %qb__2 = load %Qubit*, %Qubit** %5 - call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb__2) - %6 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %7 = bitcast i8* %6 to %Qubit** - %qb__3 = load %Qubit*, %Qubit** %7 - call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb__3) - %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %9 = bitcast i8* %8 to %Qubit** - %10 = load %Qubit*, %Qubit** %9 - %11 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %12 = bitcast i8* %11 to %Qubit** - %13 = load %Qubit*, %Qubit** %12 - call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %10, %Qubit* %13) - %14 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %15 = bitcast i8* %14 to %Qubit** - %qb__4 = load %Qubit*, %Qubit** %15 - call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__4) - %16 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %17 = bitcast i8* %16 to %Qubit** - %qb__5 = load %Qubit*, %Qubit** %17 - call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb__5) - %18 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %19 = bitcast i8* %18 to %Qubit** - %qb__6 = load %Qubit*, %Qubit** %19 - call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb__6) - %20 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %21 = bitcast i8* %20 to %Qubit** - %qb__7 = load %Qubit*, %Qubit** %21 - call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb__7) - %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %23 = bitcast i8* %22 to %Qubit** - %qb__9 = load %Qubit*, %Qubit** %23 - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__9) - call void @__quantum__qis__inject_barrier(i64 42, i64 0) - %24 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %25 = bitcast i8* %24 to %Qubit** - %qb__11 = load %Qubit*, %Qubit** %25 - call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb__11) - %26 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %27 = bitcast i8* %26 to %Qubit** - %qb__13 = load %Qubit*, %Qubit** %27 - call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb__13) - %28 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %29 = bitcast i8* %28 to %Qubit** - %qb__15 = load %Qubit*, %Qubit** %29 - call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb__15) - %30 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %31 = bitcast i8* %30 to %Qubit** - %qb__17 = load %Qubit*, %Qubit** %31 - call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb__17) - %32 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %33 = bitcast i8* %32 to %Qubit** - %34 = load %Qubit*, %Qubit** %33 - %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %36 = bitcast i8* %35 to %Qubit** - %37 = load %Qubit*, %Qubit** %36 - call void @Microsoft__Quantum__Intrinsic__CNOT__adj(%Qubit* %34, %Qubit* %37) - %38 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %39 = bitcast i8* %38 to %Qubit** - %qb__19 = load %Qubit*, %Qubit** %39 - call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__19) - %40 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %41 = bitcast i8* %40 to %Qubit** - %qb__20 = load %Qubit*, %Qubit** %41 - call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb__20) - %42 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %43 = bitcast i8* %42 to %Qubit** - %qb__21 = load %Qubit*, %Qubit** %43 - call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb__21) - %44 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %45 = bitcast i8* %44 to %Qubit** - %qb__22 = load %Qubit*, %Qubit** %45 - call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb__22) - %46 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %47 = bitcast i8* %46 to %Qubit** - %qb__24 = load %Qubit*, %Qubit** %47 - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__24) - %c = call %Qubit* @__quantum__rt__qubit_allocate() - %ctls = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %48 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls, i64 0) - %49 = bitcast i8* %48 to %Qubit** - store %Qubit* %c, %Qubit** %49 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) - %50 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %51 = bitcast i8* %50 to %Qubit** - %qb__26 = load %Qubit*, %Qubit** %51 - br i1 true, label %then0__1, label %else__1 - -then0__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %qb__26) - br label %continue__1 - -else__1: ; preds = %entry - call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %qb__26) - br label %continue__1 - -continue__1: ; preds = %else__1, %then0__1 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls, i64 -1) - %ctls__1 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %52 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__1, i64 0) - %53 = bitcast i8* %52 to %Qubit** - store %Qubit* %c, %Qubit** %53 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 1) - %54 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %55 = bitcast i8* %54 to %Qubit** - %qb__27 = load %Qubit*, %Qubit** %55 - br i1 true, label %then0__2, label %else__2 - -then0__2: ; preds = %continue__1 - call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %ctls__1, %Qubit* %qb__27) - br label %continue__2 - -else__2: ; preds = %continue__1 - call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %ctls__1, %Qubit* %qb__27) - br label %continue__2 - -continue__2: ; preds = %else__2, %then0__2 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__1, i64 -1) - %ctls__2 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %56 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__2, i64 0) - %57 = bitcast i8* %56 to %Qubit** - store %Qubit* %c, %Qubit** %57 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__2, i64 1) - %58 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %59 = bitcast i8* %58 to %Qubit** - %qb__28 = load %Qubit*, %Qubit** %59 - br i1 true, label %then0__3, label %else__3 - -then0__3: ; preds = %continue__2 - call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %ctls__2, %Qubit* %qb__28) - br label %continue__3 - -else__3: ; preds = %continue__2 - call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %ctls__2, %Qubit* %qb__28) - br label %continue__3 - -continue__3: ; preds = %else__3, %then0__3 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__2, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__2, i64 -1) - %ctls__3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %60 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__3, i64 0) - %61 = bitcast i8* %60 to %Qubit** - store %Qubit* %c, %Qubit** %61 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__3, i64 1) - %62 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %63 = bitcast i8* %62 to %Qubit** - %qb__29 = load %Qubit*, %Qubit** %63 - call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %ctls__3, %Qubit* %qb__29) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__3, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__3, i64 -1) - %ctls__4 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %64 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__4, i64 0) - %65 = bitcast i8* %64 to %Qubit** - store %Qubit* %c, %Qubit** %65 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__4, i64 1) - %66 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %67 = bitcast i8* %66 to %Qubit** - %qb__30 = load %Qubit*, %Qubit** %67 - call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls__4, %Qubit* %qb__30) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__4, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__4, i64 -1) - %ctls__5 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %68 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__5, i64 0) - %69 = bitcast i8* %68 to %Qubit** - store %Qubit* %c, %Qubit** %69 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__5, i64 1) - %70 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %71 = bitcast i8* %70 to %Qubit** - %qb__31 = load %Qubit*, %Qubit** %71 - call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls__5, %Qubit* %qb__31) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__5, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__5, i64 -1) - %ctls__6 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__6, i64 0) - %73 = bitcast i8* %72 to %Qubit** - store %Qubit* %c, %Qubit** %73 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__6, i64 1) - %74 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %75 = bitcast i8* %74 to %Qubit** - %qb__32 = load %Qubit*, %Qubit** %75 - call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls__6, %Qubit* %qb__32) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__6, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__6, i64 -1) - %ctls__7 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %76 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__7, i64 0) - %77 = bitcast i8* %76 to %Qubit** - store %Qubit* %c, %Qubit** %77 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 1) - %78 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %79 = bitcast i8* %78 to %Qubit** - %qb__33 = load %Qubit*, %Qubit** %79 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls__7, %Qubit* %qb__33) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__7, i64 -1) - %ctls__9 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) - %80 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__9, i64 0) - %81 = bitcast i8* %80 to %Qubit** - store %Qubit* %c, %Qubit** %81 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 1) - %82 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %83 = bitcast i8* %82 to %Qubit** - %qb__35 = load %Qubit*, %Qubit** %83 - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls__9, %Qubit* %qb__35) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %ctls__9, i64 -1) - call void @__quantum__rt__qubit_release(%Qubit* %c) - %cc = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %84 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %85 = bitcast i8* %84 to %Qubit** - %qb__37 = load %Qubit*, %Qubit** %85 - %86 = call i64 @__quantum__rt__array_get_size_1d(%Array* %cc) - %87 = icmp eq i64 %86, 1 - br i1 %87, label %then0__4, label %else__4 - -then0__4: ; preds = %continue__3 - call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %cc, %Qubit* %qb__37) - br label %continue__4 - -else__4: ; preds = %continue__3 - call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %cc, %Qubit* %qb__37) - br label %continue__4 - -continue__4: ; preds = %else__4, %then0__4 - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %88 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %89 = bitcast i8* %88 to %Qubit** - %qb__38 = load %Qubit*, %Qubit** %89 - %90 = icmp eq i64 %86, 1 - br i1 %90, label %then0__5, label %else__5 - -then0__5: ; preds = %continue__4 - call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %cc, %Qubit* %qb__38) - br label %continue__5 - -else__5: ; preds = %continue__4 - call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %cc, %Qubit* %qb__38) - br label %continue__5 - -continue__5: ; preds = %else__5, %then0__5 - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %91 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %92 = bitcast i8* %91 to %Qubit** - %qb__39 = load %Qubit*, %Qubit** %92 - %93 = icmp eq i64 %86, 1 - br i1 %93, label %then0__6, label %else__6 - -then0__6: ; preds = %continue__5 - call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %cc, %Qubit* %qb__39) - br label %continue__6 - -else__6: ; preds = %continue__5 - call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %cc, %Qubit* %qb__39) - br label %continue__6 - -continue__6: ; preds = %else__6, %then0__6 - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %94 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %95 = bitcast i8* %94 to %Qubit** - %qb__40 = load %Qubit*, %Qubit** %95 - call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %cc, %Qubit* %qb__40) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %96 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %97 = bitcast i8* %96 to %Qubit** - %qb__41 = load %Qubit*, %Qubit** %97 - call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %cc, %Qubit* %qb__41) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %98 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %99 = bitcast i8* %98 to %Qubit** - %qb__42 = load %Qubit*, %Qubit** %99 - call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %cc, %Qubit* %qb__42) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %100 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %101 = bitcast i8* %100 to %Qubit** - %qb__43 = load %Qubit*, %Qubit** %101 - call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %cc, %Qubit* %qb__43) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %102 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %103 = bitcast i8* %102 to %Qubit** - %qb__44 = load %Qubit*, %Qubit** %103 - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %cc, %Qubit* %qb__44) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - %104 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %105 = bitcast i8* %104 to %Qubit** - %qb__46 = load %Qubit*, %Qubit** %105 - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) - call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %cc, %Qubit* %qb__46) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__qubit_release_array(%Array* %cc) - call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %cc, 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 %Qubit* @__quantum__rt__qubit_allocate() - -declare %Array* @__quantum__rt__qubit_allocate_array(i64) - -declare void @__quantum__qis__inject_barrier(i64, i64) - -declare void @__quantum__rt__qubit_release(%Qubit*) - -declare void @__quantum__rt__qubit_release_array(%Array*) - -define void @Microsoft__Quantum__Testing__Tracer__TestMeasurements__body() { -entry: - %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 6) - 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 0) - %1 = bitcast i8* %0 to %Qubit** - %qb = load %Qubit*, %Qubit** %1 - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) - %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) - %3 = bitcast i8* %2 to %Qubit** - %qb__2 = load %Qubit*, %Qubit** %3 - %r0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__2) - %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %5 = bitcast i8* %4 to %Qubit** - %qb__4 = load %Qubit*, %Qubit** %5 - call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__4) - %6 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %7 = bitcast i8* %6 to %Qubit** - %8 = load %Qubit*, %Qubit** %7 - %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %10 = bitcast i8* %9 to %Qubit** - %11 = load %Qubit*, %Qubit** %10 - call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %8, %Qubit* %11) - %qs12 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 2) - %12 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) - %13 = bitcast i8* %12 to %Qubit** - %14 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 1) - %15 = bitcast i8* %14 to %Qubit** - %16 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) - %17 = bitcast i8* %16 to %Qubit** - %18 = load %Qubit*, %Qubit** %17 - %19 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) - %20 = bitcast i8* %19 to %Qubit** - %21 = load %Qubit*, %Qubit** %20 - store %Qubit* %18, %Qubit** %13 - store %Qubit* %21, %Qubit** %15 - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) - %paulis = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 2) - %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %23 = bitcast i8* %22 to i2* - %24 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %25 = bitcast i8* %24 to i2* - %26 = load i2, i2* @PauliY - %27 = load i2, i2* @PauliX - store i2 %26, i2* %23 - store i2 %27, i2* %25 - call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 1) - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) - %28 = load %Result*, %Result** @ResultOne - %res = alloca %Result* - store %Result* %28, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 1) - %haveY = alloca i1 - store i1 false, i1* %haveY - br label %header__1 - -header__1: ; preds = %exiting__1, %entry - %i = phi i64 [ 0, %entry ], [ %41, %exiting__1 ] - %29 = icmp sle i64 %i, 1 - br i1 %29, label %body__1, label %exit__1 - -body__1: ; preds = %header__1 - %30 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) - %31 = bitcast i8* %30 to i2* - %32 = load i2, i2* %31 - %33 = load i2, i2* @PauliY - %34 = icmp eq i2 %32, %33 - %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) - %36 = bitcast i8* %35 to i2* - %37 = load i2, i2* %36 - %38 = load i2, i2* @PauliI - %39 = icmp eq i2 %37, %38 - %40 = or i1 %34, %39 - br i1 %40, label %then0__1, label %continue__1 - -then0__1: ; preds = %body__1 - store i1 true, i1* %haveY - br label %continue__1 - -continue__1: ; preds = %then0__1, %body__1 - br label %exiting__1 - -exiting__1: ; preds = %continue__1 - %41 = add i64 %i, 1 - br label %header__1 - -exit__1: ; preds = %header__1 - %42 = load i1, i1* %haveY - br i1 %42, label %then0__2, label %test1__1 - -then0__2: ; preds = %exit__1 - %43 = call %Result* @__quantum__qis__joint_measure(i64 106, i64 1, %Array* %qs12) - call void @__quantum__rt__result_update_reference_count(%Result* %43, i64 1) - store %Result* %43, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %43, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) - br label %continue__2 - -test1__1: ; preds = %exit__1 - br i1 false, label %then1__1, label %test2__1 - -then1__1: ; preds = %test1__1 - %44 = call %Result* @__quantum__qis__joint_measure(i64 107, i64 1, %Array* %qs12) - call void @__quantum__rt__result_update_reference_count(%Result* %44, i64 1) - %45 = load %Result*, %Result** %res - store %Result* %44, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %44, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %45, i64 -1) - br label %continue__2 - -test2__1: ; preds = %test1__1 - br i1 false, label %then2__1, label %test3__1 - -then2__1: ; preds = %test2__1 - %46 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %47 = bitcast i8* %46 to i2* - %48 = load i2, i2* %47 - %49 = load i2, i2* @PauliX - %50 = icmp eq i2 %48, %49 - br i1 %50, label %then0__3, label %else__1 - -then0__3: ; preds = %then2__1 - %51 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) - %52 = bitcast i8* %51 to %Qubit** - %qb__6 = load %Qubit*, %Qubit** %52 - %53 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb__6) - call void @__quantum__rt__result_update_reference_count(%Result* %53, i64 1) - %54 = load %Result*, %Result** %res - store %Result* %53, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %53, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %54, i64 -1) - br label %continue__3 - -else__1: ; preds = %then2__1 - %55 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) - %56 = bitcast i8* %55 to %Qubit** - %qb__7 = load %Qubit*, %Qubit** %56 - %57 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__7) - call void @__quantum__rt__result_update_reference_count(%Result* %57, i64 1) - %58 = load %Result*, %Result** %res - store %Result* %57, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %57, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %58, i64 -1) - br label %continue__3 - -continue__3: ; preds = %else__1, %then0__3 - br label %continue__2 - -test3__1: ; preds = %test2__1 - %59 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %60 = bitcast i8* %59 to i2* - %61 = load i2, i2* %60 - %62 = load i2, i2* @PauliX - %63 = icmp eq i2 %61, %62 - %64 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %65 = bitcast i8* %64 to i2* - %66 = load i2, i2* %65 - %67 = load i2, i2* @PauliX - %68 = icmp eq i2 %66, %67 - %69 = and i1 %63, %68 - br i1 %69, label %then3__1, label %test4__1 - -then3__1: ; preds = %test3__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) - %70 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qs12) - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %70, i64 1) - %71 = load %Result*, %Result** %res - store %Result* %70, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %70, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %71, i64 -1) - br label %continue__2 - -test4__1: ; preds = %test3__1 - %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %73 = bitcast i8* %72 to i2* - %74 = load i2, i2* %73 - %75 = load i2, i2* @PauliX - %76 = icmp eq i2 %74, %75 - %77 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %78 = bitcast i8* %77 to i2* - %79 = load i2, i2* %78 - %80 = load i2, i2* @PauliZ - %81 = icmp eq i2 %79, %80 - %82 = and i1 %76, %81 - br i1 %82, label %then4__1, label %test5__1 - -then4__1: ; preds = %test4__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) - %83 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qs12) - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %83, i64 1) - %84 = load %Result*, %Result** %res - store %Result* %83, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %83, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %84, i64 -1) - br label %continue__2 - -test5__1: ; preds = %test4__1 - %85 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %86 = bitcast i8* %85 to i2* - %87 = load i2, i2* %86 - %88 = load i2, i2* @PauliZ - %89 = icmp eq i2 %87, %88 - %90 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %91 = bitcast i8* %90 to i2* - %92 = load i2, i2* %91 - %93 = load i2, i2* @PauliX - %94 = icmp eq i2 %92, %93 - %95 = and i1 %89, %94 - br i1 %95, label %then5__1, label %test6__1 - -then5__1: ; preds = %test5__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) - %96 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qs12) - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %96, i64 1) - %97 = load %Result*, %Result** %res - store %Result* %96, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %96, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %97, i64 -1) - br label %continue__2 - -test6__1: ; preds = %test5__1 - %98 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) - %99 = bitcast i8* %98 to i2* - %100 = load i2, i2* %99 - %101 = load i2, i2* @PauliZ - %102 = icmp eq i2 %100, %101 - %103 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) - %104 = bitcast i8* %103 to i2* - %105 = load i2, i2* %104 - %106 = load i2, i2* @PauliZ - %107 = icmp eq i2 %105, %106 - %108 = and i1 %102, %107 - br i1 %108, label %then6__1, label %continue__2 - -then6__1: ; preds = %test6__1 - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) - %109 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qs12) - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %109, i64 1) - %110 = load %Result*, %Result** %res - store %Result* %109, %Result** %res - call void @__quantum__rt__result_update_reference_count(%Result* %109, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %110, i64 -1) - br label %continue__2 - -continue__2: ; preds = %then6__1, %test6__1, %then5__1, %then4__1, %then3__1, %continue__3, %then1__1, %then0__2 - %r12 = load %Result*, %Result** %res - call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 -1) - call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %paulis, i64 -1) - %111 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %112 = bitcast %Tuple* %111 to { %Callable*, %Callable*, %Qubit* }* - %113 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 0 - %114 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 1 - %115 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 2 - %116 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %117 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__X, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %118 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 3) - %119 = bitcast i8* %118 to %Qubit** - %120 = load %Qubit*, %Qubit** %119 - store %Callable* %116, %Callable** %113 - store %Callable* %117, %Callable** %114 - store %Qubit* %120, %Qubit** %115 - %121 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %111) - %122 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %123 = bitcast %Tuple* %122 to { %Callable*, %Callable*, %Qubit* }* - %124 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 0 - %125 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 1 - %126 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 2 - %127 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %128 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__Y, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %129 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 3) - %130 = bitcast i8* %129 to %Qubit** - %131 = load %Qubit*, %Qubit** %130 - store %Callable* %127, %Callable** %124 - store %Callable* %128, %Callable** %125 - store %Qubit* %131, %Qubit** %126 - %132 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %122) - call void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %r0, %Callable* %121, %Callable* %132) - %133 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %134 = bitcast %Tuple* %133 to { %Callable*, %Callable*, %Qubit* }* - %135 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 0 - %136 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 1 - %137 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 2 - %138 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %139 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__Z, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %140 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 4) - %141 = bitcast i8* %140 to %Qubit** - %142 = load %Qubit*, %Qubit** %141 - store %Callable* %138, %Callable** %135 - store %Callable* %139, %Callable** %136 - store %Qubit* %142, %Qubit** %137 - %143 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__3, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %133) - %144 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %145 = bitcast %Tuple* %144 to { %Callable*, %Callable*, %Qubit* }* - %146 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 0 - %147 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 1 - %148 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 2 - %149 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %150 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__S, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) - %151 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 4) - %152 = bitcast i8* %151 to %Qubit** - %153 = load %Qubit*, %Qubit** %152 - store %Callable* %149, %Callable** %146 - store %Callable* %150, %Callable** %147 - store %Qubit* %153, %Qubit** %148 - %154 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__4, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %144) - call void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %r12, %Callable* %143, %Callable* %154) - %155 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 5) - %156 = bitcast i8* %155 to %Qubit** - %qb__8 = load %Qubit*, %Qubit** %156 - call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__8) - 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_alias_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %r0, i64 -1) - call void @__quantum__rt__array_update_reference_count(%Array* %qs12, i64 -1) - call void @__quantum__rt__result_update_reference_count(%Result* %r12, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %121, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %121, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %132, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %132, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %143, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %143, i64 -1) - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %154, i64 -1) - call void @__quantum__rt__callable_update_reference_count(%Callable* %154, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Testing__Tracer__Delay__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %arg-tuple to { %Callable*, %Qubit*, %Tuple* }* - %1 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 0 - %2 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 1 - %3 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 2 - %4 = load %Callable*, %Callable** %1 - %5 = load %Qubit*, %Qubit** %2 - %6 = load %Tuple*, %Tuple** %3 - call void @Microsoft__Quantum__Testing__Tracer__Delay__body(%Callable* %4, %Qubit* %5, %Tuple* %6) - ret void -} - -declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) - -define void @Microsoft__Quantum__Intrinsic__X__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 - call void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__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 - call void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__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 - call void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %3, %Qubit* %4) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__X__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 - call void @Microsoft__Quantum__Intrinsic__X__ctladj(%Array* %3, %Qubit* %4) - ret void -} - -define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %2 = load %Callable*, %Callable** %1 - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 - %4 = load %Qubit*, %Qubit** %3 - %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* - %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 - %7 = load %Tuple*, %Tuple** %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* - %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 - %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 - store %Callable* %2, %Callable** %10 - store %Qubit* %4, %Qubit** %11 - store %Tuple* %7, %Tuple** %12 - %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 - %14 = load %Callable*, %Callable** %13 - call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - ret void -} - -define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %4 = load %Callable*, %Callable** %3 - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %4, i64 %count-change) - call void @__quantum__rt__callable_update_reference_count(%Callable* %4, 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*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %4 = load %Callable*, %Callable** %3 - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %4, i64 %count-change) - call void @__quantum__rt__callable_update_alias_count(%Callable* %4, i64 %count-change) - call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__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 - call void @Microsoft__Quantum__Intrinsic__Y__body(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__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 - call void @Microsoft__Quantum__Intrinsic__Y__adj(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__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 - call void @Microsoft__Quantum__Intrinsic__Y__ctl(%Array* %3, %Qubit* %4) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Y__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 - call void @Microsoft__Quantum__Intrinsic__Y__ctladj(%Array* %3, %Qubit* %4) - 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*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %2 = load %Callable*, %Callable** %1 - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 - %4 = load %Qubit*, %Qubit** %3 - %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* - %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 - %7 = load %Tuple*, %Tuple** %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* - %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 - %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 - store %Callable* %2, %Callable** %10 - store %Qubit* %4, %Qubit** %11 - store %Tuple* %7, %Tuple** %12 - %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 - %14 = load %Callable*, %Callable** %13 - call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__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 - call void @Microsoft__Quantum__Intrinsic__Z__body(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__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 - call void @Microsoft__Quantum__Intrinsic__Z__adj(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__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 - call void @Microsoft__Quantum__Intrinsic__Z__ctl(%Array* %3, %Qubit* %4) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__Z__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 - call void @Microsoft__Quantum__Intrinsic__Z__ctladj(%Array* %3, %Qubit* %4) - ret void -} - -define void @Lifted__PartialApplication__3__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %2 = load %Callable*, %Callable** %1 - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 - %4 = load %Qubit*, %Qubit** %3 - %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* - %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 - %7 = load %Tuple*, %Tuple** %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* - %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 - %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 - store %Callable* %2, %Callable** %10 - store %Qubit* %4, %Qubit** %11 - store %Tuple* %7, %Tuple** %12 - %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 - %14 = load %Callable*, %Callable** %13 - call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__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 - call void @Microsoft__Quantum__Intrinsic__S__body(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__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 - call void @Microsoft__Quantum__Intrinsic__S__adj(%Qubit* %2) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__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 - call void @Microsoft__Quantum__Intrinsic__S__ctl(%Array* %3, %Qubit* %4) - ret void -} - -define void @Microsoft__Quantum__Intrinsic__S__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 - call void @Microsoft__Quantum__Intrinsic__S__ctladj(%Array* %3, %Qubit* %4) - ret void -} - -define void @Lifted__PartialApplication__4__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %2 = load %Callable*, %Callable** %1 - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 - %4 = load %Qubit*, %Qubit** %3 - %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* - %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 - %7 = load %Tuple*, %Tuple** %6 - %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) - %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* - %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 - %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 - %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 - store %Callable* %2, %Callable** %10 - store %Qubit* %4, %Qubit** %11 - store %Tuple* %7, %Tuple** %12 - %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 - %14 = load %Callable*, %Callable** %13 - call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) - call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) - ret void -} - -define void @MemoryManagement__2__RefCount(%Tuple* %capture-tuple, i64 %count-change) { -entry: - %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %4 = load %Callable*, %Callable** %3 - call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %4, i64 %count-change) - call void @__quantum__rt__callable_update_reference_count(%Callable* %4, 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*, %Callable*, %Qubit* }* - %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) - %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 - %4 = load %Callable*, %Callable** %3 - call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %4, i64 %count-change) - call void @__quantum__rt__callable_update_alias_count(%Callable* %4, i64 %count-change) - call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) - ret void -} - -declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) - -define { %String* }* @Microsoft__Quantum__Targeting__TargetInstruction__body(%String* %__Item1__) { -entry: - %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) - %1 = bitcast %Tuple* %0 to { %String* }* - %2 = getelementptr inbounds { %String* }, { %String* }* %1, i32 0, i32 0 - store %String* %__Item1__, %String** %2 - call void @__quantum__rt__string_update_reference_count(%String* %__Item1__, i64 1) - ret { %String* }* %1 -} - -declare void @__quantum__rt__string_update_reference_count(%String*, i64) - -declare void @__quantum__rt__tuple_update_alias_count(%Tuple*, i64) + +%Result = type opaque +%Range = type { i64, i64, i64 } +%Tuple = type opaque +%Array = type opaque +%Callable = type opaque +%Qubit = type opaque +%String = type opaque + +@ResultZero = external dllimport global %Result* +@ResultOne = external dllimport 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__Tracer__Delay = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Testing__Tracer__Delay__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@Microsoft__Quantum__Intrinsic__X = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__X__ctladj__wrapper] +@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] +@Microsoft__Quantum__Intrinsic__Y = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Y__ctladj__wrapper] +@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] +@Microsoft__Quantum__Intrinsic__Z = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__Z__ctladj__wrapper] +@PartialApplication__3 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__3__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null, void (%Tuple*, %Tuple*, %Tuple*)* null] +@Microsoft__Quantum__Intrinsic__S = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__body__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__adj__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__ctl__wrapper, void (%Tuple*, %Tuple*, %Tuple*)* @Microsoft__Quantum__Intrinsic__S__ctladj__wrapper] +@PartialApplication__4 = constant [4 x void (%Tuple*, %Tuple*, %Tuple*)*] [void (%Tuple*, %Tuple*, %Tuple*)* @Lifted__PartialApplication__4__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] + +define void @Microsoft__Quantum__Intrinsic__ApplyConditionallyIntrinsic__body(%Array* %measurementResults, %Array* %resultsValues, %Callable* %onEqualOp, %Callable* %onNonEqualOp) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %measurementResults, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %resultsValues, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onEqualOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onEqualOp, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onNonEqualOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onNonEqualOp, i64 1) + call void @__quantum__qis__apply_conditionally(%Array* %measurementResults, %Array* %resultsValues, %Callable* %onEqualOp, %Callable* %onNonEqualOp) + call void @__quantum__rt__array_update_alias_count(%Array* %measurementResults, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %resultsValues, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onEqualOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onEqualOp, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onNonEqualOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onNonEqualOp, i64 -1) + ret void +} + +declare void @__quantum__rt__array_update_alias_count(%Array*, i64) + +declare void @__quantum__rt__callable_memory_management(i32, %Callable*, i64) + +declare void @__quantum__rt__callable_update_alias_count(%Callable*, i64) + +declare void @__quantum__qis__apply_conditionally(%Array*, %Array*, %Callable*, %Callable*) + +define void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %measurementResult, %Callable* %onResultZeroOp, %Callable* %onResultOneOp) { +entry: + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultZeroOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultZeroOp, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultOneOp, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultOneOp, i64 1) + %0 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %1 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 0) + %2 = bitcast i8* %1 to %Result** + store %Result* %measurementResult, %Result** %2 + %3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 0) + %5 = bitcast i8* %4 to %Result** + %6 = load %Result*, %Result** @ResultZero + store %Result* %6, %Result** %5 + call void @__quantum__qis__apply_conditionally(%Array* %0, %Array* %3, %Callable* %onResultZeroOp, %Callable* %onResultOneOp) + call void @__quantum__rt__result_update_reference_count(%Result* %measurementResult, i64 1) + call void @__quantum__rt__result_update_reference_count(%Result* %6, i64 1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultZeroOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultZeroOp, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %onResultOneOp, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %onResultOneOp, i64 -1) + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %7 = phi i64 [ 0, %entry ], [ %12, %exiting__1 ] + %8 = icmp sle i64 %7, 0 + br i1 %8, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %0, i64 %7) + %10 = bitcast i8* %9 to %Result** + %11 = load %Result*, %Result** %10 + call void @__quantum__rt__result_update_reference_count(%Result* %11, i64 -1) + br label %exiting__1 + +exiting__1: ; preds = %body__1 + %12 = add i64 %7, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + call void @__quantum__rt__array_update_reference_count(%Array* %0, i64 -1) + br label %header__2 + +header__2: ; preds = %exiting__2, %exit__1 + %13 = phi i64 [ 0, %exit__1 ], [ %18, %exiting__2 ] + %14 = icmp sle i64 %13, 0 + br i1 %14, label %body__2, label %exit__2 + +body__2: ; preds = %header__2 + %15 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 %13) + %16 = bitcast i8* %15 to %Result** + %17 = load %Result*, %Result** %16 + call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 -1) + br label %exiting__2 + +exiting__2: ; preds = %body__2 + %18 = add i64 %13, 1 + br label %header__2 + +exit__2: ; preds = %header__2 + call void @__quantum__rt__array_update_reference_count(%Array* %3, i64 -1) + ret void +} + +declare %Array* @__quantum__rt__array_create_1d(i32, i64) + +declare i8* @__quantum__rt__array_get_element_ptr_1d(%Array*, i64) + +declare void @__quantum__rt__result_update_reference_count(%Result*, i64) + +declare void @__quantum__rt__array_update_reference_count(%Array*, i64) + +define void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %control, %Qubit* %target) { +entry: + %ctls = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %0 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls, i64 0) + %1 = bitcast i8* %0 to %Qubit** + store %Qubit* %control, %Qubit** %1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + br i1 true, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %target) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %target) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls, i64 -1) + ret void +} + +declare void @__quantum__qis__single_qubit_op_ctl(i64, i64, %Array*, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__CNOT__adj(%Qubit* %control, %Qubit* %target) { +entry: + call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %control, %Qubit* %target) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__CNOT__ctl(%Array* %ctls, { %Qubit*, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 0 + %control = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 1 + %target = load %Qubit*, %Qubit** %2 + %3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %3, i64 0) + %5 = bitcast i8* %4 to %Qubit** + store %Qubit* %control, %Qubit** %5 + %ctls__1 = call %Array* @__quantum__rt__array_concatenate(%Array* %ctls, %Array* %3) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 1) + %6 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls__1) + %7 = icmp eq i64 %6, 1 + br i1 %7, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls__1, %Qubit* %target) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls__1, %Qubit* %target) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %3, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__1, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +declare %Array* @__quantum__rt__array_concatenate(%Array*, %Array*) + +declare i64 @__quantum__rt__array_get_size_1d(%Array*) + +define void @Microsoft__Quantum__Intrinsic__CNOT__ctladj(%Array* %__controlQubits__, { %Qubit*, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %1 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 0 + %control = load %Qubit*, %Qubit** %1 + %2 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %0, i32 0, i32 1 + %target = load %Qubit*, %Qubit** %2 + %3 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 2)) + %4 = bitcast %Tuple* %3 to { %Qubit*, %Qubit* }* + %5 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %4, i32 0, i32 0 + %6 = getelementptr inbounds { %Qubit*, %Qubit* }, { %Qubit*, %Qubit* }* %4, i32 0, i32 1 + store %Qubit* %control, %Qubit** %5 + store %Qubit* %target, %Qubit** %6 + call void @Microsoft__Quantum__Intrinsic__CNOT__ctl(%Array* %__controlQubits__, { %Qubit*, %Qubit* }* %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 %Tuple* @__quantum__rt__tuple_create(i64) + +declare void @__quantum__rt__tuple_update_reference_count(%Tuple*, i64) + +define void @Microsoft__Quantum__Intrinsic__H__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb) + ret void +} + +declare void @__quantum__qis__single_qubit_op(i64, i64, %Qubit*) + +define void @Microsoft__Quantum__Intrinsic__H__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__H__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__H__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define %Result* @Microsoft__Quantum__Intrinsic__M__body(%Qubit* %qb) { +entry: + %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb) + ret %Result* %0 +} + +declare %Result* @__quantum__qis__single_qubit_measure(i64, i64, %Qubit*) + +define %Result* @Microsoft__Quantum__Intrinsic__Measure__body(%Array* %paulis, %Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = load %Result*, %Result** @ResultOne + %res = alloca %Result* + store %Result* %0, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %0, i64 1) + %haveY = alloca i1 + store i1 false, i1* %haveY + %1 = call i64 @__quantum__rt__array_get_size_1d(%Array* %paulis) + %2 = sub i64 %1, 1 + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %15, %exiting__1 ] + %3 = icmp sle i64 %i, %2 + br i1 %3, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %5 = bitcast i8* %4 to i2* + %6 = load i2, i2* %5 + %7 = load i2, i2* @PauliY + %8 = icmp eq i2 %6, %7 + %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %10 = bitcast i8* %9 to i2* + %11 = load i2, i2* %10 + %12 = load i2, i2* @PauliI + %13 = icmp eq i2 %11, %12 + %14 = or i1 %8, %13 + br i1 %14, label %then0__1, label %continue__1 + +then0__1: ; preds = %body__1 + store i1 true, i1* %haveY + br label %continue__1 + +continue__1: ; preds = %then0__1, %body__1 + br label %exiting__1 + +exiting__1: ; preds = %continue__1 + %15 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + %16 = load i1, i1* %haveY + br i1 %16, label %then0__2, label %test1__1 + +then0__2: ; preds = %exit__1 + %17 = call %Result* @__quantum__qis__joint_measure(i64 106, i64 1, %Array* %qubits) + call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 1) + store %Result* %17, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %17, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %0, i64 -1) + br label %continue__2 + +test1__1: ; preds = %exit__1 + %18 = icmp sgt i64 %1, 2 + br i1 %18, label %then1__1, label %test2__1 + +then1__1: ; preds = %test1__1 + %19 = call %Result* @__quantum__qis__joint_measure(i64 107, i64 1, %Array* %qubits) + call void @__quantum__rt__result_update_reference_count(%Result* %19, i64 1) + %20 = load %Result*, %Result** %res + store %Result* %19, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %19, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %20, i64 -1) + br label %continue__2 + +test2__1: ; preds = %test1__1 + %21 = icmp eq i64 %1, 1 + br i1 %21, label %then2__1, label %test3__1 + +then2__1: ; preds = %test2__1 + %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %23 = bitcast i8* %22 to i2* + %24 = load i2, i2* %23 + %25 = load i2, i2* @PauliX + %26 = icmp eq i2 %24, %25 + br i1 %26, label %then0__3, label %else__1 + +then0__3: ; preds = %then2__1 + %27 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %28 = bitcast i8* %27 to %Qubit** + %qb = load %Qubit*, %Qubit** %28 + %29 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb) + call void @__quantum__rt__result_update_reference_count(%Result* %29, i64 1) + %30 = load %Result*, %Result** %res + store %Result* %29, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %29, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %30, i64 -1) + br label %continue__3 + +else__1: ; preds = %then2__1 + %31 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qubits, i64 0) + %32 = bitcast i8* %31 to %Qubit** + %qb__1 = load %Qubit*, %Qubit** %32 + %33 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__1) + call void @__quantum__rt__result_update_reference_count(%Result* %33, i64 1) + %34 = load %Result*, %Result** %res + store %Result* %33, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %33, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %34, i64 -1) + br label %continue__3 + +continue__3: ; preds = %else__1, %then0__3 + br label %continue__2 + +test3__1: ; preds = %test2__1 + %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %36 = bitcast i8* %35 to i2* + %37 = load i2, i2* %36 + %38 = load i2, i2* @PauliX + %39 = icmp eq i2 %37, %38 + %40 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %41 = bitcast i8* %40 to i2* + %42 = load i2, i2* %41 + %43 = load i2, i2* @PauliX + %44 = icmp eq i2 %42, %43 + %45 = and i1 %39, %44 + br i1 %45, label %then3__1, label %test4__1 + +then3__1: ; preds = %test3__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %46 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %46, i64 1) + %47 = load %Result*, %Result** %res + store %Result* %46, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %46, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %47, i64 -1) + br label %continue__2 + +test4__1: ; preds = %test3__1 + %48 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %49 = bitcast i8* %48 to i2* + %50 = load i2, i2* %49 + %51 = load i2, i2* @PauliX + %52 = icmp eq i2 %50, %51 + %53 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %54 = bitcast i8* %53 to i2* + %55 = load i2, i2* %54 + %56 = load i2, i2* @PauliZ + %57 = icmp eq i2 %55, %56 + %58 = and i1 %52, %57 + br i1 %58, label %then4__1, label %test5__1 + +then4__1: ; preds = %test4__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %59 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 1) + %60 = load %Result*, %Result** %res + store %Result* %59, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %59, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %60, i64 -1) + br label %continue__2 + +test5__1: ; preds = %test4__1 + %61 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %62 = bitcast i8* %61 to i2* + %63 = load i2, i2* %62 + %64 = load i2, i2* @PauliZ + %65 = icmp eq i2 %63, %64 + %66 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %67 = bitcast i8* %66 to i2* + %68 = load i2, i2* %67 + %69 = load i2, i2* @PauliX + %70 = icmp eq i2 %68, %69 + %71 = and i1 %65, %70 + br i1 %71, label %then5__1, label %test6__1 + +then5__1: ; preds = %test5__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %72 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %72, i64 1) + %73 = load %Result*, %Result** %res + store %Result* %72, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %72, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %73, i64 -1) + br label %continue__2 + +test6__1: ; preds = %test5__1 + %74 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %75 = bitcast i8* %74 to i2* + %76 = load i2, i2* %75 + %77 = load i2, i2* @PauliZ + %78 = icmp eq i2 %76, %77 + %79 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %80 = bitcast i8* %79 to i2* + %81 = load i2, i2* %80 + %82 = load i2, i2* @PauliZ + %83 = icmp eq i2 %81, %82 + %84 = and i1 %78, %83 + br i1 %84, label %then6__1, label %continue__2 + +then6__1: ; preds = %test6__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %85 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %85, i64 1) + %86 = load %Result*, %Result** %res + store %Result* %85, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %85, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %86, i64 -1) + br label %continue__2 + +continue__2: ; preds = %then6__1, %test6__1, %then5__1, %then4__1, %then3__1, %continue__3, %then1__1, %then0__2 + %87 = load %Result*, %Result** %res + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %87 +} + +declare %Result* @__quantum__qis__joint_measure(i64, i64, %Array*) + +define void @Microsoft__Quantum__Intrinsic__Rx__body(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rx__adj(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rx__ctl(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rx__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__body(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__adj(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__ctl(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Ry__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__body(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__adj(double %theta, %Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__ctl(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Rz__ctladj(%Array* %ctls, { double, %Qubit* }* %0) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %1 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 0 + %theta = load double, double* %1 + %2 = getelementptr inbounds { double, %Qubit* }, { double, %Qubit* }* %0, i32 0, i32 1 + %qb = load %Qubit*, %Qubit** %2 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__T__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +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__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %ctls) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %ctls, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__ctladj(%Array* %__controlQubits__, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 1) + %0 = call i64 @__quantum__rt__array_get_size_1d(%Array* %__controlQubits__) + %1 = icmp eq i64 %0, 1 + br i1 %1, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %__controlQubits__, %Qubit* %qb) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %__controlQubits__, i64 -1) + ret void +} + +define %Tuple* @Microsoft__Quantum__Core__Attribute__body() { +entry: + ret %Tuple* null +} + +define %Tuple* @Microsoft__Quantum__Core__EntryPoint__body() { +entry: + ret %Tuple* null +} + +define %Tuple* @Microsoft__Quantum__Core__Inline__body() { +entry: + ret %Tuple* null +} + +define %Result* @Microsoft__Quantum__Instructions__Mx__body(%Qubit* %qb) { +entry: + %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mxx__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mxz__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mz__body(%Qubit* %qb) { +entry: + %0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mzx__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define %Result* @Microsoft__Quantum__Instructions__Mzz__body(%Array* %qubits) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 1) + %0 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qubits) + call void @__quantum__rt__array_update_alias_count(%Array* %qubits, i64 -1) + ret %Result* %0 +} + +define void @Microsoft__Quantum__Instructions__Sx__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 17, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sx__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 17, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sx__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 18, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sx__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 18, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Sz__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 13, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 13, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 14, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tx__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 14, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__body(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__adj(%Qubit* %qb) { +entry: + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__ctl(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Instructions__Tz__ctladj(%Array* %ctls, %Qubit* %qb) { +entry: + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls, %Qubit* %qb) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Testing__Tracer__Delay__body(%Callable* %op, %Qubit* %arg, %Tuple* %aux) { +entry: + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %op, i64 1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %op, i64 1) + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %Qubit* }* + %2 = getelementptr inbounds { %Qubit* }, { %Qubit* }* %1, i32 0, i32 0 + store %Qubit* %arg, %Qubit** %2 + call void @__quantum__rt__callable_invoke(%Callable* %op, %Tuple* %0, %Tuple* null) + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %op, i64 -1) + call void @__quantum__rt__callable_update_alias_count(%Callable* %op, i64 -1) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %0, i64 -1) + ret void +} + +declare void @__quantum__rt__callable_invoke(%Callable*, %Tuple*, %Tuple*) + +define void @Microsoft__Quantum__Testing__Tracer__TestCoreIntrinsics__body() { +entry: + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 3) + 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 0) + %1 = bitcast i8* %0 to %Qubit** + %qb = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb) + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %3 = bitcast i8* %2 to %Qubit** + %qb__1 = load %Qubit*, %Qubit** %3 + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb__1) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %5 = bitcast i8* %4 to %Qubit** + %qb__2 = load %Qubit*, %Qubit** %5 + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb__2) + %6 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %7 = bitcast i8* %6 to %Qubit** + %qb__3 = load %Qubit*, %Qubit** %7 + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb__3) + %8 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %9 = bitcast i8* %8 to %Qubit** + %10 = load %Qubit*, %Qubit** %9 + %11 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %12 = bitcast i8* %11 to %Qubit** + %13 = load %Qubit*, %Qubit** %12 + call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %10, %Qubit* %13) + %14 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %15 = bitcast i8* %14 to %Qubit** + %qb__4 = load %Qubit*, %Qubit** %15 + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__4) + %16 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %17 = bitcast i8* %16 to %Qubit** + %qb__5 = load %Qubit*, %Qubit** %17 + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb__5) + %18 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %19 = bitcast i8* %18 to %Qubit** + %qb__6 = load %Qubit*, %Qubit** %19 + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb__6) + %20 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %21 = bitcast i8* %20 to %Qubit** + %qb__7 = load %Qubit*, %Qubit** %21 + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb__7) + %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %23 = bitcast i8* %22 to %Qubit** + %qb__9 = load %Qubit*, %Qubit** %23 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__9) + call void @__quantum__qis__inject_barrier(i64 42, i64 0) + %24 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %25 = bitcast i8* %24 to %Qubit** + %qb__11 = load %Qubit*, %Qubit** %25 + call void @__quantum__qis__single_qubit_op(i64 0, i64 1, %Qubit* %qb__11) + %26 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %27 = bitcast i8* %26 to %Qubit** + %qb__13 = load %Qubit*, %Qubit** %27 + call void @__quantum__qis__single_qubit_op(i64 3, i64 1, %Qubit* %qb__13) + %28 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %29 = bitcast i8* %28 to %Qubit** + %qb__15 = load %Qubit*, %Qubit** %29 + call void @__quantum__qis__single_qubit_op(i64 6, i64 1, %Qubit* %qb__15) + %30 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %31 = bitcast i8* %30 to %Qubit** + %qb__17 = load %Qubit*, %Qubit** %31 + call void @__quantum__qis__single_qubit_op(i64 9, i64 1, %Qubit* %qb__17) + %32 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %33 = bitcast i8* %32 to %Qubit** + %34 = load %Qubit*, %Qubit** %33 + %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %36 = bitcast i8* %35 to %Qubit** + %37 = load %Qubit*, %Qubit** %36 + call void @Microsoft__Quantum__Intrinsic__CNOT__adj(%Qubit* %34, %Qubit* %37) + %38 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %39 = bitcast i8* %38 to %Qubit** + %qb__19 = load %Qubit*, %Qubit** %39 + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__19) + %40 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %41 = bitcast i8* %40 to %Qubit** + %qb__20 = load %Qubit*, %Qubit** %41 + call void @__quantum__qis__single_qubit_op(i64 21, i64 1, %Qubit* %qb__20) + %42 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %43 = bitcast i8* %42 to %Qubit** + %qb__21 = load %Qubit*, %Qubit** %43 + call void @__quantum__qis__single_qubit_op(i64 23, i64 1, %Qubit* %qb__21) + %44 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %45 = bitcast i8* %44 to %Qubit** + %qb__22 = load %Qubit*, %Qubit** %45 + call void @__quantum__qis__single_qubit_op(i64 15, i64 1, %Qubit* %qb__22) + %46 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %47 = bitcast i8* %46 to %Qubit** + %qb__24 = load %Qubit*, %Qubit** %47 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__24) + %c = call %Qubit* @__quantum__rt__qubit_allocate() + %ctls = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %48 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls, i64 0) + %49 = bitcast i8* %48 to %Qubit** + store %Qubit* %c, %Qubit** %49 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 1) + %50 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %51 = bitcast i8* %50 to %Qubit** + %qb__26 = load %Qubit*, %Qubit** %51 + br i1 true, label %then0__1, label %else__1 + +then0__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %ctls, %Qubit* %qb__26) + br label %continue__1 + +else__1: ; preds = %entry + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %ctls, %Qubit* %qb__26) + br label %continue__1 + +continue__1: ; preds = %else__1, %then0__1 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls, i64 -1) + %ctls__1 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %52 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__1, i64 0) + %53 = bitcast i8* %52 to %Qubit** + store %Qubit* %c, %Qubit** %53 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 1) + %54 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %55 = bitcast i8* %54 to %Qubit** + %qb__27 = load %Qubit*, %Qubit** %55 + br i1 true, label %then0__2, label %else__2 + +then0__2: ; preds = %continue__1 + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %ctls__1, %Qubit* %qb__27) + br label %continue__2 + +else__2: ; preds = %continue__1 + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %ctls__1, %Qubit* %qb__27) + br label %continue__2 + +continue__2: ; preds = %else__2, %then0__2 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__1, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__1, i64 -1) + %ctls__2 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %56 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__2, i64 0) + %57 = bitcast i8* %56 to %Qubit** + store %Qubit* %c, %Qubit** %57 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__2, i64 1) + %58 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %59 = bitcast i8* %58 to %Qubit** + %qb__28 = load %Qubit*, %Qubit** %59 + br i1 true, label %then0__3, label %else__3 + +then0__3: ; preds = %continue__2 + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %ctls__2, %Qubit* %qb__28) + br label %continue__3 + +else__3: ; preds = %continue__2 + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %ctls__2, %Qubit* %qb__28) + br label %continue__3 + +continue__3: ; preds = %else__3, %then0__3 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__2, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__2, i64 -1) + %ctls__3 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %60 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__3, i64 0) + %61 = bitcast i8* %60 to %Qubit** + store %Qubit* %c, %Qubit** %61 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__3, i64 1) + %62 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %63 = bitcast i8* %62 to %Qubit** + %qb__29 = load %Qubit*, %Qubit** %63 + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %ctls__3, %Qubit* %qb__29) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__3, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__3, i64 -1) + %ctls__4 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %64 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__4, i64 0) + %65 = bitcast i8* %64 to %Qubit** + store %Qubit* %c, %Qubit** %65 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__4, i64 1) + %66 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %67 = bitcast i8* %66 to %Qubit** + %qb__30 = load %Qubit*, %Qubit** %67 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %ctls__4, %Qubit* %qb__30) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__4, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__4, i64 -1) + %ctls__5 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %68 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__5, i64 0) + %69 = bitcast i8* %68 to %Qubit** + store %Qubit* %c, %Qubit** %69 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__5, i64 1) + %70 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %71 = bitcast i8* %70 to %Qubit** + %qb__31 = load %Qubit*, %Qubit** %71 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %ctls__5, %Qubit* %qb__31) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__5, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__5, i64 -1) + %ctls__6 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__6, i64 0) + %73 = bitcast i8* %72 to %Qubit** + store %Qubit* %c, %Qubit** %73 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__6, i64 1) + %74 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %75 = bitcast i8* %74 to %Qubit** + %qb__32 = load %Qubit*, %Qubit** %75 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %ctls__6, %Qubit* %qb__32) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__6, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__6, i64 -1) + %ctls__7 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %76 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__7, i64 0) + %77 = bitcast i8* %76 to %Qubit** + store %Qubit* %c, %Qubit** %77 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 1) + %78 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %79 = bitcast i8* %78 to %Qubit** + %qb__33 = load %Qubit*, %Qubit** %79 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %ctls__7, %Qubit* %qb__33) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__7, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__7, i64 -1) + %ctls__9 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 1) + %80 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %ctls__9, i64 0) + %81 = bitcast i8* %80 to %Qubit** + store %Qubit* %c, %Qubit** %81 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 1) + %82 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %83 = bitcast i8* %82 to %Qubit** + %qb__35 = load %Qubit*, %Qubit** %83 + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %ctls__9, %Qubit* %qb__35) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %ctls__9, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %ctls__9, i64 -1) + call void @__quantum__rt__qubit_release(%Qubit* %c) + %cc = call %Array* @__quantum__rt__qubit_allocate_array(i64 2) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %84 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %85 = bitcast i8* %84 to %Qubit** + %qb__37 = load %Qubit*, %Qubit** %85 + %86 = call i64 @__quantum__rt__array_get_size_1d(%Array* %cc) + %87 = icmp eq i64 %86, 1 + br i1 %87, label %then0__4, label %else__4 + +then0__4: ; preds = %continue__3 + call void @__quantum__qis__single_qubit_op_ctl(i64 1, i64 1, %Array* %cc, %Qubit* %qb__37) + br label %continue__4 + +else__4: ; preds = %continue__3 + call void @__quantum__qis__single_qubit_op_ctl(i64 2, i64 1, %Array* %cc, %Qubit* %qb__37) + br label %continue__4 + +continue__4: ; preds = %else__4, %then0__4 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %88 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %89 = bitcast i8* %88 to %Qubit** + %qb__38 = load %Qubit*, %Qubit** %89 + %90 = icmp eq i64 %86, 1 + br i1 %90, label %then0__5, label %else__5 + +then0__5: ; preds = %continue__4 + call void @__quantum__qis__single_qubit_op_ctl(i64 4, i64 1, %Array* %cc, %Qubit* %qb__38) + br label %continue__5 + +else__5: ; preds = %continue__4 + call void @__quantum__qis__single_qubit_op_ctl(i64 5, i64 1, %Array* %cc, %Qubit* %qb__38) + br label %continue__5 + +continue__5: ; preds = %else__5, %then0__5 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %91 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %92 = bitcast i8* %91 to %Qubit** + %qb__39 = load %Qubit*, %Qubit** %92 + %93 = icmp eq i64 %86, 1 + br i1 %93, label %then0__6, label %else__6 + +then0__6: ; preds = %continue__5 + call void @__quantum__qis__single_qubit_op_ctl(i64 7, i64 1, %Array* %cc, %Qubit* %qb__39) + br label %continue__6 + +else__6: ; preds = %continue__5 + call void @__quantum__qis__single_qubit_op_ctl(i64 8, i64 1, %Array* %cc, %Qubit* %qb__39) + br label %continue__6 + +continue__6: ; preds = %else__6, %then0__6 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %94 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %95 = bitcast i8* %94 to %Qubit** + %qb__40 = load %Qubit*, %Qubit** %95 + call void @__quantum__qis__single_qubit_op_ctl(i64 10, i64 1, %Array* %cc, %Qubit* %qb__40) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %96 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %97 = bitcast i8* %96 to %Qubit** + %qb__41 = load %Qubit*, %Qubit** %97 + call void @__quantum__qis__single_qubit_op_ctl(i64 20, i64 1, %Array* %cc, %Qubit* %qb__41) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %98 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %99 = bitcast i8* %98 to %Qubit** + %qb__42 = load %Qubit*, %Qubit** %99 + call void @__quantum__qis__single_qubit_op_ctl(i64 22, i64 1, %Array* %cc, %Qubit* %qb__42) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %100 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %101 = bitcast i8* %100 to %Qubit** + %qb__43 = load %Qubit*, %Qubit** %101 + call void @__quantum__qis__single_qubit_op_ctl(i64 24, i64 1, %Array* %cc, %Qubit* %qb__43) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %102 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %103 = bitcast i8* %102 to %Qubit** + %qb__44 = load %Qubit*, %Qubit** %103 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 16, i64 1, %Array* %cc, %Qubit* %qb__44) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + %104 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %105 = bitcast i8* %104 to %Qubit** + %qb__46 = load %Qubit*, %Qubit** %105 + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 1) + call void @__quantum__qis__single_qubit_op_ctl(i64 12, i64 1, %Array* %cc, %Qubit* %qb__46) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__qubit_release_array(%Array* %cc) + call void @__quantum__rt__array_update_alias_count(%Array* %cc, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %cc, 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 %Qubit* @__quantum__rt__qubit_allocate() + +declare %Array* @__quantum__rt__qubit_allocate_array(i64) + +declare void @__quantum__qis__inject_barrier(i64, i64) + +declare void @__quantum__rt__qubit_release(%Qubit*) + +declare void @__quantum__rt__qubit_release_array(%Array*) + +define void @Microsoft__Quantum__Testing__Tracer__TestMeasurements__body() { +entry: + %qs = call %Array* @__quantum__rt__qubit_allocate_array(i64 6) + 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 0) + %1 = bitcast i8* %0 to %Qubit** + %qb = load %Qubit*, %Qubit** %1 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb) + %2 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 0) + %3 = bitcast i8* %2 to %Qubit** + %qb__2 = load %Qubit*, %Qubit** %3 + %r0 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__2) + %4 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %5 = bitcast i8* %4 to %Qubit** + %qb__4 = load %Qubit*, %Qubit** %5 + call void @__quantum__qis__single_qubit_op(i64 11, i64 1, %Qubit* %qb__4) + %6 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %7 = bitcast i8* %6 to %Qubit** + %8 = load %Qubit*, %Qubit** %7 + %9 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %10 = bitcast i8* %9 to %Qubit** + %11 = load %Qubit*, %Qubit** %10 + call void @Microsoft__Quantum__Intrinsic__CNOT__body(%Qubit* %8, %Qubit* %11) + %qs12 = call %Array* @__quantum__rt__array_create_1d(i32 8, i64 2) + %12 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) + %13 = bitcast i8* %12 to %Qubit** + %14 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 1) + %15 = bitcast i8* %14 to %Qubit** + %16 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 1) + %17 = bitcast i8* %16 to %Qubit** + %18 = load %Qubit*, %Qubit** %17 + %19 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 2) + %20 = bitcast i8* %19 to %Qubit** + %21 = load %Qubit*, %Qubit** %20 + store %Qubit* %18, %Qubit** %13 + store %Qubit* %21, %Qubit** %15 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %paulis = call %Array* @__quantum__rt__array_create_1d(i32 1, i64 2) + %22 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %23 = bitcast i8* %22 to i2* + %24 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %25 = bitcast i8* %24 to i2* + %26 = load i2, i2* @PauliY + %27 = load i2, i2* @PauliX + store i2 %26, i2* %23 + store i2 %27, i2* %25 + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 1) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %28 = load %Result*, %Result** @ResultOne + %res = alloca %Result* + store %Result* %28, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 1) + %haveY = alloca i1 + store i1 false, i1* %haveY + br label %header__1 + +header__1: ; preds = %exiting__1, %entry + %i = phi i64 [ 0, %entry ], [ %41, %exiting__1 ] + %29 = icmp sle i64 %i, 1 + br i1 %29, label %body__1, label %exit__1 + +body__1: ; preds = %header__1 + %30 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %31 = bitcast i8* %30 to i2* + %32 = load i2, i2* %31 + %33 = load i2, i2* @PauliY + %34 = icmp eq i2 %32, %33 + %35 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 %i) + %36 = bitcast i8* %35 to i2* + %37 = load i2, i2* %36 + %38 = load i2, i2* @PauliI + %39 = icmp eq i2 %37, %38 + %40 = or i1 %34, %39 + br i1 %40, label %then0__1, label %continue__1 + +then0__1: ; preds = %body__1 + store i1 true, i1* %haveY + br label %continue__1 + +continue__1: ; preds = %then0__1, %body__1 + br label %exiting__1 + +exiting__1: ; preds = %continue__1 + %41 = add i64 %i, 1 + br label %header__1 + +exit__1: ; preds = %header__1 + %42 = load i1, i1* %haveY + br i1 %42, label %then0__2, label %test1__1 + +then0__2: ; preds = %exit__1 + %43 = call %Result* @__quantum__qis__joint_measure(i64 106, i64 1, %Array* %qs12) + call void @__quantum__rt__result_update_reference_count(%Result* %43, i64 1) + store %Result* %43, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %43, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %28, i64 -1) + br label %continue__2 + +test1__1: ; preds = %exit__1 + br i1 false, label %then1__1, label %test2__1 + +then1__1: ; preds = %test1__1 + %44 = call %Result* @__quantum__qis__joint_measure(i64 107, i64 1, %Array* %qs12) + call void @__quantum__rt__result_update_reference_count(%Result* %44, i64 1) + %45 = load %Result*, %Result** %res + store %Result* %44, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %44, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %45, i64 -1) + br label %continue__2 + +test2__1: ; preds = %test1__1 + br i1 false, label %then2__1, label %test3__1 + +then2__1: ; preds = %test2__1 + %46 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %47 = bitcast i8* %46 to i2* + %48 = load i2, i2* %47 + %49 = load i2, i2* @PauliX + %50 = icmp eq i2 %48, %49 + br i1 %50, label %then0__3, label %else__1 + +then0__3: ; preds = %then2__1 + %51 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) + %52 = bitcast i8* %51 to %Qubit** + %qb__6 = load %Qubit*, %Qubit** %52 + %53 = call %Result* @__quantum__qis__single_qubit_measure(i64 101, i64 1, %Qubit* %qb__6) + call void @__quantum__rt__result_update_reference_count(%Result* %53, i64 1) + %54 = load %Result*, %Result** %res + store %Result* %53, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %53, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %54, i64 -1) + br label %continue__3 + +else__1: ; preds = %then2__1 + %55 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs12, i64 0) + %56 = bitcast i8* %55 to %Qubit** + %qb__7 = load %Qubit*, %Qubit** %56 + %57 = call %Result* @__quantum__qis__single_qubit_measure(i64 100, i64 1, %Qubit* %qb__7) + call void @__quantum__rt__result_update_reference_count(%Result* %57, i64 1) + %58 = load %Result*, %Result** %res + store %Result* %57, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %57, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %58, i64 -1) + br label %continue__3 + +continue__3: ; preds = %else__1, %then0__3 + br label %continue__2 + +test3__1: ; preds = %test2__1 + %59 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %60 = bitcast i8* %59 to i2* + %61 = load i2, i2* %60 + %62 = load i2, i2* @PauliX + %63 = icmp eq i2 %61, %62 + %64 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %65 = bitcast i8* %64 to i2* + %66 = load i2, i2* %65 + %67 = load i2, i2* @PauliX + %68 = icmp eq i2 %66, %67 + %69 = and i1 %63, %68 + br i1 %69, label %then3__1, label %test4__1 + +then3__1: ; preds = %test3__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %70 = call %Result* @__quantum__qis__joint_measure(i64 105, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %70, i64 1) + %71 = load %Result*, %Result** %res + store %Result* %70, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %70, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %71, i64 -1) + br label %continue__2 + +test4__1: ; preds = %test3__1 + %72 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %73 = bitcast i8* %72 to i2* + %74 = load i2, i2* %73 + %75 = load i2, i2* @PauliX + %76 = icmp eq i2 %74, %75 + %77 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %78 = bitcast i8* %77 to i2* + %79 = load i2, i2* %78 + %80 = load i2, i2* @PauliZ + %81 = icmp eq i2 %79, %80 + %82 = and i1 %76, %81 + br i1 %82, label %then4__1, label %test5__1 + +then4__1: ; preds = %test4__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %83 = call %Result* @__quantum__qis__joint_measure(i64 103, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %83, i64 1) + %84 = load %Result*, %Result** %res + store %Result* %83, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %83, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %84, i64 -1) + br label %continue__2 + +test5__1: ; preds = %test4__1 + %85 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %86 = bitcast i8* %85 to i2* + %87 = load i2, i2* %86 + %88 = load i2, i2* @PauliZ + %89 = icmp eq i2 %87, %88 + %90 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %91 = bitcast i8* %90 to i2* + %92 = load i2, i2* %91 + %93 = load i2, i2* @PauliX + %94 = icmp eq i2 %92, %93 + %95 = and i1 %89, %94 + br i1 %95, label %then5__1, label %test6__1 + +then5__1: ; preds = %test5__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %96 = call %Result* @__quantum__qis__joint_measure(i64 104, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %96, i64 1) + %97 = load %Result*, %Result** %res + store %Result* %96, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %96, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %97, i64 -1) + br label %continue__2 + +test6__1: ; preds = %test5__1 + %98 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 0) + %99 = bitcast i8* %98 to i2* + %100 = load i2, i2* %99 + %101 = load i2, i2* @PauliZ + %102 = icmp eq i2 %100, %101 + %103 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %paulis, i64 1) + %104 = bitcast i8* %103 to i2* + %105 = load i2, i2* %104 + %106 = load i2, i2* @PauliZ + %107 = icmp eq i2 %105, %106 + %108 = and i1 %102, %107 + br i1 %108, label %then6__1, label %continue__2 + +then6__1: ; preds = %test6__1 + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 1) + %109 = call %Result* @__quantum__qis__joint_measure(i64 102, i64 1, %Array* %qs12) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %109, i64 1) + %110 = load %Result*, %Result** %res + store %Result* %109, %Result** %res + call void @__quantum__rt__result_update_reference_count(%Result* %109, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %110, i64 -1) + br label %continue__2 + +continue__2: ; preds = %then6__1, %test6__1, %then5__1, %then4__1, %then3__1, %continue__3, %then1__1, %then0__2 + %r12 = load %Result*, %Result** %res + call void @__quantum__rt__array_update_alias_count(%Array* %paulis, i64 -1) + call void @__quantum__rt__array_update_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %paulis, i64 -1) + %111 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %112 = bitcast %Tuple* %111 to { %Callable*, %Callable*, %Qubit* }* + %113 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 0 + %114 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 1 + %115 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %112, i32 0, i32 2 + %116 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %117 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__X, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %118 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 3) + %119 = bitcast i8* %118 to %Qubit** + %120 = load %Qubit*, %Qubit** %119 + store %Callable* %116, %Callable** %113 + store %Callable* %117, %Callable** %114 + store %Qubit* %120, %Qubit** %115 + %121 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__1, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %111) + %122 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %123 = bitcast %Tuple* %122 to { %Callable*, %Callable*, %Qubit* }* + %124 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 0 + %125 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 1 + %126 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %123, i32 0, i32 2 + %127 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %128 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__Y, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %129 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 3) + %130 = bitcast i8* %129 to %Qubit** + %131 = load %Qubit*, %Qubit** %130 + store %Callable* %127, %Callable** %124 + store %Callable* %128, %Callable** %125 + store %Qubit* %131, %Qubit** %126 + %132 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__2, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %122) + call void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %r0, %Callable* %121, %Callable* %132) + %133 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %134 = bitcast %Tuple* %133 to { %Callable*, %Callable*, %Qubit* }* + %135 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 0 + %136 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 1 + %137 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %134, i32 0, i32 2 + %138 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %139 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__Z, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %140 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 4) + %141 = bitcast i8* %140 to %Qubit** + %142 = load %Qubit*, %Qubit** %141 + store %Callable* %138, %Callable** %135 + store %Callable* %139, %Callable** %136 + store %Qubit* %142, %Qubit** %137 + %143 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__3, [2 x void (%Tuple*, i64)*]* @MemoryManagement__1, %Tuple* %133) + %144 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %145 = bitcast %Tuple* %144 to { %Callable*, %Callable*, %Qubit* }* + %146 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 0 + %147 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 1 + %148 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %145, i32 0, i32 2 + %149 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Testing__Tracer__Delay, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %150 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @Microsoft__Quantum__Intrinsic__S, [2 x void (%Tuple*, i64)*]* null, %Tuple* null) + %151 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 4) + %152 = bitcast i8* %151 to %Qubit** + %153 = load %Qubit*, %Qubit** %152 + store %Callable* %149, %Callable** %146 + store %Callable* %150, %Callable** %147 + store %Qubit* %153, %Qubit** %148 + %154 = call %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]* @PartialApplication__4, [2 x void (%Tuple*, i64)*]* @MemoryManagement__2, %Tuple* %144) + call void @Microsoft__Quantum__Intrinsic__ApplyIfElseIntrinsic__body(%Result* %r12, %Callable* %143, %Callable* %154) + %155 = call i8* @__quantum__rt__array_get_element_ptr_1d(%Array* %qs, i64 5) + %156 = bitcast i8* %155 to %Qubit** + %qb__8 = load %Qubit*, %Qubit** %156 + call void @__quantum__qis__single_qubit_op(i64 19, i64 1, %Qubit* %qb__8) + 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_alias_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %r0, i64 -1) + call void @__quantum__rt__array_update_reference_count(%Array* %qs12, i64 -1) + call void @__quantum__rt__result_update_reference_count(%Result* %r12, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %121, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %121, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %132, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %132, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %143, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %143, i64 -1) + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %154, i64 -1) + call void @__quantum__rt__callable_update_reference_count(%Callable* %154, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Testing__Tracer__Delay__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %arg-tuple to { %Callable*, %Qubit*, %Tuple* }* + %1 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 0 + %2 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 1 + %3 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %0, i32 0, i32 2 + %4 = load %Callable*, %Callable** %1 + %5 = load %Qubit*, %Qubit** %2 + %6 = load %Tuple*, %Tuple** %3 + call void @Microsoft__Quantum__Testing__Tracer__Delay__body(%Callable* %4, %Qubit* %5, %Tuple* %6) + ret void +} + +declare %Callable* @__quantum__rt__callable_create([4 x void (%Tuple*, %Tuple*, %Tuple*)*]*, [2 x void (%Tuple*, i64)*]*, %Tuple*) + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__X__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 + call void @Microsoft__Quantum__Intrinsic__X__ctladj(%Array* %3, %Qubit* %4) + ret void +} + +define void @Lifted__PartialApplication__1__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @MemoryManagement__1__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %4, 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*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %4, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Y__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 + call void @Microsoft__Quantum__Intrinsic__Y__ctladj(%Array* %3, %Qubit* %4) + 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*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__Z__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 + call void @Microsoft__Quantum__Intrinsic__Z__ctladj(%Array* %3, %Qubit* %4) + ret void +} + +define void @Lifted__PartialApplication__3__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__body(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__adj(%Qubit* %2) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__ctl(%Array* %3, %Qubit* %4) + ret void +} + +define void @Microsoft__Quantum__Intrinsic__S__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 + call void @Microsoft__Quantum__Intrinsic__S__ctladj(%Array* %3, %Qubit* %4) + ret void +} + +define void @Lifted__PartialApplication__4__body__wrapper(%Tuple* %capture-tuple, %Tuple* %arg-tuple, %Tuple* %result-tuple) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %2 = load %Callable*, %Callable** %1 + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 2 + %4 = load %Qubit*, %Qubit** %3 + %5 = bitcast %Tuple* %arg-tuple to { %Tuple* }* + %6 = getelementptr inbounds { %Tuple* }, { %Tuple* }* %5, i32 0, i32 0 + %7 = load %Tuple*, %Tuple** %6 + %8 = call %Tuple* @__quantum__rt__tuple_create(i64 mul nuw (i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64), i64 3)) + %9 = bitcast %Tuple* %8 to { %Callable*, %Qubit*, %Tuple* }* + %10 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 0 + %11 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 1 + %12 = getelementptr inbounds { %Callable*, %Qubit*, %Tuple* }, { %Callable*, %Qubit*, %Tuple* }* %9, i32 0, i32 2 + store %Callable* %2, %Callable** %10 + store %Qubit* %4, %Qubit** %11 + store %Tuple* %7, %Tuple** %12 + %13 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 0 + %14 = load %Callable*, %Callable** %13 + call void @__quantum__rt__callable_invoke(%Callable* %14, %Tuple* %8, %Tuple* %result-tuple) + call void @__quantum__rt__tuple_update_reference_count(%Tuple* %8, i64 -1) + ret void +} + +define void @MemoryManagement__2__RefCount(%Tuple* %capture-tuple, i64 %count-change) { +entry: + %0 = bitcast %Tuple* %capture-tuple to { %Callable*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 0, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_reference_count(%Callable* %4, 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*, %Callable*, %Qubit* }* + %1 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %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) + %3 = getelementptr inbounds { %Callable*, %Callable*, %Qubit* }, { %Callable*, %Callable*, %Qubit* }* %0, i32 0, i32 1 + %4 = load %Callable*, %Callable** %3 + call void @__quantum__rt__callable_memory_management(i32 1, %Callable* %4, i64 %count-change) + call void @__quantum__rt__callable_update_alias_count(%Callable* %4, i64 %count-change) + call void @__quantum__rt__tuple_update_alias_count(%Tuple* %capture-tuple, i64 %count-change) + ret void +} + +declare void @__quantum__rt__callable_update_reference_count(%Callable*, i64) + +define { %String* }* @Microsoft__Quantum__Targeting__TargetInstruction__body(%String* %__Item1__) { +entry: + %0 = call %Tuple* @__quantum__rt__tuple_create(i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)) + %1 = bitcast %Tuple* %0 to { %String* }* + %2 = getelementptr inbounds { %String* }, { %String* }* %1, i32 0, i32 0 + store %String* %__Item1__, %String** %2 + call void @__quantum__rt__string_update_reference_count(%String* %__Item1__, i64 1) + ret { %String* }* %1 +} + +declare void @__quantum__rt__string_update_reference_count(%String*, i64) + +declare void @__quantum__rt__tuple_update_alias_count(%Tuple*, i64) From 74e19af6484c852a323ecedb72a39af5367800e8 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 17:45:48 +0000 Subject: [PATCH 24/31] move build and test of QIR to after sln --- build/build.ps1 | 22 ++++++++++------------ build/test.ps1 | 23 +++++++++++------------ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/build/build.ps1 b/build/build.ps1 index 3af9ece1dc0..9ff2e82b758 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -16,18 +16,6 @@ if ($Env:ENABLE_NATIVE -ne "false") { Write-Host "Skipping build of native simulator because ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE." } - -if ($Env:ENABLE_QIRRUNTIME -eq "true") { - $qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime") - & "$qirRuntime/build-qir-runtime.ps1" - if ($LastExitCode -ne 0) { - $script:all_ok = $False - } -} else { - Write-Host "Skipping build of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME" -} - - function Build-One { param( [string]$action, @@ -57,6 +45,16 @@ Build-One 'publish' '../src/Simulation/CSharpGeneration.App' Build-One 'build' '../Simulation.sln' +if ($Env:ENABLE_QIRRUNTIME -eq "true") { + $qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime") + & "$qirRuntime/build-qir-runtime.ps1" + if ($LastExitCode -ne 0) { + $script:all_ok = $False + } +} else { + Write-Host "Skipping build of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME" +} + if (-not $all_ok) { throw "At least one project failed to compile. Check the logs." } diff --git a/build/test.ps1 b/build/test.ps1 index d1941939ecd..cc2e0507a28 100644 --- a/build/test.ps1 +++ b/build/test.ps1 @@ -13,18 +13,6 @@ if ($Env:ENABLE_NATIVE -ne "false") { } else { Write-Host "Skipping test of native simulator because ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE." } - -if (($Env:ENABLE_NATIVE -ne "false") -and ($Env:ENABLE_QIRRUNTIME -eq "true")) { - $qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime") - & "$qirRuntime/test-qir-runtime.ps1" - if ($LastExitCode -ne 0) { - $script:all_ok = $False - } -} else { - Write-Host "Skipping test of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME ` - and ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE." -} - function Test-One { Param($project) @@ -49,6 +37,17 @@ function Test-One { Test-One '../Simulation.sln' +if (($Env:ENABLE_NATIVE -ne "false") -and ($Env:ENABLE_QIRRUNTIME -eq "true")) { + $qirRuntime = (Join-Path $PSScriptRoot "../src/QirRuntime") + & "$qirRuntime/test-qir-runtime.ps1" + if ($LastExitCode -ne 0) { + $script:all_ok = $False + } +} else { + Write-Host "Skipping test of qir runtime because ENABLE_QIRRUNTIME variable is set to: $Env:ENABLE_QIRRUNTIME ` + and ENABLE_NATIVE variable is set to: $Env:ENABLE_NATIVE." +} + if (-not $all_ok) { throw "At least one project failed during testing. Check the logs." } From ac74215b77e237a6978d330df8ee1a8586bd16d1 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Mon, 8 Mar 2021 18:06:46 +0000 Subject: [PATCH 25/31] Update build scripts and readme --- build/set-env.ps1 | 6 +- src/QirRuntime/README.md | 13 +-- src/QirRuntime/build-qir-runtime.ps1 | 146 +++++++++++++-------------- src/QirRuntime/test-qir-runtime.ps1 | 24 ++--- 4 files changed, 85 insertions(+), 104 deletions(-) diff --git a/build/set-env.ps1 b/build/set-env.ps1 index fe39a1224ec..9d9e79c6c83 100644 --- a/build/set-env.ps1 +++ b/build/set-env.ps1 @@ -11,10 +11,8 @@ If ($Env:BUILD_VERBOSITY -eq $null) { $Env:BUILD_VERBOSITY ="m" } If ($Env:ASSEMBLY_VERSION -eq $null) { $Env:ASSEMBLY_VERSION ="$Env:BUILD_BUILDNUMBER" } If ($Env:NUGET_VERSION -eq $null) { $Env:NUGET_VERSION ="$Env:ASSEMBLY_VERSION-alpha" } -If ($Env:ENABLE_QIRRUNTIME -eq "true") { - If (($Env:ENABLE_NATIVE -ne "false") -and ($Env:NATIVE_SIMULATOR -eq $null) ) { - $Env:NATIVE_SIMULATOR = (Join-Path $PSScriptRoot "..\src\Simulation\Native\build\drop") - } +If (($Env:ENABLE_NATIVE -ne "false") -and ($Env:NATIVE_SIMULATOR -eq $null) ) { + $Env:NATIVE_SIMULATOR = (Join-Path $PSScriptRoot "..\src\Simulation\Native\build\drop") } If ($Env:DROPS_DIR -eq $null) { $Env:DROPS_DIR = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\drops")) } diff --git a/src/QirRuntime/README.md b/src/QirRuntime/README.md index fcf60b28d82..af95086dddf 100644 --- a/src/QirRuntime/README.md +++ b/src/QirRuntime/README.md @@ -22,16 +22,9 @@ You can use CMake directly. For example, to produce a release build: 4. cmake -G Ninja -DCMAKE_BUILD_TYPE=Release .. 5. cmake --build . -Or you can run `build.py` script from QirRuntime folder. The default options for the script are `make debug`. +Or you can run `build-qir-runtime.ps1` script from QirRuntime folder. The script will place the build artifacts into `build/[Debug|Release]` folder. We strongly recommend doing local builds using the build script because it also runs clang-tidy if it is installed. -- (Windows) `python build.py [make/nomake] [debug|release] [noqirgen]` -- (Linux) `python3 build.py [make/nomake] [debug|release] [noqirgen]` - -The script will place the build artifacts into `build/[Windows|Linux]/[Debug|Release]` folder. We strongly recommend - doing local builds using the build script because it also runs clang-tidy. - -CI builds and tests are enabled for this project. The build has no external dependencies, but some of the tests depend - on `Microsoft.Quantum.Simulator.Runtime` library. +CI builds and tests are enabled for this project. The build for `test/QIR-static/qsharp/qir-gen.csproj` has project dependencies on other parts of the runtime and may trigger a build for those components, while some of the tests depend on `Microsoft.Quantum.Simulator.Runtime` dynamic library built from. ### Windows pre-reqs @@ -40,7 +33,6 @@ CI builds and tests are enabled for this project. The build has no external depe 1. Install VS 2019 and enable "Desktop development with C++" component (Clang uses MSVC's standard library on Windows). 1. Install clang-tidy and clang-format if your Clang/LLVM packages didn't include the tools. 1. Install the same version of dotnet as specified by qsharp-runtime [README](../../README.md) -1. <_optional_> To use build/test scripts install Python 3.8. *Building from Visual Studio and VS Code is **not** supported. Running cmake from the editors will likely default to MSVC or clang-cl and fail.* @@ -58,7 +50,6 @@ Running cmake from the editors will likely default to MSVC or clang-cl and fail. - $ export CXX=/usr/bin/clang++-11 1. `$ sudo apt install clang-tidy-11` (`$ clang-tidy-11 --version` should return 'LLVM version 11.0.0') 1. Install the same version of dotnet as specified by qsharp-runtime [README](../../README.md) - 1. <_optional_> To use build/test scripts, check that you have python3 installed (it should be by default). See [https://code.visualstudio.com/docs/remote/wsl] on how to use VS Code with WSL. diff --git a/src/QirRuntime/build-qir-runtime.ps1 b/src/QirRuntime/build-qir-runtime.ps1 index 010c6d04a3b..778ec099cc8 100644 --- a/src/QirRuntime/build-qir-runtime.ps1 +++ b/src/QirRuntime/build-qir-runtime.ps1 @@ -1,86 +1,86 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -if ($Env:ENABLE_QIRRUNTIME -eq "true") { - & (Join-Path $PSScriptRoot .. .. build set-env.ps1) - Write-Host "##[info]Compile Q# Projects into QIR" - $qirStaticPath = Join-Path $PSScriptRoot test QIR-static qsharp - dotnet build $qirStaticPath -c $Env:BUILD_CONFIGURATION -v $Env:BUILD_VERBOSITY - if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to compile Q# project at '$qirStaticPath' into QIR." - return - } - Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination (Split-Path $qirStaticPath -Parent) - # Also copy to drops so it ends up in build artifacts, for easier post-build debugging. - Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination $Env:DROPS_DIR +& (Join-Path $PSScriptRoot .. .. build set-env.ps1) +Write-Host "##[info]Compile Q# Projects into QIR" +$qirStaticPath = Join-Path $PSScriptRoot test QIR-static qsharp +dotnet build $qirStaticPath -c $Env:BUILD_CONFIGURATION -v $Env:BUILD_VERBOSITY +if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to compile Q# project at '$qirStaticPath' into QIR." + return +} +Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination (Split-Path $qirStaticPath -Parent) +# Also copy to drops so it ends up in build artifacts, for easier post-build debugging. +Copy-Item -Path (Join-Path $qirStaticPath qir *.ll) -Destination $Env:DROPS_DIR - Write-Host "##[info]Build QIR Runtime" - $oldCC = $env:CC - $oldCXX = $env:CXX - $oldRC = $env:RC +Write-Host "##[info]Build QIR Runtime" +$oldCC = $env:CC +$oldCXX = $env:CXX +$oldRC = $env:RC - $clangTidy = "" +$clangTidy = "" - if (($IsMacOS) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Darwin")))) - { - Write-Host "On MacOS build QIR Runtim using the default C/C++ compiler (should be AppleClang)" - } - elseif (($IsLinux) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Lin")))) - { - Write-Host "On Linux build QIR Runtime using Clang" - $env:CC = "/usr/bin/clang-11" - $env:CXX = "/usr/bin/clang++-11" - $env:RC = "/usr/bin/clang++-11" - $clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy-11" - } - elseif (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win")))) - { - Write-Host "On Windows build QIR Runtime using Clang" - $env:CC = "C:\Program Files\LLVM\bin\clang.exe" - $env:CXX = "C:\Program Files\LLVM\bin\clang++.exe" - $env:RC = "C:\Program Files\LLVM\bin\clang++.exe" - $llvmExtras = (Join-Path $PSScriptRoot "externals/LLVM") - $env:PATH += ";$llvmExtras" - } else { - Write-Host "##vso[task.logissue type=error;]Failed to identify the OS. Will use default CXX compiler" - } +if (($IsMacOS) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Darwin")))) +{ + Write-Host "On MacOS build QIR Runtim using the default C/C++ compiler (should be AppleClang)" +} +elseif (($IsLinux) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Lin")))) +{ + Write-Host "On Linux build QIR Runtime using Clang" + $env:CC = "/usr/bin/clang-11" + $env:CXX = "/usr/bin/clang++-11" + $env:RC = "/usr/bin/clang++-11" + $clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy-11" +} +elseif (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win")))) +{ + Write-Host "On Windows build QIR Runtime using Clang" + $env:CC = "C:\Program Files\LLVM\bin\clang.exe" + $env:CXX = "C:\Program Files\LLVM\bin\clang++.exe" + $env:RC = "C:\Program Files\LLVM\bin\clang++.exe" + $llvmExtras = (Join-Path $PSScriptRoot "externals/LLVM") + $env:PATH += ";$llvmExtras" - $qirRuntimeBuildFolder = (Join-Path $PSScriptRoot "build\$Env:BUILD_CONFIGURATION") - if (-not (Test-Path $qirRuntimeBuildFolder)) { - New-Item -Path $qirRuntimeBuildFolder -ItemType "directory" + if (Get-Command clang-tidy -ErrorAction SilentlyContinue) { + $clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy" } +} else { + Write-Host "##vso[task.logissue type=error;]Failed to identify the OS. Will use default CXX compiler" +} - Push-Location $qirRuntimeBuildFolder - - cmake -G Ninja $clangTidy -D CMAKE_BUILD_TYPE="$Env:BUILD_CONFIGURATION" ../.. - if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to generate QIR Runtime." - } - cmake --build . --target install - if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to build QIR Runtime." - } +$qirRuntimeBuildFolder = (Join-Path $PSScriptRoot "build\$Env:BUILD_CONFIGURATION") +if (-not (Test-Path $qirRuntimeBuildFolder)) { + New-Item -Path $qirRuntimeBuildFolder -ItemType "directory" +} - $os = "win32" - $pattern = "*.dll" - if ($IsMacOS) { - $os = "osx" - $pattern = "*.dylib" - } elseif ($IsLinux) { - $os = "linux" - $pattern = "*.so" - } - $osQirDropFolder = Join-Path $Env:DROPS_DIR QIR $os - if (!(Test-Path $osQirDropFolder)) { - New-Item -Path $osQirDropFolder -ItemType "directory" - } - Copy-Item (Join-Path . bin $pattern) $osQirDropFolder +Push-Location $qirRuntimeBuildFolder - Pop-Location +cmake -G Ninja $clangTidy -D CMAKE_BUILD_TYPE="$Env:BUILD_CONFIGURATION" ../.. +if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to generate QIR Runtime." +} +cmake --build . --target install +if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to build QIR Runtime." +} - $env:CC = $oldCC - $env:CXX = $oldCXX - $env:RC = $oldRC -} else { - Write-Host "To enable build of QIR Runtime set ENABLE_QIRRUNTIME environment variable to 'true'" +$os = "win32" +$pattern = "*.dll" +if ($IsMacOS) { + $os = "osx" + $pattern = "*.dylib" +} elseif ($IsLinux) { + $os = "linux" + $pattern = "*.so" +} +$osQirDropFolder = Join-Path $Env:DROPS_DIR QIR $os +if (!(Test-Path $osQirDropFolder)) { + New-Item -Path $osQirDropFolder -ItemType "directory" } +Copy-Item (Join-Path . bin $pattern) $osQirDropFolder + +Pop-Location + +$env:CC = $oldCC +$env:CXX = $oldCXX +$env:RC = $oldRC diff --git a/src/QirRuntime/test-qir-runtime.ps1 b/src/QirRuntime/test-qir-runtime.ps1 index c8cd5ffd121..663231acfbf 100644 --- a/src/QirRuntime/test-qir-runtime.ps1 +++ b/src/QirRuntime/test-qir-runtime.ps1 @@ -1,23 +1,15 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -if ($Env:ENABLE_NATIVE -ne "false") { - if ($Env:ENABLE_QIRRUNTIME -eq "true") { - Write-Host "##[info]Test QIR Runtime" +Write-Host "##[info]Test QIR Runtime" - Push-Location (Join-Path $PSScriptRoot build $Env:BUILD_CONFIGURATION test) +Push-Location (Join-Path $PSScriptRoot build $Env:BUILD_CONFIGURATION test) - ctest --verbose +ctest --verbose - if ($LastExitCode -ne 0) { - Write-Host "##vso[task.logissue type=error;]Failed to test QIR Runtime" - $script:all_ok = $False - } - - Pop-Location - } else { - Write-Host "Skipping testing qir runtime because ENABLE_QIRRUNTIME variable set to: $Env:ENABLE_QIRRUNTIME." - } -} else { - Write-Host "Skipping native components because ENABLE_NATIVE variable set to: $Env:ENABLE_NATIVE." +if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to test QIR Runtime" + $script:all_ok = $False } + +Pop-Location From 725b07ab1b8194e63a082d9bfe5fd519b22cf355 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Mar 2021 03:01:06 +0000 Subject: [PATCH 26/31] Update build scripts for PR feedback --- src/QirRuntime/README.md | 2 ++ src/QirRuntime/build-qir-runtime.ps1 | 17 ++++++++++------- src/QirRuntime/prerequisites.ps1 | 3 ++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/QirRuntime/README.md b/src/QirRuntime/README.md index af95086dddf..cf52bd09e6b 100644 --- a/src/QirRuntime/README.md +++ b/src/QirRuntime/README.md @@ -26,6 +26,8 @@ Or you can run `build-qir-runtime.ps1` script from QirRuntime folder. The script CI builds and tests are enabled for this project. The build for `test/QIR-static/qsharp/qir-gen.csproj` has project dependencies on other parts of the runtime and may trigger a build for those components, while some of the tests depend on `Microsoft.Quantum.Simulator.Runtime` dynamic library built from. +To install prerequisite tools for building the QIR runtime, you can set the `ENABLE_QIRRUNTIME` environment variable to the string `"true"` and run `prerequisites.ps1` or manually install pre-reqs with the steps listed below. + ### Windows pre-reqs 1. Install Clang 11, Ninja and CMake from the public distros. diff --git a/src/QirRuntime/build-qir-runtime.ps1 b/src/QirRuntime/build-qir-runtime.ps1 index 778ec099cc8..5bee2d51695 100644 --- a/src/QirRuntime/build-qir-runtime.ps1 +++ b/src/QirRuntime/build-qir-runtime.ps1 @@ -22,26 +22,29 @@ $clangTidy = "" if (($IsMacOS) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Darwin")))) { - Write-Host "On MacOS build QIR Runtim using the default C/C++ compiler (should be AppleClang)" + Write-Host "On MacOS build QIR Runtime using the default C/C++ compiler (should be AppleClang)" } elseif (($IsLinux) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Lin")))) { Write-Host "On Linux build QIR Runtime using Clang" - $env:CC = "/usr/bin/clang-11" - $env:CXX = "/usr/bin/clang++-11" - $env:RC = "/usr/bin/clang++-11" + $env:CC = "clang-11" + $env:CXX = "clang++-11" + $env:RC = "clang++-11" $clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy-11" } elseif (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win")))) { Write-Host "On Windows build QIR Runtime using Clang" - $env:CC = "C:\Program Files\LLVM\bin\clang.exe" - $env:CXX = "C:\Program Files\LLVM\bin\clang++.exe" - $env:RC = "C:\Program Files\LLVM\bin\clang++.exe" + $env:CC = "clang.exe" + $env:CXX = "clang++.exe" + $env:RC = "clang++.exe" $llvmExtras = (Join-Path $PSScriptRoot "externals/LLVM") $env:PATH += ";$llvmExtras" if (Get-Command clang-tidy -ErrorAction SilentlyContinue) { + # Only run clang-tidy if it's installed. This is because the package used by chocolatey on + # the build pipeline doesn't include clang-tidy, so we allow skipping that there and let + # the Linux build catch tidy issues. $clangTidy = "-DCMAKE_CXX_CLANG_TIDY=clang-tidy" } } else { diff --git a/src/QirRuntime/prerequisites.ps1 b/src/QirRuntime/prerequisites.ps1 index 66a03ff8f78..17b9b0633ca 100644 --- a/src/QirRuntime/prerequisites.ps1 +++ b/src/QirRuntime/prerequisites.ps1 @@ -2,7 +2,8 @@ # Licensed under the MIT License. if ($Env:ENABLE_QIRRUNTIME -eq "true") { - if (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win")))) { + if (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWith("Win"))) -and + !(Get-Command clang -ErrorAction SilentlyContinue)) { choco install llvm choco install ninja } elseif ($IsMacOS) { From b01e2ebccf0062e83abd3d03e565b500ea28b289 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Mar 2021 03:41:53 +0000 Subject: [PATCH 27/31] Fix qir build with dynamic path update --- src/QirRuntime/README.md | 2 +- src/QirRuntime/build-qir-runtime.ps1 | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/QirRuntime/README.md b/src/QirRuntime/README.md index cf52bd09e6b..3a7f2e4b69b 100644 --- a/src/QirRuntime/README.md +++ b/src/QirRuntime/README.md @@ -26,7 +26,7 @@ Or you can run `build-qir-runtime.ps1` script from QirRuntime folder. The script CI builds and tests are enabled for this project. The build for `test/QIR-static/qsharp/qir-gen.csproj` has project dependencies on other parts of the runtime and may trigger a build for those components, while some of the tests depend on `Microsoft.Quantum.Simulator.Runtime` dynamic library built from. -To install prerequisite tools for building the QIR runtime, you can set the `ENABLE_QIRRUNTIME` environment variable to the string `"true"` and run `prerequisites.ps1` or manually install pre-reqs with the steps listed below. +To install prerequisite tools for building the QIR runtime, you can set the `ENABLE_QIRRUNTIME` environment variable to the string `"true"` and run `prerequisites.ps1` or manually install pre-reqs with the steps listed below (Windows script relies on [Chocolatey](https://chocolatey.org/) for installation). ### Windows pre-reqs diff --git a/src/QirRuntime/build-qir-runtime.ps1 b/src/QirRuntime/build-qir-runtime.ps1 index 5bee2d51695..639fb235876 100644 --- a/src/QirRuntime/build-qir-runtime.ps1 +++ b/src/QirRuntime/build-qir-runtime.ps1 @@ -38,9 +38,14 @@ elseif (($IsWindows) -or ((Test-Path Env:AGENT_OS) -and ($Env:AGENT_OS.StartsWit $env:CC = "clang.exe" $env:CXX = "clang++.exe" $env:RC = "clang++.exe" - $llvmExtras = (Join-Path $PSScriptRoot "externals/LLVM") + $llvmExtras = Join-Path $PSScriptRoot externals LLVM $env:PATH += ";$llvmExtras" + if (!(Get-Command clang -ErrorAction SilentlyContinue) -and (choco find --idonly -l llvm) -contains "llvm") { + # LLVM was installed by Chocolatey, so add the install location to the path. + $env:PATH += ";$($env:SystemDrive)\Program Files\LLVM\bin" + } + if (Get-Command clang-tidy -ErrorAction SilentlyContinue) { # Only run clang-tidy if it's installed. This is because the package used by chocolatey on # the build pipeline doesn't include clang-tidy, so we allow skipping that there and let From c31949af1827ff3c77d195fbed39c2bc6e7858d4 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Mar 2021 16:26:57 +0000 Subject: [PATCH 28/31] Rename qir.dll to Microsoft.Quantum.Qir.Runtime --- src/QirRuntime/lib/QIR/CMakeLists.txt | 14 +++++++------- src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 2 +- src/QirRuntime/lib/Tracer/CMakeLists.txt | 2 +- src/QirRuntime/test/QIR-dynamic/CMakeLists.txt | 2 +- src/QirRuntime/test/QIR-tracer/CMakeLists.txt | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index 0233f5317a0..c125357a756 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -68,22 +68,22 @@ set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) target_compile_definitions(qir-qis-support-obj PRIVATE EXPORT_QIR_API) #=============================================================================== -# Produce the qir dynamic library +# Produce the Microsoft.Quantum.Qir.Runtime dynamic library # -add_library(qir SHARED) +add_library(Microsoft.Quantum.Qir.Runtime SHARED) -target_link_libraries(qir +target_link_libraries(Microsoft.Quantum.Qir.Runtime ${CMAKE_DL_LIBS} qir-rt-support-obj qir-qis-support-obj ) -target_include_directories(qir PUBLIC ${public_includes}) -target_compile_definitions(qir PRIVATE EXPORT_QIR_API) +target_include_directories(Microsoft.Quantum.Qir.Runtime PUBLIC ${public_includes}) +target_compile_definitions(Microsoft.Quantum.Qir.Runtime PRIVATE EXPORT_QIR_API) -set_property(TARGET qir PROPERTY POSITION_INDEPENDENT_CODE ON) +set_property(TARGET Microsoft.Quantum.Qir.Runtime PROPERTY POSITION_INDEPENDENT_CODE ON) -install(TARGETS qir +install(TARGETS Microsoft.Quantum.Qir.Runtime RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index a8e2b662a38..f9e64515b69 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -37,7 +37,7 @@ target_link_libraries(QSharpCore qsharp-core-qis-support-obj simulators-obj "-L${CMAKE_BINARY_DIR}/lib/QIR" - -lqir + -lMicrosoft.Quantum.Qir.Runtime ) target_include_directories(QSharpCore PUBLIC ${public_includes}) diff --git a/src/QirRuntime/lib/Tracer/CMakeLists.txt b/src/QirRuntime/lib/Tracer/CMakeLists.txt index b9ea696fb74..76d932d1e48 100644 --- a/src/QirRuntime/lib/Tracer/CMakeLists.txt +++ b/src/QirRuntime/lib/Tracer/CMakeLists.txt @@ -33,7 +33,7 @@ target_link_libraries(qirtracer ${CMAKE_DL_LIBS} tracer-obj "-L${CMAKE_BINARY_DIR}/lib/QIR" - -lqir + -lMicrosoft.Quantum.Qir.Runtime ) target_include_directories(qirtracer PUBLIC ${includes}) diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index 852caa18585..b0af81ae702 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -26,7 +26,7 @@ add_executable(qir-dynamic-tests target_link_libraries(qir-dynamic-tests PUBLIC ${QIR_TESTS_LIBS} "-L${CMAKE_BINARY_DIR}/lib/QIR" - -lqir + -lMicrosoft.Quantum.Qir.Runtime "-L${CMAKE_BINARY_DIR}/lib/QSharpCore" -lQSharpCore ) diff --git a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt index 83fe7496ed4..6d112daa74b 100644 --- a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt @@ -26,7 +26,7 @@ add_executable(qir-tracer-tests target_link_libraries(qir-tracer-tests PUBLIC ${QIR_TESTS_LIBS} "-L${CMAKE_BINARY_DIR}/lib/QIR" - -lqir + -lMicrosoft.Quantum.Qir.Runtime "-L${CMAKE_BINARY_DIR}/lib/Tracer" -lqirtracer ) From 275d354fe9795d928770d0868637ae773e817762 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Mar 2021 16:56:30 +0000 Subject: [PATCH 29/31] Rename QSharpCore and qirtracer dlls --- src/QirRuntime/lib/QSharpCore/CMakeLists.txt | 14 +++++++------- src/QirRuntime/lib/Tracer/CMakeLists.txt | 14 +++++++------- src/QirRuntime/test/QIR-dynamic/CMakeLists.txt | 4 ++-- src/QirRuntime/test/QIR-tracer/CMakeLists.txt | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt index f9e64515b69..a6ede1aa2c2 100644 --- a/src/QirRuntime/lib/QSharpCore/CMakeLists.txt +++ b/src/QirRuntime/lib/QSharpCore/CMakeLists.txt @@ -28,11 +28,11 @@ set_property(TARGET qsharp-core-qis-support-obj PROPERTY POSITION_INDEPENDENT_CO target_compile_definitions(qsharp-core-qis-support-obj PUBLIC EXPORT_QIR_API) #=============================================================================== -# Produce the QSharpCore dynamic library +# Produce the Microsoft.Quantum.Qir.QSharp.Core dynamic library # -add_library(QSharpCore SHARED) +add_library(Microsoft.Quantum.Qir.QSharp.Core SHARED) -target_link_libraries(QSharpCore +target_link_libraries(Microsoft.Quantum.Qir.QSharp.Core ${CMAKE_DL_LIBS} qsharp-core-qis-support-obj simulators-obj @@ -40,12 +40,12 @@ target_link_libraries(QSharpCore -lMicrosoft.Quantum.Qir.Runtime ) -target_include_directories(QSharpCore PUBLIC ${public_includes}) -target_compile_definitions(QSharpCore PRIVATE EXPORT_QIR_API) +target_include_directories(Microsoft.Quantum.Qir.QSharp.Core PUBLIC ${public_includes}) +target_compile_definitions(Microsoft.Quantum.Qir.QSharp.Core PRIVATE EXPORT_QIR_API) -set_property(TARGET QSharpCore PROPERTY POSITION_INDEPENDENT_CODE ON) +set_property(TARGET Microsoft.Quantum.Qir.QSharp.Core PROPERTY POSITION_INDEPENDENT_CODE ON) -install(TARGETS QSharpCore +install(TARGETS Microsoft.Quantum.Qir.QSharp.Core RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/lib/Tracer/CMakeLists.txt b/src/QirRuntime/lib/Tracer/CMakeLists.txt index 76d932d1e48..c59a3dc40c7 100644 --- a/src/QirRuntime/lib/Tracer/CMakeLists.txt +++ b/src/QirRuntime/lib/Tracer/CMakeLists.txt @@ -25,23 +25,23 @@ set_property(TARGET tracer-obj PROPERTY POSITION_INDEPENDENT_CODE ON) target_compile_definitions(tracer-obj PRIVATE EXPORT_QIR_API) #=============================================================================== -# Produce the qirtracer dynamic library +# Produce the Microsoft.Quantum.Qir.Tracer dynamic library # -add_library(qirtracer SHARED) +add_library(Microsoft.Quantum.Qir.Tracer SHARED) -target_link_libraries(qirtracer +target_link_libraries(Microsoft.Quantum.Qir.Tracer ${CMAKE_DL_LIBS} tracer-obj "-L${CMAKE_BINARY_DIR}/lib/QIR" -lMicrosoft.Quantum.Qir.Runtime ) -target_include_directories(qirtracer PUBLIC ${includes}) -target_compile_definitions(qirtracer PRIVATE EXPORT_QIR_API) +target_include_directories(Microsoft.Quantum.Qir.Tracer PUBLIC ${includes}) +target_compile_definitions(Microsoft.Quantum.Qir.Tracer PRIVATE EXPORT_QIR_API) -set_property(TARGET qirtracer PROPERTY POSITION_INDEPENDENT_CODE ON) +set_property(TARGET Microsoft.Quantum.Qir.Tracer PROPERTY POSITION_INDEPENDENT_CODE ON) -install(TARGETS qirtracer +install(TARGETS Microsoft.Quantum.Qir.Tracer RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" ) diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index b0af81ae702..ae11c1be001 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -16,7 +16,7 @@ endforeach() add_custom_target(qir_dynamic_test_lib DEPENDS ${QIR_TESTS_LIBS}) #============================================================================== -# This executable target links test code against the dynamic QIR and QSharpCore libraries rather than the explicit +# This executable target links test code against the dynamic libraries rather than the explicit # static QIR/RT libs (qir will statically link in the bridge via transitivity of target_link_libraries). # add_executable(qir-dynamic-tests @@ -28,7 +28,7 @@ target_link_libraries(qir-dynamic-tests PUBLIC "-L${CMAKE_BINARY_DIR}/lib/QIR" -lMicrosoft.Quantum.Qir.Runtime "-L${CMAKE_BINARY_DIR}/lib/QSharpCore" - -lQSharpCore + -lMicrosoft.Quantum.Qir.QSharp.Core ) target_include_directories(qir-dynamic-tests PUBLIC diff --git a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt index 6d112daa74b..fb6ab5bd850 100644 --- a/src/QirRuntime/test/QIR-tracer/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-tracer/CMakeLists.txt @@ -28,13 +28,13 @@ target_link_libraries(qir-tracer-tests PUBLIC "-L${CMAKE_BINARY_DIR}/lib/QIR" -lMicrosoft.Quantum.Qir.Runtime "-L${CMAKE_BINARY_DIR}/lib/Tracer" - -lqirtracer + -lMicrosoft.Quantum.Qir.Tracer ) target_include_directories(qir-tracer-tests PUBLIC "${test_includes}" "${public_includes}" - "${PROJECT_SOURCE_DIR}/lib/Tracer" + "${PROJECT_SOURCE_DIR}/lib/Tracer" # TODO: Remove this when tracer api is put into public headers. ) add_dependencies(qir-tracer-tests tracer_qir_test_lib) From bb80b930121dd41f704c457ac2a8f50fc0d91329 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Mar 2021 19:09:52 +0000 Subject: [PATCH 30/31] Separate out quantum__qis into QSharp.Foundation --- src/QirRuntime/CMakeLists.txt | 4 +- src/QirRuntime/lib/CMakeLists.txt | 1 + src/QirRuntime/lib/QIR/CMakeLists.txt | 28 - src/QirRuntime/lib/QIR/allocationsTracker.cpp | 2 +- src/QirRuntime/lib/QIR/arrays.cpp | 2 +- src/QirRuntime/lib/QIR/callables.cpp | 2 +- src/QirRuntime/lib/QIR/delegated.cpp | 2 +- src/QirRuntime/lib/QIR/strings.cpp | 2 +- src/QirRuntime/lib/QIR/utils.cpp | 2 +- .../lib/QSharpFoundation/CMakeLists.txt | 53 ++ .../conditionals.cpp | 92 +-- .../intrinsicsMath.cpp | 6 +- .../intrinsicsOut.cpp | 2 +- .../qsharp-foundation-qis.ll} | 446 ++++++------- .../qsharp__foundation__qis.hpp} | 104 +-- .../qsharp__foundation_internal.hpp} | 0 .../quantum__rt.hpp => public/QirRuntime.hpp} | 590 +++++++++--------- .../test/FullstateSimulator/CMakeLists.txt | 4 +- .../test/QIR-dynamic/CMakeLists.txt | 2 + src/QirRuntime/test/QIR-static/CMakeLists.txt | 5 +- src/QirRuntime/test/QIR-static/qir-driver.cpp | 2 +- .../test/QIR-static/qir-test-math.cpp | 2 +- .../test/QIR-static/qir-test-ouput.cpp | 2 +- src/QirRuntime/test/unittests/CMakeLists.txt | 3 +- .../test/unittests/QirRuntimeTests.cpp | 4 +- 25 files changed, 696 insertions(+), 666 deletions(-) create mode 100644 src/QirRuntime/lib/QSharpFoundation/CMakeLists.txt rename src/QirRuntime/lib/{QIR => QSharpFoundation}/conditionals.cpp (93%) rename src/QirRuntime/lib/{QIR => QSharpFoundation}/intrinsicsMath.cpp (96%) rename src/QirRuntime/lib/{QIR => QSharpFoundation}/intrinsicsOut.cpp (96%) rename src/QirRuntime/lib/{QIR/bridge-qis.ll => QSharpFoundation/qsharp-foundation-qis.ll} (97%) rename src/QirRuntime/lib/{QIR/quantum__qis.hpp => QSharpFoundation/qsharp__foundation__qis.hpp} (97%) rename src/QirRuntime/lib/{QIR/quantum__qis_internal.hpp => QSharpFoundation/qsharp__foundation_internal.hpp} (100%) rename src/QirRuntime/{lib/QIR/quantum__rt.hpp => public/QirRuntime.hpp} (98%) diff --git a/src/QirRuntime/CMakeLists.txt b/src/QirRuntime/CMakeLists.txt index bc1e94abe98..e8f85268d6d 100644 --- a/src/QirRuntime/CMakeLists.txt +++ b/src/QirRuntime/CMakeLists.txt @@ -32,12 +32,12 @@ include(qir_cmake_include) if (WIN32) set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-rt-u.lib") - set(QIR_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/bridge-qis-u.lib") + set(QSHARP_FOUNDATION_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpFoundation/qsharp-foundation-qis-u.lib") set(QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpCore/qsharp-core-qis-u.lib") set(QIR_BRIDGE_TRACER_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/Tracer/tracer-bridge-u.lib") else() set(QIR_BRIDGE_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/libbridge-rt-u.a") - set(QIR_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QIR/libbridge-qis-u.a") + set(QSHARP_FOUNDATION_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpFoundation/libqsharp-foundation-qis-u.a") set(QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/QSharpCore/libqsharp-core-qis-u.a") set(QIR_BRIDGE_TRACER_UTILITY_LIB "${PROJECT_BINARY_DIR}/lib/Tracer/libtracer-bridge-u.a") endif() diff --git a/src/QirRuntime/lib/CMakeLists.txt b/src/QirRuntime/lib/CMakeLists.txt index f578ad66163..343d7162ebc 100644 --- a/src/QirRuntime/lib/CMakeLists.txt +++ b/src/QirRuntime/lib/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(QIR) +add_subdirectory(QSharpFoundation) add_subdirectory(QSharpCore) add_subdirectory(Simulators) add_subdirectory(Tracer) diff --git a/src/QirRuntime/lib/QIR/CMakeLists.txt b/src/QirRuntime/lib/QIR/CMakeLists.txt index c125357a756..1172279d910 100644 --- a/src/QirRuntime/lib/QIR/CMakeLists.txt +++ b/src/QirRuntime/lib/QIR/CMakeLists.txt @@ -40,33 +40,6 @@ target_compile_definitions(qir-rt-support-obj PRIVATE EXPORT_QIR_API) # qir-qis #+++++++++++++++++++++++++++++++++++++ -#=============================================================================== -# create a utility lib from bridge-qis.ll -# -set(bridge_qis_target "bridge_qis_target") -compile_from_qir(bridge-qis ${bridge_qis_target}) - -#=============================================================================== -# create qir-qis-support lib from the C++ sources -# -set(qis_sup_source_files - conditionals.cpp - intrinsicsMath.cpp - intrinsicsOut.cpp -) - -add_library(qir-qis-support ${qis_sup_source_files}) -target_include_directories(qir-qis-support PUBLIC ${public_includes}) -add_dependencies(qir-qis-support ${bridge_qis_target}) -target_compile_definitions(qir-qis-support PRIVATE EXPORT_QIR_API) - -# Produce object lib we'll use to create a shared lib (so/dll) later on -add_library(qir-qis-support-obj OBJECT ${qis_sup_source_files}) -target_source_from_qir_obj(qir-qis-support-obj bridge-qis) -target_include_directories(qir-qis-support-obj PUBLIC ${public_includes}) -set_property(TARGET qir-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_compile_definitions(qir-qis-support-obj PRIVATE EXPORT_QIR_API) - #=============================================================================== # Produce the Microsoft.Quantum.Qir.Runtime dynamic library # @@ -75,7 +48,6 @@ add_library(Microsoft.Quantum.Qir.Runtime SHARED) target_link_libraries(Microsoft.Quantum.Qir.Runtime ${CMAKE_DL_LIBS} qir-rt-support-obj - qir-qis-support-obj ) target_include_directories(Microsoft.Quantum.Qir.Runtime PUBLIC ${public_includes}) diff --git a/src/QirRuntime/lib/QIR/allocationsTracker.cpp b/src/QirRuntime/lib/QIR/allocationsTracker.cpp index 2eaf5613b87..af483c54f15 100644 --- a/src/QirRuntime/lib/QIR/allocationsTracker.cpp +++ b/src/QirRuntime/lib/QIR/allocationsTracker.cpp @@ -3,7 +3,7 @@ #include "allocationsTracker.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" using namespace std; diff --git a/src/QirRuntime/lib/QIR/arrays.cpp b/src/QirRuntime/lib/QIR/arrays.cpp index 04532fa55ce..00d8d9e19c6 100644 --- a/src/QirRuntime/lib/QIR/arrays.cpp +++ b/src/QirRuntime/lib/QIR/arrays.cpp @@ -13,7 +13,7 @@ #include "QirContext.hpp" #include "QirTypes.hpp" #include "allocationsTracker.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" using namespace Microsoft::Quantum; diff --git a/src/QirRuntime/lib/QIR/callables.cpp b/src/QirRuntime/lib/QIR/callables.cpp index e354d55e959..454eb4f3dbf 100644 --- a/src/QirRuntime/lib/QIR/callables.cpp +++ b/src/QirRuntime/lib/QIR/callables.cpp @@ -11,7 +11,7 @@ #include "QirContext.hpp" #include "QirTypes.hpp" #include "allocationsTracker.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" using namespace Microsoft::Quantum; diff --git a/src/QirRuntime/lib/QIR/delegated.cpp b/src/QirRuntime/lib/QIR/delegated.cpp index 6530297b227..e85264f6a72 100644 --- a/src/QirRuntime/lib/QIR/delegated.cpp +++ b/src/QirRuntime/lib/QIR/delegated.cpp @@ -4,7 +4,7 @@ #include #include -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" #include "QuantumApi_I.hpp" #include "SimFactory.hpp" diff --git a/src/QirRuntime/lib/QIR/strings.cpp b/src/QirRuntime/lib/QIR/strings.cpp index 5ecbb8400ff..21f3b571d14 100644 --- a/src/QirRuntime/lib/QIR/strings.cpp +++ b/src/QirRuntime/lib/QIR/strings.cpp @@ -8,7 +8,7 @@ #include #include "QirTypes.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" std::unordered_map& AllocatedStrings() { diff --git a/src/QirRuntime/lib/QIR/utils.cpp b/src/QirRuntime/lib/QIR/utils.cpp index 36195562ae3..6f024cdfafe 100644 --- a/src/QirRuntime/lib/QIR/utils.cpp +++ b/src/QirRuntime/lib/QIR/utils.cpp @@ -7,7 +7,7 @@ #include #include -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" #include "QirTypes.hpp" diff --git a/src/QirRuntime/lib/QSharpFoundation/CMakeLists.txt b/src/QirRuntime/lib/QSharpFoundation/CMakeLists.txt new file mode 100644 index 00000000000..2aebcd19b9a --- /dev/null +++ b/src/QirRuntime/lib/QSharpFoundation/CMakeLists.txt @@ -0,0 +1,53 @@ +#+++++++++++++++++++++++++++++++++++++ +# qsharp-foundation-qis +#+++++++++++++++++++++++++++++++++++++ + +#=============================================================================== +# create a utility lib from qsharp-foundation-qis.ll +# +set(qsharp_foundation_qis_target "qsharp_foundation_qis_target") +compile_from_qir(qsharp-foundation-qis ${qsharp_foundation_qis_target}) + +#=============================================================================== +# create qsharp-foundation-qis-support lib from the C++ sources +# +set(qsharp_foundation_sup_source_files + intrinsicsMath.cpp + intrinsicsOut.cpp + conditionals.cpp +) + +add_library(qsharp-foundation-qis-support ${qsharp_foundation_sup_source_files}) +target_include_directories(qsharp-foundation-qis-support PUBLIC ${public_includes}) +add_dependencies(qsharp-foundation-qis-support ${qsharp_foundation_qis_target}) +target_compile_definitions(qsharp-foundation-qis-support PRIVATE EXPORT_QIR_API) + +# Produce object lib we'll use to create a shared lib (so/dll) later on +add_library(qsharp-foundation-qis-support-obj OBJECT ${qsharp_foundation_sup_source_files}) +target_source_from_qir_obj(qsharp-foundation-qis-support-obj qsharp-foundation-qis) +target_include_directories(qsharp-foundation-qis-support-obj PUBLIC ${public_includes}) +set_property(TARGET qsharp-foundation-qis-support-obj PROPERTY POSITION_INDEPENDENT_CODE ON) +target_compile_definitions(qsharp-foundation-qis-support-obj PUBLIC EXPORT_QIR_API) + +#=============================================================================== +# Produce the Microsoft.Quantum.Qir.QSharp.Foundation dynamic library +# +add_library(Microsoft.Quantum.Qir.QSharp.Foundation SHARED) + +target_link_libraries(Microsoft.Quantum.Qir.QSharp.Foundation + ${CMAKE_DL_LIBS} + qsharp-foundation-qis-support-obj + "-L${CMAKE_BINARY_DIR}/lib/QIR" + -lMicrosoft.Quantum.Qir.Runtime +) + +target_include_directories(Microsoft.Quantum.Qir.QSharp.Foundation PUBLIC ${public_includes}) +target_compile_definitions(Microsoft.Quantum.Qir.QSharp.Foundation PRIVATE EXPORT_QIR_API) + +set_property(TARGET Microsoft.Quantum.Qir.QSharp.Foundation PROPERTY POSITION_INDEPENDENT_CODE ON) + +install(TARGETS Microsoft.Quantum.Qir.QSharp.Foundation + RUNTIME DESTINATION "${CMAKE_BINARY_DIR}/bin" + LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/bin" +) + diff --git a/src/QirRuntime/lib/QIR/conditionals.cpp b/src/QirRuntime/lib/QSharpFoundation/conditionals.cpp similarity index 93% rename from src/QirRuntime/lib/QIR/conditionals.cpp rename to src/QirRuntime/lib/QSharpFoundation/conditionals.cpp index e9e0bb8d083..048ce01eadb 100644 --- a/src/QirRuntime/lib/QIR/conditionals.cpp +++ b/src/QirRuntime/lib/QSharpFoundation/conditionals.cpp @@ -1,47 +1,47 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include -#include - -#include "quantum__qis.hpp" - -#include "QirTypes.hpp" -#include "quantum__rt.hpp" - -static bool ArraysContainEqualResults(QirArray* rs1, QirArray* rs2) -{ - assert(rs1 != nullptr && rs2 != nullptr && rs1->count == rs2->count); - assert(rs1->itemSizeInBytes == sizeof(void*)); // the array should contain pointers to RESULT - assert(rs2->itemSizeInBytes == sizeof(void*)); // the array should contain pointers to RESULT - - RESULT** results1 = reinterpret_cast(rs1->buffer); - RESULT** results2 = reinterpret_cast(rs2->buffer); - for (int64_t i = 0; i < rs1->count; i++) - { - if (!quantum__rt__result_equal(results1[i], results2[i])) - { - return false; - } - } - return true; -} - -extern "C" -{ - void quantum__qis__applyifelseintrinsic__body(RESULT* r, QirCallable* clbOnZero, QirCallable* clbOnOne) - { - QirCallable* clb = quantum__rt__result_equal(r, quantum__rt__result_zero()) ? clbOnZero : clbOnOne; - clb->Invoke(); - } - - void quantum__qis__applyconditionallyintrinsic__body( - QirArray* rs1, - QirArray* rs2, - QirCallable* clbOnAllEqual, - QirCallable* clbOnSomeDifferent) - { - QirCallable* clb = ArraysContainEqualResults(rs1, rs2) ? clbOnAllEqual : clbOnSomeDifferent; - clb->Invoke(); - } +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include +#include + +#include "qsharp__foundation__qis.hpp" + +#include "QirTypes.hpp" +#include "QirRuntime.hpp" + +static bool ArraysContainEqualResults(QirArray* rs1, QirArray* rs2) +{ + assert(rs1 != nullptr && rs2 != nullptr && rs1->count == rs2->count); + assert(rs1->itemSizeInBytes == sizeof(void*)); // the array should contain pointers to RESULT + assert(rs2->itemSizeInBytes == sizeof(void*)); // the array should contain pointers to RESULT + + RESULT** results1 = reinterpret_cast(rs1->buffer); + RESULT** results2 = reinterpret_cast(rs2->buffer); + for (int64_t i = 0; i < rs1->count; i++) + { + if (!quantum__rt__result_equal(results1[i], results2[i])) + { + return false; + } + } + return true; +} + +extern "C" +{ + void quantum__qis__applyifelseintrinsic__body(RESULT* r, QirCallable* clbOnZero, QirCallable* clbOnOne) + { + QirCallable* clb = quantum__rt__result_equal(r, quantum__rt__result_zero()) ? clbOnZero : clbOnOne; + clb->Invoke(); + } + + void quantum__qis__applyconditionallyintrinsic__body( + QirArray* rs1, + QirArray* rs2, + QirCallable* clbOnAllEqual, + QirCallable* clbOnSomeDifferent) + { + QirCallable* clb = ArraysContainEqualResults(rs1, rs2) ? clbOnAllEqual : clbOnSomeDifferent; + clb->Invoke(); + } } \ No newline at end of file diff --git a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp b/src/QirRuntime/lib/QSharpFoundation/intrinsicsMath.cpp similarity index 96% rename from src/QirRuntime/lib/QIR/intrinsicsMath.cpp rename to src/QirRuntime/lib/QSharpFoundation/intrinsicsMath.cpp index 41180ace397..cc22595ebe3 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsMath.cpp +++ b/src/QirRuntime/lib/QSharpFoundation/intrinsicsMath.cpp @@ -4,9 +4,9 @@ #include #include #include -#include "quantum__qis.hpp" -#include "quantum__qis_internal.hpp" -#include "quantum__rt.hpp" +#include "qsharp__foundation__qis.hpp" +#include "qsharp__foundation_internal.hpp" +#include "QirRuntime.hpp" // Forward declarations: namespace // Visible in this translation unit only. diff --git a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp b/src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp similarity index 96% rename from src/QirRuntime/lib/QIR/intrinsicsOut.cpp rename to src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp index 17a48cec660..3ab0f538b58 100644 --- a/src/QirRuntime/lib/QIR/intrinsicsOut.cpp +++ b/src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp @@ -4,7 +4,7 @@ #include #include "QirTypes.hpp" -#include "quantum__qis.hpp" +#include "qsharp__foundation__qis.hpp" // Forward declarations: static std::ostream& GetOutputStream(); diff --git a/src/QirRuntime/lib/QIR/bridge-qis.ll b/src/QirRuntime/lib/QSharpFoundation/qsharp-foundation-qis.ll similarity index 97% rename from src/QirRuntime/lib/QIR/bridge-qis.ll rename to src/QirRuntime/lib/QSharpFoundation/qsharp-foundation-qis.ll index b1cce0ca990..4bc362335c1 100644 --- a/src/QirRuntime/lib/QIR/bridge-qis.ll +++ b/src/QirRuntime/lib/QSharpFoundation/qsharp-foundation-qis.ll @@ -1,223 +1,223 @@ -; Copyright (c) Microsoft Corporation. -; Licensed under the MIT License. - -; The __quantum__qis__* definitions should be automatically generated by QIR, depending on the specific target. -; However, for simulator targets we provide an optional simple bridge that covers commonly used intrinsics. - -;======================================================================================================================= -; QIR types -; -%Array = type opaque -%Callable = type opaque -%Qubit = type opaque -%Range = type { i64, i64, i64 } -%Result = type opaque -%String = type opaque -%Pauli = type i2 - -;======================================================================================================================= -; Native types -; NB: there is no overloading at IR level, so a call/invoke will be made even -; if the definition of the function mismatches the declaration of the arguments. -; It means we could declare here the bridge's C-functions using QIR types -; and avoid bitcasts. However, it seems prudent to be more explicit about -; what's going on and declare the true signatures, as generated by Clang. -; -%class.QUBIT = type opaque -%class.RESULT = type opaque -%struct.QirArray = type opaque -%struct.QirCallable = type opaque -%struct.QirRange = type { i64, i64, i64 } -%struct.QirString = type opaque -%PauliId = type i32 - -declare void @quantum__qis__message__body(%struct.QirString* %str) - -;=============================================================================== -; -define dllexport 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 -; - -; LLVM intrinsics (https://llvm.org/docs/LangRef.html): -declare double @llvm.sqrt.f64(double %.val) -declare double @llvm.log.f64(double %Val) -declare double @llvm.sin.f64(double %Val) -declare double @llvm.cos.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) -declare double @quantum__qis__sinh__body(double %theta) -declare double @quantum__qis__cosh__body(double %theta) -declare double @quantum__qis__arcsin__body(double %theta) -declare double @quantum__qis__arccos__body(double %theta) -declare double @quantum__qis__arctan__body(double %theta) -declare double @quantum__qis__ieeeremainder__body(double %y, double %x) -declare i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) - -; API for the user code: -define dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 -} - -; function Sin (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sin -define dllexport double @__quantum__qis__sin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sin - %result = call double @llvm.sin.f64(double %theta) ; https://llvm.org/docs/LangRef.html#llvm-sin-intrinsic - ret double %result -} - -; function Cos (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.cos -define dllexport double @__quantum__qis__cos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cos - %result = call double @llvm.cos.f64(double %theta) ; https://llvm.org/docs/LangRef.html#llvm-cos-intrinsic - ret double %result -} - -; function Tan (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.tan -define dllexport double @__quantum__qis__tan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tan - %sin = call double @llvm.sin.f64(double %theta) - %cos = call double @llvm.cos.f64(double %theta) - %result = fdiv double %sin, %cos ; tg(x) = sin(x) / cos(x) - ret double %result -} - -; function Sinh (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sinh -define dllexport double @__quantum__qis__sinh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sinh - %result = call double @quantum__qis__sinh__body(double %theta) - ret double %result -} - -; function Cosh (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.cosh -define dllexport double @__quantum__qis__cosh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cosh - %result = call double @quantum__qis__cosh__body(double %theta) - ret double %result -} - -; function Tanh (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.tanh -define dllexport double @__quantum__qis__tanh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tanh - %sin = call double @__quantum__qis__sinh__body(double %theta) - %cos = call double @__quantum__qis__cosh__body(double %theta) - %result = fdiv double %sin, %cos ; tanh(x) = sinh(x) / cosh(x) - ret double %result -} - -; function ArcSin (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arcsin -define dllexport double @__quantum__qis__arcsin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/asin - %result = call double @quantum__qis__arcsin__body(double %theta) - ret double %result -} - -; function ArcCos (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos -define dllexport double @__quantum__qis__arccos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/acos - %result = call double @quantum__qis__arccos__body(double %theta) - ret double %result -} - -; function ArcTan (theta : Double) : Double -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan -define dllexport double @__quantum__qis__arctan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/atan - %result = call double @quantum__qis__arctan__body(double %theta) - ret double %result -} - - -; function IEEERemainder(x : Double, y : Double) : Double -define dllexport double @__quantum__qis__ieeeremainder__body(double %x, double %y) { - %result = call double @quantum__qis__ieeeremainder__body(double %x, double %y) - ret double %result -} - - -; operation DrawRandomInt (min : Int, max : Int) : Int -; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint -define dllexport i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { - %result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) - ret i64 %result -} - -;=============================================================================== -; quantum.qis conditional functions -; -declare void @quantum__qis__applyifelseintrinsic__body(%class.RESULT*, %struct.QirCallable*, %struct.QirCallable*) -declare void @quantum__qis__applyconditionallyintrinsic__body( - %struct.QirArray*, %struct.QirArray*, %struct.QirCallable*, %struct.QirCallable*) - -define dllexport void @__quantum__qis__applyifelseintrinsic__body( - %Result* %.r, %Callable* %.clb_on_zero, %Callable* %.clb_on_one) { - - %r = bitcast %Result* %.r to %class.RESULT* - %clb_on_zero = bitcast %Callable* %.clb_on_zero to %struct.QirCallable* - %clb_on_one = bitcast %Callable* %.clb_on_one to %struct.QirCallable* - call void @quantum__qis__applyifelseintrinsic__body( - %class.RESULT* %r, %struct.QirCallable* %clb_on_zero, %struct.QirCallable* %clb_on_one) - ret void -} - -define dllexport void @__quantum__qis__applyconditionallyintrinsic__body( - %Array* %.rs1, %Array* %.rs2, %Callable* %.clb_on_equal, %Callable* %.clb_on_different) { - - %rs1 = bitcast %Array* %.rs1 to %struct.QirArray* - %rs2 = bitcast %Array* %.rs2 to %struct.QirArray* - %clb_on_equal = bitcast %Callable* %.clb_on_equal to %struct.QirCallable* - %clb_on_different = bitcast %Callable* %.clb_on_different to %struct.QirCallable* - call void @quantum__qis__applyconditionallyintrinsic__body( - %struct.QirArray* %rs1, %struct.QirArray* %rs2, - %struct.QirCallable* %clb_on_equal, %struct.QirCallable* %clb_on_different) - ret void -} - +; Copyright (c) Microsoft Corporation. +; Licensed under the MIT License. + +; The __quantum__qis__* definitions should be automatically generated by QIR, depending on the specific target. +; However, for simulator targets we provide an optional simple bridge that covers commonly used intrinsics. + +;======================================================================================================================= +; QIR types +; +%Array = type opaque +%Callable = type opaque +%Qubit = type opaque +%Range = type { i64, i64, i64 } +%Result = type opaque +%String = type opaque +%Pauli = type i2 + +;======================================================================================================================= +; Native types +; NB: there is no overloading at IR level, so a call/invoke will be made even +; if the definition of the function mismatches the declaration of the arguments. +; It means we could declare here the bridge's C-functions using QIR types +; and avoid bitcasts. However, it seems prudent to be more explicit about +; what's going on and declare the true signatures, as generated by Clang. +; +%class.QUBIT = type opaque +%class.RESULT = type opaque +%struct.QirArray = type opaque +%struct.QirCallable = type opaque +%struct.QirRange = type { i64, i64, i64 } +%struct.QirString = type opaque +%PauliId = type i32 + +declare void @quantum__qis__message__body(%struct.QirString* %str) + +;=============================================================================== +; +define dllexport 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 +; + +; LLVM intrinsics (https://llvm.org/docs/LangRef.html): +declare double @llvm.sqrt.f64(double %.val) +declare double @llvm.log.f64(double %Val) +declare double @llvm.sin.f64(double %Val) +declare double @llvm.cos.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) +declare double @quantum__qis__sinh__body(double %theta) +declare double @quantum__qis__cosh__body(double %theta) +declare double @quantum__qis__arcsin__body(double %theta) +declare double @quantum__qis__arccos__body(double %theta) +declare double @quantum__qis__arctan__body(double %theta) +declare double @quantum__qis__ieeeremainder__body(double %y, double %x) +declare i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) + +; API for the user code: +define dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 dllexport 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 +} + +; function Sin (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sin +define dllexport double @__quantum__qis__sin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sin + %result = call double @llvm.sin.f64(double %theta) ; https://llvm.org/docs/LangRef.html#llvm-sin-intrinsic + ret double %result +} + +; function Cos (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.cos +define dllexport double @__quantum__qis__cos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cos + %result = call double @llvm.cos.f64(double %theta) ; https://llvm.org/docs/LangRef.html#llvm-cos-intrinsic + ret double %result +} + +; function Tan (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.tan +define dllexport double @__quantum__qis__tan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tan + %sin = call double @llvm.sin.f64(double %theta) + %cos = call double @llvm.cos.f64(double %theta) + %result = fdiv double %sin, %cos ; tg(x) = sin(x) / cos(x) + ret double %result +} + +; function Sinh (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.sinh +define dllexport double @__quantum__qis__sinh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/sinh + %result = call double @quantum__qis__sinh__body(double %theta) + ret double %result +} + +; function Cosh (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.cosh +define dllexport double @__quantum__qis__cosh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/cosh + %result = call double @quantum__qis__cosh__body(double %theta) + ret double %result +} + +; function Tanh (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.tanh +define dllexport double @__quantum__qis__tanh__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/tanh + %sin = call double @__quantum__qis__sinh__body(double %theta) + %cos = call double @__quantum__qis__cosh__body(double %theta) + %result = fdiv double %sin, %cos ; tanh(x) = sinh(x) / cosh(x) + ret double %result +} + +; function ArcSin (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arcsin +define dllexport double @__quantum__qis__arcsin__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/asin + %result = call double @quantum__qis__arcsin__body(double %theta) + ret double %result +} + +; function ArcCos (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arccos +define dllexport double @__quantum__qis__arccos__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/acos + %result = call double @quantum__qis__arccos__body(double %theta) + ret double %result +} + +; function ArcTan (theta : Double) : Double +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.arctan +define dllexport double @__quantum__qis__arctan__body(double %theta) { ; https://en.cppreference.com/w/cpp/numeric/math/atan + %result = call double @quantum__qis__arctan__body(double %theta) + ret double %result +} + + +; function IEEERemainder(x : Double, y : Double) : Double +define dllexport double @__quantum__qis__ieeeremainder__body(double %x, double %y) { + %result = call double @quantum__qis__ieeeremainder__body(double %x, double %y) + ret double %result +} + + +; operation DrawRandomInt (min : Int, max : Int) : Int +; https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.random.drawrandomint +define dllexport i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) { + %result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max) + ret i64 %result +} + +;=============================================================================== +; quantum.qis conditional functions +; +declare void @quantum__qis__applyifelseintrinsic__body(%class.RESULT*, %struct.QirCallable*, %struct.QirCallable*) +declare void @quantum__qis__applyconditionallyintrinsic__body( + %struct.QirArray*, %struct.QirArray*, %struct.QirCallable*, %struct.QirCallable*) + +define dllexport void @__quantum__qis__applyifelseintrinsic__body( + %Result* %.r, %Callable* %.clb_on_zero, %Callable* %.clb_on_one) { + + %r = bitcast %Result* %.r to %class.RESULT* + %clb_on_zero = bitcast %Callable* %.clb_on_zero to %struct.QirCallable* + %clb_on_one = bitcast %Callable* %.clb_on_one to %struct.QirCallable* + call void @quantum__qis__applyifelseintrinsic__body( + %class.RESULT* %r, %struct.QirCallable* %clb_on_zero, %struct.QirCallable* %clb_on_one) + ret void +} + +define dllexport void @__quantum__qis__applyconditionallyintrinsic__body( + %Array* %.rs1, %Array* %.rs2, %Callable* %.clb_on_equal, %Callable* %.clb_on_different) { + + %rs1 = bitcast %Array* %.rs1 to %struct.QirArray* + %rs2 = bitcast %Array* %.rs2 to %struct.QirArray* + %clb_on_equal = bitcast %Callable* %.clb_on_equal to %struct.QirCallable* + %clb_on_different = bitcast %Callable* %.clb_on_different to %struct.QirCallable* + call void @quantum__qis__applyconditionallyintrinsic__body( + %struct.QirArray* %rs1, %struct.QirArray* %rs2, + %struct.QirCallable* %clb_on_equal, %struct.QirCallable* %clb_on_different) + ret void +} + diff --git a/src/QirRuntime/lib/QIR/quantum__qis.hpp b/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation__qis.hpp similarity index 97% rename from src/QirRuntime/lib/QIR/quantum__qis.hpp rename to src/QirRuntime/lib/QSharpFoundation/qsharp__foundation__qis.hpp index 961d07fd2e8..3c15948463b 100644 --- a/src/QirRuntime/lib/QIR/quantum__qis.hpp +++ b/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation__qis.hpp @@ -1,53 +1,53 @@ -#pragma once - -#include - -#include "CoreTypes.hpp" - -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -struct QirArray; -struct QirCallable; -struct QirString; -struct QirBigInt; - -namespace Microsoft -{ -namespace Quantum -{ - struct IQuantumGateSet; -} -} // namespace Microsoft - -/* - Methods from __quantum__qis namespace are specific to the target. When QIR is generated it might limit or extend - the set of intrinsics, supported by the target (known to QIR generator at compile time). As part of the runtime - we provide _optional_ implementation of the common intrinsics that redirects to IQuantumGateSet. -*/ -extern "C" -{ - 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 - QIR_SHARED_API double quantum__qis__arctan2__body(double y, double x); // NOLINT - QIR_SHARED_API double quantum__qis__sinh__body(double theta); // NOLINT - QIR_SHARED_API double quantum__qis__cosh__body(double theta); // NOLINT - QIR_SHARED_API double quantum__qis__arcsin__body(double theta); // NOLINT - QIR_SHARED_API double quantum__qis__arccos__body(double theta); // NOLINT - QIR_SHARED_API double quantum__qis__arctan__body(double theta); // NOLINT - - QIR_SHARED_API double quantum__qis__ieeeremainder__body(double x, double y); // NOLINT - QIR_SHARED_API int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum); // NOLINT - - // Q# ApplyIf: - QIR_SHARED_API void quantum__qis__applyifelseintrinsic__body(RESULT*, QirCallable*, QirCallable*); // NOLINT - QIR_SHARED_API void quantum__qis__applyconditionallyintrinsic__body( // NOLINT - QirArray*, - QirArray*, - QirCallable*, - QirCallable*); +#pragma once + +#include + +#include "CoreTypes.hpp" + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +struct QirArray; +struct QirCallable; +struct QirString; +struct QirBigInt; + +namespace Microsoft +{ +namespace Quantum +{ + struct IQuantumGateSet; +} +} // namespace Microsoft + +/* + Methods from __quantum__qis namespace are specific to the target. When QIR is generated it might limit or extend + the set of intrinsics, supported by the target (known to QIR generator at compile time). As part of the runtime + we provide _optional_ implementation of the common intrinsics that redirects to IQuantumGateSet. +*/ +extern "C" +{ + 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 + QIR_SHARED_API double quantum__qis__arctan2__body(double y, double x); // NOLINT + QIR_SHARED_API double quantum__qis__sinh__body(double theta); // NOLINT + QIR_SHARED_API double quantum__qis__cosh__body(double theta); // NOLINT + QIR_SHARED_API double quantum__qis__arcsin__body(double theta); // NOLINT + QIR_SHARED_API double quantum__qis__arccos__body(double theta); // NOLINT + QIR_SHARED_API double quantum__qis__arctan__body(double theta); // NOLINT + + QIR_SHARED_API double quantum__qis__ieeeremainder__body(double x, double y); // NOLINT + QIR_SHARED_API int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum); // NOLINT + + // Q# ApplyIf: + QIR_SHARED_API void quantum__qis__applyifelseintrinsic__body(RESULT*, QirCallable*, QirCallable*); // NOLINT + QIR_SHARED_API void quantum__qis__applyconditionallyintrinsic__body( // NOLINT + QirArray*, + QirArray*, + QirCallable*, + QirCallable*); } \ No newline at end of file diff --git a/src/QirRuntime/lib/QIR/quantum__qis_internal.hpp b/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation_internal.hpp similarity index 100% rename from src/QirRuntime/lib/QIR/quantum__qis_internal.hpp rename to src/QirRuntime/lib/QSharpFoundation/qsharp__foundation_internal.hpp diff --git a/src/QirRuntime/lib/QIR/quantum__rt.hpp b/src/QirRuntime/public/QirRuntime.hpp similarity index 98% rename from src/QirRuntime/lib/QIR/quantum__rt.hpp rename to src/QirRuntime/public/QirRuntime.hpp index 4cb5aae9163..eedcdf659b4 100644 --- a/src/QirRuntime/lib/QIR/quantum__rt.hpp +++ b/src/QirRuntime/public/QirRuntime.hpp @@ -1,296 +1,296 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -#include -#include // for va_list - -#include "CoreTypes.hpp" -#include "QirTypes.hpp" - -struct QirArray; -struct QirCallable; -struct QirString; -struct QirBigInt; - -extern "C" -{ - struct QirRange - { - int64_t start; - int64_t step; - int64_t end; - }; - - // ------------------------------------------------------------------------ - // Qubits - // ------------------------------------------------------------------------ - - // Allocates a single qubit. - QIR_SHARED_API QUBIT* quantum__rt__qubit_allocate(); // NOLINT - - // Allocates an array of qubits. - QIR_SHARED_API QirArray* quantum__rt__qubit_allocate_array(int64_t count); // NOLINT - - // Release a single qubit. - QIR_SHARED_API void quantum__rt__qubit_release(QUBIT*); // NOLINT - - // Release qubits, owned by the array. The array itself still needs to be released. - QIR_SHARED_API void quantum__rt__qubit_release_array(QirArray*); // NOLINT - - // Borrow a single qubit. - // TODO QIR_SHARED_API QUBIT* quantum__rt__qubit_borrow(); // NOLINT - - // Borrow an array of qubits. - // TODO QIR_SHARED_API QirArray* quantum__rt__qubit_borrow_array(int64_t count); // NOLINT - - // Return a borrowed qubit. - // TODO QIR_SHARED_API void quantum__rt__qubit_return(QUBIT*); // NOLINT - - // Return an array of borrowed qubits. - // TODO QIR_SHARED_API void quantum__rt__qubit_return_array(QirArray*); // NOLINT - - // ------------------------------------------------------------------------ - // Utils - // ------------------------------------------------------------------------ - - // Allocate a block of memory on the heap. - QIR_SHARED_API char* quantum__rt__heap_alloc(int size); // NOLINT - - // Release a block of allocated heap memory. - QIR_SHARED_API void quantum__rt__heap_free(char* buffer); // NOLINT - - // Fail the computation with the given error message. - QIR_SHARED_API void quantum__rt__fail(QirString* msg); // NOLINT - - // Include the given message in the computation's execution log or equivalent. - QIR_SHARED_API void quantum__rt__message(QirString* msg); // NOLINT - - // ------------------------------------------------------------------------ - // Results - // ------------------------------------------------------------------------ - - // Returns true if the two results are the same, and false if they are different. - QIR_SHARED_API bool quantum__rt__result_equal(RESULT*, RESULT*); // NOLINT - - // Adds the given integer value to the reference count for the result. Deallocates the result if the reference count - // becomes 0. The behavior is undefined if the reference count becomes negative. - QIR_SHARED_API void quantum__rt__result_update_reference_count(RESULT*, int32_t); // NOLINT - - // Not in the QIR spec right now - QIR_SHARED_API RESULT* quantum__rt__result_one(); // NOLINT - QIR_SHARED_API RESULT* quantum__rt__result_zero(); // NOLINT - - // ------------------------------------------------------------------------ - // Tuples - // ------------------------------------------------------------------------ - - // Allocates space for a tuple requiring the given number of bytes and sets the reference count to 1. - QIR_SHARED_API PTuple quantum__rt__tuple_create(int64_t); // NOLINT - - // Adds the given integer value to the reference count for the tuple. Deallocates the tuple if the reference count - // becomes 0. The behavior is undefined if the reference count becomes negative. - QIR_SHARED_API void quantum__rt__tuple_update_reference_count(PTuple, int32_t); // NOLINT - - // Adds the given integer value to the alias count for the tuple. Fails if the count becomes negative. - QIR_SHARED_API void quantum__rt__tuple_update_alias_count(PTuple, int32_t); // NOLINT - - // Creates a shallow copy of the tuple if the user count is larger than 0 or the second argument is `true`. - QIR_SHARED_API PTuple quantum__rt__tuple_copy(PTuple, bool force); // NOLINT - - // ------------------------------------------------------------------------ - // Arrrays - // ------------------------------------------------------------------------ - - // Creates a new 1-dimensional array. The int is the size of each element in bytes. The int64_t is the length - // of the array. The bytes of the new array should be set to zero. - QIR_SHARED_API QirArray* quantum__rt__array_create_1d(int32_t, int64_t); // NOLINT - - // Adds the given integer value to the reference count for the array. Deallocates the array if the reference count - // becomes 0. The behavior is undefined if the reference count becomes negative. - QIR_SHARED_API void quantum__rt__array_update_reference_count(QirArray*, int32_t); // NOLINT - - // Adds the given integer value to the alias count for the array. Fails if the count becomes negative. - QIR_SHARED_API void quantum__rt__array_update_alias_count(QirArray*, int32_t); // NOLINT - - // Creates a shallow copy of the array if the user count is larger than 0 or the second argument is `true`. - QIR_SHARED_API QirArray* quantum__rt__array_copy(QirArray*, bool); // NOLINT - - // Returns a new array which is the concatenation of the two passed-in arrays. - QIR_SHARED_API QirArray* quantum__rt__array_concatenate(QirArray*, QirArray*); // NOLINT - - // Returns the length of a dimension of the array. The int is the zero-based dimension to return the length of; it - // must be 0 for a 1-dimensional array. - QIR_SHARED_API int64_t quantum__rt__array_get_size(QirArray*, int32_t); // NOLINT - - // Returns a pointer to the element of the array at the zero-based index given by the int64_t. - QIR_SHARED_API char* quantum__rt__array_get_element_ptr_1d(QirArray*, int64_t); // NOLINT - - // Creates a new array. The first int is the size of each element in bytes. The second int is the dimension count. - // The variable arguments should be a sequence of int64_ts contains the length of each dimension. The bytes of the - // new array should be set to zero. - QIR_SHARED_API QirArray* quantum__rt__array_create(int, int, ...); // NOLINT - QIR_SHARED_API QirArray* quantum__rt__array_create_nonvariadic( // NOLINT - int itemSizeInBytes, - int countDimensions, - va_list dims); - - // Returns the number of dimensions in the array. - QIR_SHARED_API int32_t quantum__rt__array_get_dim(QirArray*); // NOLINT - - // Returns a pointer to the indicated element of the array. The variable arguments should be a sequence of int64_ts - // that are the indices for each dimension. - QIR_SHARED_API char* quantum__rt__array_get_element_ptr(QirArray*, ...); // NOLINT - QIR_SHARED_API char* quantum__rt__array_get_element_ptr_nonvariadic(QirArray*, va_list dims); // NOLINT - - // Creates and returns an array that is a slice of an existing array. The int indicates which dimension - // the slice is on. The %Range specifies the slice. - QIR_SHARED_API QirArray* quantum__rt__array_slice(QirArray*, int32_t, const QirRange&); // NOLINT - - // Creates and returns an array that is a projection of an existing array. The int indicates which dimension the - // projection is on, and the int64_t specifies the specific index value to project. The returned Array* will have - // one fewer dimension than the existing array. - QIR_SHARED_API QirArray* quantum__rt__array_project(QirArray*, int32_t, int64_t); // NOLINT - - // ------------------------------------------------------------------------ - // Callables - // ------------------------------------------------------------------------ - - // Initializes the callable with the provided function table and capture tuple. The capture tuple pointer - // should be null if there is no capture. - typedef void (*t_CallableEntry)(PTuple, PTuple, PTuple); // NOLINT - typedef void (*t_CaptureCallback)(PTuple, int64_t); // NOLINT - QIR_SHARED_API QirCallable* quantum__rt__callable_create(t_CallableEntry*, t_CaptureCallback*, PTuple); // NOLINT - - // Adds the given integer value to the reference count for the callable. Deallocates the callable if the reference - // count becomes 0. The behavior is undefined if the reference count becomes negative. - QIR_SHARED_API void quantum__rt__callable_update_reference_count(QirCallable*, int32_t); // NOLINT - - // Adds the given integer value to the alias count for the callable. Fails if the count becomes negative. - QIR_SHARED_API void quantum__rt__callable_update_alias_count(QirCallable*, int32_t); // NOLINT - - // Creates a shallow copy of the callable if the alias count is larger than 0 or the second argument is `true`. - // Returns the given callable pointer otherwise, after increasing its reference count by 1. - QIR_SHARED_API QirCallable* quantum__rt__callable_copy(QirCallable*, bool); // NOLINT - - // Invokes the callable with the provided argument tuple and fills in the result tuple. - QIR_SHARED_API void quantum__rt__callable_invoke(QirCallable*, PTuple, PTuple); // NOLINT - - // Updates the callable by applying the Adjoint functor. - QIR_SHARED_API void quantum__rt__callable_make_adjoint(QirCallable*); // NOLINT - - // Updates the callable by applying the Controlled functor. - QIR_SHARED_API void quantum__rt__callable_make_controlled(QirCallable*); // NOLINT - - // Invokes the function at the given index in the memory management table of the callable with the capture tuple and - // the given 64-bit integer. Does nothing if if the memory management table pointer or the function pointer at that - // index is null. - QIR_SHARED_API void quantum__rt__callable_memory_management(int32_t, QirCallable*, int64_t); // NOLINT - - // ------------------------------------------------------------------------ - // Strings - // ------------------------------------------------------------------------ - - // Creates a string from an array of UTF-8 bytes. - // TODO the provided constructor doesn't match the spec! - // QIR_SHARED_API QirString* quantum__rt__string_create(int, char*); // NOLINT - QIR_SHARED_API QirString* quantum__rt__string_create(const char*); // NOLINT - - // Adds the given integer value to the reference count for the string. Deallocates the string if the reference count - // becomes 0. The behavior is undefined if the reference count becomes negative. - QIR_SHARED_API void quantum__rt__string_update_reference_count(QirString*, int32_t); // NOLINT - - // Creates a new string that is the concatenation of the two argument strings. - QIR_SHARED_API QirString* quantum__rt__string_concatenate(QirString*, QirString*); // NOLINT - - // Returns true if the two strings are equal, false otherwise. - QIR_SHARED_API bool quantum__rt__string_equal(QirString*, QirString*); // NOLINT - - // Returns a string representation of the integer. - QIR_SHARED_API QirString* quantum__rt__int_to_string(int64_t); // NOLINT - - // Returns a string representation of the double. - QIR_SHARED_API QirString* quantum__rt__double_to_string(double); // NOLINT - - // Returns a string representation of the Boolean. - QIR_SHARED_API QirString* quantum__rt__bool_to_string(bool); // NOLINT - - // Returns a string representation of the result. - QIR_SHARED_API QirString* quantum__rt__result_to_string(RESULT*); // NOLINT - - // Returns a string representation of the Pauli. - QIR_SHARED_API QirString* quantum__rt__pauli_to_string(PauliId); // NOLINT - - // Returns a string representation of the qubit. - QIR_SHARED_API QirString* quantum__rt__qubit_to_string(QUBIT*); // NOLINT - - // Returns a string representation of the range. - QIR_SHARED_API QirString* quantum__rt__range_to_string(const QirRange&); // NOLINT - - // Returns a string representation of the big integer. - // TODO QIR_SHARED_API QirString* quantum__rt__bigint_to_string(QirBigInt*); // NOLINT - - // ------------------------------------------------------------------------ - // BigInts - // ------------------------------------------------------------------------ - - // Creates a big integer with the specified initial value. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_create_int64_t(int64_t); // NOLINT - - // Creates a big integer with the initial value specified by the i8 array. The 0-th element of the array is the - // highest-order byte, followed by the first element, etc. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_create_array(int, char*); // NOLINT - - // Adds the given integer value to the reference count for the big integer. Deallocates the big integer if the - // reference count becomes 0. The behavior is undefined if the reference count becomes negative. - // TODO QIR_SHARED_API void quantum__rt__bigint_update_reference_count(QirBigInt*, int32_t); // NOLINT - - // Returns the negative of the big integer. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_negate(QirBigInt*); // NOLINT - - // Adds two big integers and returns their sum. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_add(QirBigInt*, QirBigInt*); // NOLINT - - // Subtracts the second big integer from the first and returns their difference. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_subtract(QirBigInt*, QirBigInt*); // NOLINT - - // Multiplies two big integers and returns their product. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_multiply(QirBigInt*, QirBigInt*); // NOLINT - - // Divides the first big integer by the second and returns their quotient. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_divide(QirBigInt*, QirBigInt*); // NOLINT - - // Returns the first big integer modulo the second. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_modulus(QirBigInt*, QirBigInt*); // NOLINT - - // Returns the big integer raised to the integer power. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_power(QirBigInt*, int); // NOLINT - - // Returns the bitwise-AND of two big integers. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitand(QirBigInt*, QirBigInt*); // NOLINT - - // Returns the bitwise-OR of two big integers. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitor(QirBigInt*, QirBigInt*); // NOLINT - - // Returns the bitwise-XOR of two big integers. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitxor(QirBigInt*, QirBigInt*); // NOLINT - - // Returns the bitwise complement of the big integer. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitnot(QirBigInt*); // NOLINT - - // Returns the big integer arithmetically shifted left by the integer amount of bits. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_shiftleft(QirBigInt*, int64_t); // NOLINT - - // Returns the big integer arithmetically shifted right by the integer amount of bits. - // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_shiftright(QirBigInt*, int64_t); // NOLINT - - // Returns true if the two big integers are equal, false otherwise. - // TODO QIR_SHARED_API bool quantum__rt__bigint_equal(QirBigInt*, QirBigInt*); // NOLINT - - // Returns true if the first big integer is greater than the second, false otherwise. - // TODO QIR_SHARED_API bool quantum__rt__bigint_greater(QirBigInt*, QirBigInt*); // NOLINT - - // Returns true if the first big integer is greater than or equal to the second, false otherwise. - // TODO QIR_SHARED_API bool quantum__rt__bigint_greater_eq(QirBigInt*, QirBigInt*); // NOLINT +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +#include +#include // for va_list + +#include "CoreTypes.hpp" +#include "QirTypes.hpp" + +struct QirArray; +struct QirCallable; +struct QirString; +struct QirBigInt; + +extern "C" +{ + struct QirRange + { + int64_t start; + int64_t step; + int64_t end; + }; + + // ------------------------------------------------------------------------ + // Qubits + // ------------------------------------------------------------------------ + + // Allocates a single qubit. + QIR_SHARED_API QUBIT* quantum__rt__qubit_allocate(); // NOLINT + + // Allocates an array of qubits. + QIR_SHARED_API QirArray* quantum__rt__qubit_allocate_array(int64_t count); // NOLINT + + // Release a single qubit. + QIR_SHARED_API void quantum__rt__qubit_release(QUBIT*); // NOLINT + + // Release qubits, owned by the array. The array itself still needs to be released. + QIR_SHARED_API void quantum__rt__qubit_release_array(QirArray*); // NOLINT + + // Borrow a single qubit. + // TODO QIR_SHARED_API QUBIT* quantum__rt__qubit_borrow(); // NOLINT + + // Borrow an array of qubits. + // TODO QIR_SHARED_API QirArray* quantum__rt__qubit_borrow_array(int64_t count); // NOLINT + + // Return a borrowed qubit. + // TODO QIR_SHARED_API void quantum__rt__qubit_return(QUBIT*); // NOLINT + + // Return an array of borrowed qubits. + // TODO QIR_SHARED_API void quantum__rt__qubit_return_array(QirArray*); // NOLINT + + // ------------------------------------------------------------------------ + // Utils + // ------------------------------------------------------------------------ + + // Allocate a block of memory on the heap. + QIR_SHARED_API char* quantum__rt__heap_alloc(int size); // NOLINT + + // Release a block of allocated heap memory. + QIR_SHARED_API void quantum__rt__heap_free(char* buffer); // NOLINT + + // Fail the computation with the given error message. + QIR_SHARED_API void quantum__rt__fail(QirString* msg); // NOLINT + + // Include the given message in the computation's execution log or equivalent. + QIR_SHARED_API void quantum__rt__message(QirString* msg); // NOLINT + + // ------------------------------------------------------------------------ + // Results + // ------------------------------------------------------------------------ + + // Returns true if the two results are the same, and false if they are different. + QIR_SHARED_API bool quantum__rt__result_equal(RESULT*, RESULT*); // NOLINT + + // Adds the given integer value to the reference count for the result. Deallocates the result if the reference count + // becomes 0. The behavior is undefined if the reference count becomes negative. + QIR_SHARED_API void quantum__rt__result_update_reference_count(RESULT*, int32_t); // NOLINT + + // Not in the QIR spec right now + QIR_SHARED_API RESULT* quantum__rt__result_one(); // NOLINT + QIR_SHARED_API RESULT* quantum__rt__result_zero(); // NOLINT + + // ------------------------------------------------------------------------ + // Tuples + // ------------------------------------------------------------------------ + + // Allocates space for a tuple requiring the given number of bytes and sets the reference count to 1. + QIR_SHARED_API PTuple quantum__rt__tuple_create(int64_t); // NOLINT + + // Adds the given integer value to the reference count for the tuple. Deallocates the tuple if the reference count + // becomes 0. The behavior is undefined if the reference count becomes negative. + QIR_SHARED_API void quantum__rt__tuple_update_reference_count(PTuple, int32_t); // NOLINT + + // Adds the given integer value to the alias count for the tuple. Fails if the count becomes negative. + QIR_SHARED_API void quantum__rt__tuple_update_alias_count(PTuple, int32_t); // NOLINT + + // Creates a shallow copy of the tuple if the user count is larger than 0 or the second argument is `true`. + QIR_SHARED_API PTuple quantum__rt__tuple_copy(PTuple, bool force); // NOLINT + + // ------------------------------------------------------------------------ + // Arrrays + // ------------------------------------------------------------------------ + + // Creates a new 1-dimensional array. The int is the size of each element in bytes. The int64_t is the length + // of the array. The bytes of the new array should be set to zero. + QIR_SHARED_API QirArray* quantum__rt__array_create_1d(int32_t, int64_t); // NOLINT + + // Adds the given integer value to the reference count for the array. Deallocates the array if the reference count + // becomes 0. The behavior is undefined if the reference count becomes negative. + QIR_SHARED_API void quantum__rt__array_update_reference_count(QirArray*, int32_t); // NOLINT + + // Adds the given integer value to the alias count for the array. Fails if the count becomes negative. + QIR_SHARED_API void quantum__rt__array_update_alias_count(QirArray*, int32_t); // NOLINT + + // Creates a shallow copy of the array if the user count is larger than 0 or the second argument is `true`. + QIR_SHARED_API QirArray* quantum__rt__array_copy(QirArray*, bool); // NOLINT + + // Returns a new array which is the concatenation of the two passed-in arrays. + QIR_SHARED_API QirArray* quantum__rt__array_concatenate(QirArray*, QirArray*); // NOLINT + + // Returns the length of a dimension of the array. The int is the zero-based dimension to return the length of; it + // must be 0 for a 1-dimensional array. + QIR_SHARED_API int64_t quantum__rt__array_get_size(QirArray*, int32_t); // NOLINT + + // Returns a pointer to the element of the array at the zero-based index given by the int64_t. + QIR_SHARED_API char* quantum__rt__array_get_element_ptr_1d(QirArray*, int64_t); // NOLINT + + // Creates a new array. The first int is the size of each element in bytes. The second int is the dimension count. + // The variable arguments should be a sequence of int64_ts contains the length of each dimension. The bytes of the + // new array should be set to zero. + QIR_SHARED_API QirArray* quantum__rt__array_create(int, int, ...); // NOLINT + QIR_SHARED_API QirArray* quantum__rt__array_create_nonvariadic( // NOLINT + int itemSizeInBytes, + int countDimensions, + va_list dims); + + // Returns the number of dimensions in the array. + QIR_SHARED_API int32_t quantum__rt__array_get_dim(QirArray*); // NOLINT + + // Returns a pointer to the indicated element of the array. The variable arguments should be a sequence of int64_ts + // that are the indices for each dimension. + QIR_SHARED_API char* quantum__rt__array_get_element_ptr(QirArray*, ...); // NOLINT + QIR_SHARED_API char* quantum__rt__array_get_element_ptr_nonvariadic(QirArray*, va_list dims); // NOLINT + + // Creates and returns an array that is a slice of an existing array. The int indicates which dimension + // the slice is on. The %Range specifies the slice. + QIR_SHARED_API QirArray* quantum__rt__array_slice(QirArray*, int32_t, const QirRange&); // NOLINT + + // Creates and returns an array that is a projection of an existing array. The int indicates which dimension the + // projection is on, and the int64_t specifies the specific index value to project. The returned Array* will have + // one fewer dimension than the existing array. + QIR_SHARED_API QirArray* quantum__rt__array_project(QirArray*, int32_t, int64_t); // NOLINT + + // ------------------------------------------------------------------------ + // Callables + // ------------------------------------------------------------------------ + + // Initializes the callable with the provided function table and capture tuple. The capture tuple pointer + // should be null if there is no capture. + typedef void (*t_CallableEntry)(PTuple, PTuple, PTuple); // NOLINT + typedef void (*t_CaptureCallback)(PTuple, int64_t); // NOLINT + QIR_SHARED_API QirCallable* quantum__rt__callable_create(t_CallableEntry*, t_CaptureCallback*, PTuple); // NOLINT + + // Adds the given integer value to the reference count for the callable. Deallocates the callable if the reference + // count becomes 0. The behavior is undefined if the reference count becomes negative. + QIR_SHARED_API void quantum__rt__callable_update_reference_count(QirCallable*, int32_t); // NOLINT + + // Adds the given integer value to the alias count for the callable. Fails if the count becomes negative. + QIR_SHARED_API void quantum__rt__callable_update_alias_count(QirCallable*, int32_t); // NOLINT + + // Creates a shallow copy of the callable if the alias count is larger than 0 or the second argument is `true`. + // Returns the given callable pointer otherwise, after increasing its reference count by 1. + QIR_SHARED_API QirCallable* quantum__rt__callable_copy(QirCallable*, bool); // NOLINT + + // Invokes the callable with the provided argument tuple and fills in the result tuple. + QIR_SHARED_API void quantum__rt__callable_invoke(QirCallable*, PTuple, PTuple); // NOLINT + + // Updates the callable by applying the Adjoint functor. + QIR_SHARED_API void quantum__rt__callable_make_adjoint(QirCallable*); // NOLINT + + // Updates the callable by applying the Controlled functor. + QIR_SHARED_API void quantum__rt__callable_make_controlled(QirCallable*); // NOLINT + + // Invokes the function at the given index in the memory management table of the callable with the capture tuple and + // the given 64-bit integer. Does nothing if if the memory management table pointer or the function pointer at that + // index is null. + QIR_SHARED_API void quantum__rt__callable_memory_management(int32_t, QirCallable*, int64_t); // NOLINT + + // ------------------------------------------------------------------------ + // Strings + // ------------------------------------------------------------------------ + + // Creates a string from an array of UTF-8 bytes. + // TODO the provided constructor doesn't match the spec! + // QIR_SHARED_API QirString* quantum__rt__string_create(int, char*); // NOLINT + QIR_SHARED_API QirString* quantum__rt__string_create(const char*); // NOLINT + + // Adds the given integer value to the reference count for the string. Deallocates the string if the reference count + // becomes 0. The behavior is undefined if the reference count becomes negative. + QIR_SHARED_API void quantum__rt__string_update_reference_count(QirString*, int32_t); // NOLINT + + // Creates a new string that is the concatenation of the two argument strings. + QIR_SHARED_API QirString* quantum__rt__string_concatenate(QirString*, QirString*); // NOLINT + + // Returns true if the two strings are equal, false otherwise. + QIR_SHARED_API bool quantum__rt__string_equal(QirString*, QirString*); // NOLINT + + // Returns a string representation of the integer. + QIR_SHARED_API QirString* quantum__rt__int_to_string(int64_t); // NOLINT + + // Returns a string representation of the double. + QIR_SHARED_API QirString* quantum__rt__double_to_string(double); // NOLINT + + // Returns a string representation of the Boolean. + QIR_SHARED_API QirString* quantum__rt__bool_to_string(bool); // NOLINT + + // Returns a string representation of the result. + QIR_SHARED_API QirString* quantum__rt__result_to_string(RESULT*); // NOLINT + + // Returns a string representation of the Pauli. + QIR_SHARED_API QirString* quantum__rt__pauli_to_string(PauliId); // NOLINT + + // Returns a string representation of the qubit. + QIR_SHARED_API QirString* quantum__rt__qubit_to_string(QUBIT*); // NOLINT + + // Returns a string representation of the range. + QIR_SHARED_API QirString* quantum__rt__range_to_string(const QirRange&); // NOLINT + + // Returns a string representation of the big integer. + // TODO QIR_SHARED_API QirString* quantum__rt__bigint_to_string(QirBigInt*); // NOLINT + + // ------------------------------------------------------------------------ + // BigInts + // ------------------------------------------------------------------------ + + // Creates a big integer with the specified initial value. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_create_int64_t(int64_t); // NOLINT + + // Creates a big integer with the initial value specified by the i8 array. The 0-th element of the array is the + // highest-order byte, followed by the first element, etc. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_create_array(int, char*); // NOLINT + + // Adds the given integer value to the reference count for the big integer. Deallocates the big integer if the + // reference count becomes 0. The behavior is undefined if the reference count becomes negative. + // TODO QIR_SHARED_API void quantum__rt__bigint_update_reference_count(QirBigInt*, int32_t); // NOLINT + + // Returns the negative of the big integer. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_negate(QirBigInt*); // NOLINT + + // Adds two big integers and returns their sum. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_add(QirBigInt*, QirBigInt*); // NOLINT + + // Subtracts the second big integer from the first and returns their difference. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_subtract(QirBigInt*, QirBigInt*); // NOLINT + + // Multiplies two big integers and returns their product. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_multiply(QirBigInt*, QirBigInt*); // NOLINT + + // Divides the first big integer by the second and returns their quotient. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_divide(QirBigInt*, QirBigInt*); // NOLINT + + // Returns the first big integer modulo the second. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_modulus(QirBigInt*, QirBigInt*); // NOLINT + + // Returns the big integer raised to the integer power. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_power(QirBigInt*, int); // NOLINT + + // Returns the bitwise-AND of two big integers. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitand(QirBigInt*, QirBigInt*); // NOLINT + + // Returns the bitwise-OR of two big integers. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitor(QirBigInt*, QirBigInt*); // NOLINT + + // Returns the bitwise-XOR of two big integers. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitxor(QirBigInt*, QirBigInt*); // NOLINT + + // Returns the bitwise complement of the big integer. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_bitnot(QirBigInt*); // NOLINT + + // Returns the big integer arithmetically shifted left by the integer amount of bits. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_shiftleft(QirBigInt*, int64_t); // NOLINT + + // Returns the big integer arithmetically shifted right by the integer amount of bits. + // TODO QIR_SHARED_API QirBigInt* quantum__rt__bigint_shiftright(QirBigInt*, int64_t); // NOLINT + + // Returns true if the two big integers are equal, false otherwise. + // TODO QIR_SHARED_API bool quantum__rt__bigint_equal(QirBigInt*, QirBigInt*); // NOLINT + + // Returns true if the first big integer is greater than the second, false otherwise. + // TODO QIR_SHARED_API bool quantum__rt__bigint_greater(QirBigInt*, QirBigInt*); // NOLINT + + // Returns true if the first big integer is greater than or equal to the second, false otherwise. + // TODO QIR_SHARED_API bool quantum__rt__bigint_greater_eq(QirBigInt*, QirBigInt*); // NOLINT } \ No newline at end of file diff --git a/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt b/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt index 6c111cdee40..21c10647ba4 100644 --- a/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt +++ b/src/QirRuntime/test/FullstateSimulator/CMakeLists.txt @@ -7,10 +7,10 @@ add_executable(fullstate-simulator-tests target_link_libraries(fullstate-simulator-tests PUBLIC ${QIR_UTILITY_LIB} # created by compile_from_qir ${QIR_BRIDGE_UTILITY_LIB} - ${QIR_BRIDGE_QIS_UTILITY_LIB} + ${QSHARP_FOUNDATION_BRIDGE_QIS_UTILITY_LIB} ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} qir-rt-support - qir-qis-support + qsharp-foundation-qis-support qsharp-core-qis-support simulators ) diff --git a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt index ae11c1be001..d40bcbd8871 100644 --- a/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-dynamic/CMakeLists.txt @@ -27,6 +27,8 @@ target_link_libraries(qir-dynamic-tests PUBLIC ${QIR_TESTS_LIBS} "-L${CMAKE_BINARY_DIR}/lib/QIR" -lMicrosoft.Quantum.Qir.Runtime + "-L${CMAKE_BINARY_DIR}/lib/QSharpFoundation" + -lMicrosoft.Quantum.Qir.QSharp.Foundation "-L${CMAKE_BINARY_DIR}/lib/QSharpCore" -lMicrosoft.Quantum.Qir.QSharp.Core ) diff --git a/src/QirRuntime/test/QIR-static/CMakeLists.txt b/src/QirRuntime/test/QIR-static/CMakeLists.txt index 6d144560779..7e6c2f1234e 100644 --- a/src/QirRuntime/test/QIR-static/CMakeLists.txt +++ b/src/QirRuntime/test/QIR-static/CMakeLists.txt @@ -27,10 +27,10 @@ add_executable(qir-static-tests target_link_libraries(qir-static-tests PUBLIC ${QIR_TESTS_LIBS} ${QIR_BRIDGE_UTILITY_LIB} - ${QIR_BRIDGE_QIS_UTILITY_LIB} + ${QSHARP_FOUNDATION_BRIDGE_QIS_UTILITY_LIB} ${QSHARP_CORE_BRIDGE_QIS_UTILITY_LIB} qir-rt-support - qir-qis-support + qsharp-foundation-qis-support qsharp-core-qis-support simulators ) @@ -39,6 +39,7 @@ target_include_directories(qir-static-tests PUBLIC "${test_includes}" "${public_includes}" "${PROJECT_SOURCE_DIR}/lib/QIR" + "${PROJECT_SOURCE_DIR}/lib/QSharpFoundation" ) target_compile_definitions(qir-static-tests PRIVATE EXPORT_QIR_API) add_dependencies(qir-static-tests qir_static_test_lib) diff --git a/src/QirRuntime/test/QIR-static/qir-driver.cpp b/src/QirRuntime/test/QIR-static/qir-driver.cpp index c9157c42fcf..558b1c3b150 100644 --- a/src/QirRuntime/test/QIR-static/qir-driver.cpp +++ b/src/QirRuntime/test/QIR-static/qir-driver.cpp @@ -14,7 +14,7 @@ #include "QuantumApi_I.hpp" #include "SimFactory.hpp" #include "SimulatorStub.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file #include "catch.hpp" diff --git a/src/QirRuntime/test/QIR-static/qir-test-math.cpp b/src/QirRuntime/test/QIR-static/qir-test-math.cpp index 6995f4ac285..b46b2ed4a1e 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-math.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-math.cpp @@ -6,7 +6,7 @@ #include "catch.hpp" -#include "quantum__qis_internal.hpp" +#include "qsharp__foundation_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 diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 1f74986dfdf..92f487c0ef5 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -6,7 +6,7 @@ #include "catch.hpp" #include "QirTypes.hpp" -#include "quantum__qis_internal.hpp" +#include "qsharp__foundation_internal.hpp" extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(void*); // NOLINT diff --git a/src/QirRuntime/test/unittests/CMakeLists.txt b/src/QirRuntime/test/unittests/CMakeLists.txt index dbc96a627ca..29e3357f695 100644 --- a/src/QirRuntime/test/unittests/CMakeLists.txt +++ b/src/QirRuntime/test/unittests/CMakeLists.txt @@ -10,7 +10,7 @@ add_executable(qir-runtime-unittests target_link_libraries(qir-runtime-unittests PUBLIC qir-rt-support - qir-qis-support + qsharp-foundation-qis-support qsharp-core-qis-support simulators tracer @@ -20,6 +20,7 @@ target_include_directories(qir-runtime-unittests PUBLIC "${test_includes}" ${public_includes} "${PROJECT_SOURCE_DIR}/lib/QIR" + "${PROJECT_SOURCE_DIR}/lib/QSharpFoundation" "${PROJECT_SOURCE_DIR}/lib/QSharpCore" "${PROJECT_SOURCE_DIR}/lib/Tracer" ) diff --git a/src/QirRuntime/test/unittests/QirRuntimeTests.cpp b/src/QirRuntime/test/unittests/QirRuntimeTests.cpp index b52554ad898..b59b88d8828 100644 --- a/src/QirRuntime/test/unittests/QirRuntimeTests.cpp +++ b/src/QirRuntime/test/unittests/QirRuntimeTests.cpp @@ -10,9 +10,9 @@ #include #include "QirTypes.hpp" -#include "quantum__qis.hpp" +#include "qsharp__foundation__qis.hpp" #include "qsharp__core__qis.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" #include "BitStates.hpp" #include "QirContext.hpp" From 500f0bc88d5eb83b4147eb9619d8b9fbeb70f02d Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Mar 2021 21:19:40 +0000 Subject: [PATCH 31/31] Convert sample to dynamic, add to scripts --- .../lib/QSharpFoundation/intrinsicsOut.cpp | 21 ++++++++----------- .../qsharp__foundation_internal.hpp | 1 - src/QirRuntime/public/SimFactory.hpp | 1 + .../StandaloneInputReference/CMakeLists.txt | 13 ++++++------ .../StandaloneInputReference/qir-driver.cpp | 8 +++---- src/QirRuntime/test-qir-runtime.ps1 | 13 ++++++++++++ .../test/QIR-static/qir-test-ouput.cpp | 5 +++-- 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp b/src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp index 3ab0f538b58..99eb2292dac 100644 --- a/src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp +++ b/src/QirRuntime/lib/QSharpFoundation/intrinsicsOut.cpp @@ -4,6 +4,7 @@ #include #include "QirTypes.hpp" +#include "SimFactory.hpp" #include "qsharp__foundation__qis.hpp" // Forward declarations: @@ -28,20 +29,16 @@ static std::ostream& GetOutputStream() } -// For test purposes only: -namespace Quantum // Replace with `namespace Quantum::Qis::Internal` after migration to C++17. +namespace Microsoft // Replace with `namespace Microsoft::Quantum` after migration to C++17. { -namespace Qis +namespace Quantum { - namespace Internal + std::ostream& SetOutputStream(std::ostream & newOStream) { - std::ostream& SetOutputStream(std::ostream & newOStream) - { - std::ostream& oldOStream = *currentOutputStream; - currentOutputStream = &newOStream; - return oldOStream; - } - } // namespace Internal -} // namespace Qis + std::ostream& oldOStream = *currentOutputStream; + currentOutputStream = &newOStream; + return oldOStream; + } } // namespace Quantum +} // namespace Microsoft diff --git a/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation_internal.hpp b/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation_internal.hpp index 673b41d28e3..6e923191efe 100644 --- a/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation_internal.hpp +++ b/src/QirRuntime/lib/QSharpFoundation/qsharp__foundation_internal.hpp @@ -15,7 +15,6 @@ namespace Qis { extern char const excStrDrawRandomInt[]; - extern std::ostream& SetOutputStream(std::ostream& newOStream); void RandomizeSeed(bool randomize); int64_t GetLastGeneratedRandomNumber(); } // namespace Internal diff --git a/src/QirRuntime/public/SimFactory.hpp b/src/QirRuntime/public/SimFactory.hpp index f2e31a40dec..f29f790c5b5 100644 --- a/src/QirRuntime/public/SimFactory.hpp +++ b/src/QirRuntime/public/SimFactory.hpp @@ -15,5 +15,6 @@ namespace Quantum // Full State Simulator QIR_SHARED_API std::unique_ptr CreateFullstateSimulator(); + QIR_SHARED_API std::ostream& SetOutputStream(std::ostream& newOStream); } // namespace Quantum } // namespace Microsoft \ No newline at end of file diff --git a/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt b/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt index 93a72e0ef0a..fb694fa533b 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt +++ b/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt @@ -1,7 +1,6 @@ #======================================================================================================================= # This is a reference make file on how to build a QIR-based standalone executable. #======================================================================================================================= - add_executable(qir-input-reference-standalone qir-driver.cpp ) @@ -11,11 +10,12 @@ compile_from_qir(qir-standalone-input-reference qir_standalone_input_reference_t target_link_libraries(qir-input-reference-standalone PUBLIC ${QIR_UTILITY_LIB} # created by compile_from_qir - ${QIR_BRIDGE_UTILITY_LIB} - ${QIR_BRIDGE_QIS_UTILITY_LIB} - qir-rt-support - qir-qis-support - simulators + "-L${CMAKE_BINARY_DIR}/lib/QIR" + -lMicrosoft.Quantum.Qir.Runtime + "-L${CMAKE_BINARY_DIR}/lib/QSharpFoundation" + -lMicrosoft.Quantum.Qir.QSharp.Foundation + "-L${CMAKE_BINARY_DIR}/lib/QSharpCore" + -lMicrosoft.Quantum.Qir.QSharp.Core ) set(standalone_includes "${PROJECT_SOURCE_DIR}/externals/CLI11") @@ -23,7 +23,6 @@ set(standalone_includes "${PROJECT_SOURCE_DIR}/externals/CLI11") target_include_directories(qir-input-reference-standalone PUBLIC "${standalone_includes}" "${public_includes}" - "${PROJECT_SOURCE_DIR}/lib/QIR" ) add_dependencies(qir-input-reference-standalone qir_standalone_input_reference_target) diff --git a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp index 2177e3e6f0a..843b7cf1830 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp +++ b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp @@ -15,9 +15,7 @@ #include "QirTypes.hpp" #include "QuantumApi_I.hpp" #include "SimFactory.hpp" - -#include "quantum__qis_internal.hpp" -#include "quantum__rt.hpp" +#include "QirRuntime.hpp" using namespace Microsoft::Quantum; using namespace std; @@ -226,13 +224,13 @@ int main(int argc, char* argv[]) // Create a QirString. QirString* qirString = quantum__rt__string_create(stringValue.c_str()); - // Redirect the simulator output from std::cout if the --simulator-output option is present. + // Redirect the simulator output from std::cout if the --simulation-output option is present. ostream* simulatorOutputStream = &cout; ofstream simulationOutputFileStream; if (!simulationOutputFileOpt->empty()) { simulationOutputFileStream.open(simulationOutputFile); - Quantum::Qis::Internal::SetOutputStream(simulationOutputFileStream); + SetOutputStream(simulationOutputFileStream); simulatorOutputStream = &simulationOutputFileStream; } diff --git a/src/QirRuntime/test-qir-runtime.ps1 b/src/QirRuntime/test-qir-runtime.ps1 index 663231acfbf..0b0094e1054 100644 --- a/src/QirRuntime/test-qir-runtime.ps1 +++ b/src/QirRuntime/test-qir-runtime.ps1 @@ -13,3 +13,16 @@ if ($LastExitCode -ne 0) { } Pop-Location + +Write-Host "##[info]Test QIR Standalone Sample" + +Push-Location (Join-Path $PSScriptRoot build $Env:BUILD_CONFIGURATION samples StandaloneInputReference) + +ctest --verbose + +if ($LastExitCode -ne 0) { + Write-Host "##vso[task.logissue type=error;]Failed to test QIR Standalone Sample" + $script:all_ok = $False +} + +Pop-Location diff --git a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp index 92f487c0ef5..a7d47893926 100644 --- a/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp +++ b/src/QirRuntime/test/QIR-static/qir-test-ouput.cpp @@ -6,6 +6,7 @@ #include "catch.hpp" #include "QirTypes.hpp" +#include "SimFactory.hpp" #include "qsharp__foundation_internal.hpp" extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(void*); // NOLINT @@ -17,12 +18,12 @@ extern "C" void Microsoft__Quantum__Testing__QIR__Out__MessageTest__body(void*); struct OstreamRedirectorScoped { OstreamRedirectorScoped(std::ostream& newOstream) - : old(Quantum::Qis::Internal::SetOutputStream(newOstream)) + : old(Microsoft::Quantum::SetOutputStream(newOstream)) {} ~OstreamRedirectorScoped() { - Quantum::Qis::Internal::SetOutputStream(old); + Microsoft::Quantum::SetOutputStream(old); } private: