summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analysis/lattice.h12
-rw-r--r--src/tools/CMakeLists.txt1
-rw-r--r--src/tools/wasm-fuzz-lattices.cpp509
-rw-r--r--test/lit/fuzz-lattices.test1305
4 files changed, 1827 insertions, 0 deletions
diff --git a/src/analysis/lattice.h b/src/analysis/lattice.h
index 5ab92a320..a5c7047dd 100644
--- a/src/analysis/lattice.h
+++ b/src/analysis/lattice.h
@@ -11,6 +11,18 @@ namespace wasm::analysis {
enum LatticeComparison { NO_RELATION, EQUAL, LESS, GREATER };
+// If parameter "comparison" compares x and y, the function returns the opposite
+// direction comparison between y and x.
+inline LatticeComparison reverseComparison(LatticeComparison comparison) {
+ if (comparison == LatticeComparison::LESS) {
+ return LatticeComparison::GREATER;
+ } else if (comparison == LatticeComparison::GREATER) {
+ return LatticeComparison::LESS;
+ } else {
+ return comparison;
+ }
+}
+
template<typename Lattice>
constexpr bool has_getBottom =
std::is_invocable_r<typename Lattice::Element,
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 3d12b4e34..c73797f54 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -19,6 +19,7 @@ if(NOT BUILD_EMSCRIPTEN_TOOLS_ONLY)
binaryen_add_executable(wasm-reduce wasm-reduce.cpp)
binaryen_add_executable(wasm-merge wasm-merge.cpp)
binaryen_add_executable(wasm-fuzz-types "${fuzzing_SOURCES};wasm-fuzz-types.cpp")
+ binaryen_add_executable(wasm-fuzz-lattices "${fuzzing_SOURCES};wasm-fuzz-lattices.cpp")
endif()
add_subdirectory(wasm-split)
diff --git a/src/tools/wasm-fuzz-lattices.cpp b/src/tools/wasm-fuzz-lattices.cpp
new file mode 100644
index 000000000..c31d64290
--- /dev/null
+++ b/src/tools/wasm-fuzz-lattices.cpp
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2023 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <optional>
+#include <random>
+#include <string>
+
+#include "analysis/lattice.h"
+#include "analysis/liveness-transfer-function.h"
+#include "analysis/reaching-definitions-transfer-function.h"
+
+#include "support/command-line.h"
+#include "tools/fuzzing.h"
+#include "tools/fuzzing/random.h"
+
+namespace wasm {
+using RandEngine = std::mt19937_64;
+using namespace analysis;
+
+// Helps printing error messages.
+std::string LatticeComparisonNames[4] = {
+ "No Relation", "Equal", "Less", "Greater"};
+std::string LatticeComparisonSymbols[4] = {"?", "=", "<", ">"};
+
+uint64_t getSeed() {
+ // Return a (truly) random 64-bit value.
+ std::random_device rand;
+ return std::uniform_int_distribution<uint64_t>{}(rand);
+}
+
+// Utility class which provides methods to check properties of the transfer
+// function and lattice of an analysis.
+template<typename Lattice, typename TransferFunction> struct AnalysisChecker {
+ Lattice& lattice;
+ TransferFunction& transferFunction;
+ std::string latticeName;
+ std::string transferFunctionName;
+ uint64_t latticeElementSeed;
+ Name funcName;
+
+ AnalysisChecker(Lattice& lattice,
+ TransferFunction& transferFunction,
+ std::string latticeName,
+ std::string transferFunctionName,
+ uint64_t latticeElementSeed,
+ Name funcName)
+ : lattice(lattice), transferFunction(transferFunction),
+ latticeName(latticeName), transferFunctionName(transferFunctionName),
+ latticeElementSeed(latticeElementSeed), funcName(funcName) {}
+
+ void printFailureInfo(std::ostream& os) {
+ os << "Error for " << transferFunctionName << " and " << latticeName
+ << " at lattice element seed " << latticeElementSeed << " and function "
+ << funcName << ".\n";
+ }
+
+ // Prints information about a particular test case consisting of a randomly
+ // generated function and triple of randomly generate lattice elements.
+ void printVerboseFunctionCase(std::ostream& os,
+ typename Lattice::Element& x,
+ typename Lattice::Element& y,
+ typename Lattice::Element& z) {
+ os << "Using lattice element seed " << latticeElementSeed << "\nGenerated "
+ << latticeName << " elements:\n";
+ x.print(os);
+ os << ",\n";
+ y.print(os);
+ os << ",\n";
+ z.print(os);
+ os << "\nfor " << funcName << " to test " << transferFunctionName
+ << ".\n\n";
+ }
+
+ // Checks reflexivity of a lattice element, i.e. x = x.
+ void checkReflexivity(typename Lattice::Element& element) {
+ LatticeComparison result = lattice.compare(element, element);
+ if (result != LatticeComparison::EQUAL) {
+ std::stringstream ss;
+ printFailureInfo(ss);
+ ss << "Element ";
+ element.print(ss);
+ ss << " is not reflexive.\n";
+ Fatal() << ss.str();
+ }
+ }
+
+ // Anti-Symmetry is defined as x <= y and y <= x imply x = y. Due to the
+ // fact that the compare(x, y) function of the lattice explicitly tells
+ // us if two lattice elements are <, =, or = instead of providing a
+ // <= comparison, it is not useful to check for anti-symmetry as it is defined
+ // in the fuzzer.
+ //
+ // Instead, we check for a related concept that x < y implies y > x, and
+ // vice versa in this checkAntiSymmetry function.
+ void checkAntiSymmetry(typename Lattice::Element& x,
+ typename Lattice::Element& y) {
+ LatticeComparison result = lattice.compare(x, y);
+ LatticeComparison reverseResult = lattice.compare(y, x);
+
+ if (reverseComparison(result) != reverseResult) {
+ std::stringstream ss;
+ printFailureInfo(ss);
+ x.print(ss);
+ ss << " " << LatticeComparisonNames[result] << " ";
+ y.print(ss);
+ ss << " but reverse direction comparison is "
+ << LatticeComparisonNames[reverseResult] << ".\n";
+ Fatal() << ss.str();
+ }
+ }
+
+private:
+ // Prints the error message when a triple of lattice elements violates
+ // transitivity.
+ void printTransitivityError(std::ostream& os,
+ typename Lattice::Element& a,
+ typename Lattice::Element& b,
+ typename Lattice::Element& c,
+ LatticeComparison ab,
+ LatticeComparison bc,
+ LatticeComparison ac) {
+ printFailureInfo(os);
+ os << "Elements a = ";
+ a.print(os);
+ os << ", b = ";
+ b.print(os);
+ os << ", and c = ";
+ c.print(os);
+ os << " are not transitive. a" << LatticeComparisonSymbols[ab] << "b and b"
+ << LatticeComparisonSymbols[bc] << "c, but a"
+ << LatticeComparisonSymbols[ac] << "c.\n";
+ }
+
+ // Returns true if given a-b and b-c comparisons, the a-c comparison violates
+ // transitivity.
+ bool violatesTransitivity(LatticeComparison ab,
+ LatticeComparison bc,
+ LatticeComparison ac) {
+ if (ab != LatticeComparison::NO_RELATION &&
+ (bc == LatticeComparison::EQUAL || bc == ab) && ab != ac) {
+ return true;
+ } else if (bc != LatticeComparison::NO_RELATION &&
+ (ab == LatticeComparison::EQUAL || ab == bc) && bc != ac) {
+ return true;
+ }
+ return false;
+ }
+
+public:
+ // Given three lattice elements x, y, and z, checks if transitivity holds
+ // between them.
+ void checkTransitivity(typename Lattice::Element& x,
+ typename Lattice::Element& y,
+ typename Lattice::Element& z) {
+ LatticeComparison xy = lattice.compare(x, y);
+ LatticeComparison yz = lattice.compare(y, z);
+ LatticeComparison xz = lattice.compare(x, z);
+
+ LatticeComparison yx = reverseComparison(xy);
+ LatticeComparison zy = reverseComparison(yz);
+
+ // Cover all permutations of x, y, and z.
+ if (violatesTransitivity(xy, yz, xz)) {
+ std::stringstream ss;
+ printTransitivityError(ss, x, y, z, xy, yz, xz);
+ Fatal() << ss.str();
+ } else if (violatesTransitivity(yx, xz, yz)) {
+ std::stringstream ss;
+ printTransitivityError(ss, y, x, z, yx, xz, yz);
+ Fatal() << ss.str();
+ } else if (violatesTransitivity(xz, zy, xy)) {
+ std::stringstream ss;
+ printTransitivityError(ss, x, z, y, xz, zy, xy);
+ Fatal() << ss.str();
+ }
+ }
+
+ // Given two input - output lattice pairs of a transfer function, checks if
+ // the transfer function is monotonic. If this is violated, then we print out
+ // the CFG block input which caused the transfer function to exhibit
+ // non-monotonic behavior.
+ void checkMonotonicity(const BasicBlock* cfgBlock,
+ typename Lattice::Element& first,
+ typename Lattice::Element& second,
+ typename Lattice::Element& firstResult,
+ typename Lattice::Element& secondResult) {
+ LatticeComparison beforeCmp = lattice.compare(first, second);
+ LatticeComparison afterCmp = lattice.compare(firstResult, secondResult);
+
+ // Cases in which monotonicity is preserved.
+ if (beforeCmp == LatticeComparison::NO_RELATION) {
+ // If there is no relation in the first place, we can't expect anything.
+ return;
+ } else if (beforeCmp == LatticeComparison::LESS &&
+ (afterCmp == LatticeComparison::LESS ||
+ afterCmp == LatticeComparison::EQUAL)) {
+ // x < y and f(x) <= f(y)
+ return;
+ } else if (beforeCmp == LatticeComparison::GREATER &&
+ (afterCmp == LatticeComparison::GREATER ||
+ afterCmp == LatticeComparison::EQUAL)) {
+ // x > y and f(x) >= f(y)
+ return;
+ } else if (beforeCmp == LatticeComparison::EQUAL &&
+ afterCmp == LatticeComparison::EQUAL) {
+ // x = y and f(x) = f(y)
+ return;
+ }
+
+ std::stringstream ss;
+ printFailureInfo(ss);
+
+ ss << "Elements ";
+ first.print(ss);
+ ss << " -> ";
+ firstResult.print(ss);
+ ss << " and ";
+ second.print(ss);
+ ss << " -> ";
+ secondResult.print(ss);
+ ss << "\n show that the transfer function is not monotone when given the "
+ "input:\n";
+ cfgBlock->print(ss);
+ ss << "\n";
+
+ Fatal() << ss.str();
+ }
+
+ // Checks lattice-only properties for a triple of lattices.
+ void checkLatticeElements(typename Lattice::Element x,
+ typename Lattice::Element y,
+ typename Lattice::Element z) {
+ checkReflexivity(x);
+ checkReflexivity(y);
+ checkReflexivity(z);
+ checkAntiSymmetry(x, y);
+ checkAntiSymmetry(x, z);
+ checkAntiSymmetry(y, z);
+ checkTransitivity(x, y, z);
+ }
+
+ // Checks transfer function relevant properties given a CFG and three input
+ // states. It does this by applying the transfer function on each CFG block
+ // using the same three input states each time and then checking properties on
+ // the inputs and outputs.
+ void checkTransferFunction(CFG& cfg,
+ typename Lattice::Element x,
+ typename Lattice::Element y,
+ typename Lattice::Element z) {
+ for (auto cfgIter = cfg.begin(); cfgIter != cfg.end(); ++cfgIter) {
+ // Apply transfer function on each lattice element.
+ typename Lattice::Element xResult = x;
+ transferFunction.transfer(&(*cfgIter), xResult);
+ typename Lattice::Element yResult = y;
+ transferFunction.transfer(&(*cfgIter), yResult);
+ typename Lattice::Element zResult = z;
+ transferFunction.transfer(&(*cfgIter), zResult);
+
+ // Check monotonicity for every pair of transfer function outputs.
+ checkMonotonicity(&(*cfgIter), x, y, xResult, yResult);
+ checkMonotonicity(&(*cfgIter), x, z, xResult, zResult);
+ checkMonotonicity(&(*cfgIter), y, z, yResult, zResult);
+ }
+ }
+};
+
+// Struct to set up and check liveness analysis lattice and transfer function.
+struct LivenessChecker {
+ LivenessTransferFunction transferFunction;
+ FiniteIntPowersetLattice lattice;
+ AnalysisChecker<FiniteIntPowersetLattice, LivenessTransferFunction> checker;
+ LivenessChecker(Function* func, uint64_t latticeElementSeed, Name funcName)
+ : lattice(func->getNumLocals()), checker(lattice,
+ transferFunction,
+ "FiniteIntPowersetLattice",
+ "LivenessTransferFunction",
+ latticeElementSeed,
+ funcName) {}
+
+ FiniteIntPowersetLattice::Element getRandomElement(Random& rand) {
+ FiniteIntPowersetLattice::Element result = lattice.getBottom();
+
+ // Uses rand to randomly select which members are to be included (i. e. flip
+ // bits in the bitvector).
+ for (size_t i = 0; i < lattice.getSetSize(); ++i) {
+ result.set(i, rand.oneIn(2));
+ }
+ return result;
+ }
+
+ // Runs all checks for liveness analysis.
+ void runChecks(CFG& cfg, Random& rand, bool verbose) {
+ FiniteIntPowersetLattice::Element x = getRandomElement(rand);
+ FiniteIntPowersetLattice::Element y = getRandomElement(rand);
+ FiniteIntPowersetLattice::Element z = getRandomElement(rand);
+
+ if (verbose) {
+ checker.printVerboseFunctionCase(std::cout, x, y, z);
+ }
+
+ checker.checkLatticeElements(x, y, z);
+ checker.checkTransferFunction(cfg, x, y, z);
+ }
+};
+
+// Struct to set up and check reaching definitions analysis lattice and transfer
+// function.
+struct ReachingDefinitionsChecker {
+ LocalGraph::GetSetses getSetses;
+ LocalGraph::Locations locations;
+ ReachingDefinitionsTransferFunction transferFunction;
+ AnalysisChecker<FinitePowersetLattice<LocalSet*>,
+ ReachingDefinitionsTransferFunction>
+ checker;
+ ReachingDefinitionsChecker(Function* func,
+ uint64_t latticeElementSeed,
+ Name funcName)
+ : transferFunction(func, getSetses, locations),
+ checker(transferFunction.lattice,
+ transferFunction,
+ "FinitePowersetLattice<LocalSet*>",
+ "ReachingDefinitionsTransferFunction",
+ latticeElementSeed,
+ funcName) {}
+
+ FinitePowersetLattice<LocalSet*>::Element getRandomElement(Random& rand) {
+ FinitePowersetLattice<LocalSet*>::Element result =
+ transferFunction.lattice.getBottom();
+
+ // Uses rand to randomly select which members are to be included (i. e. flip
+ // bits in the bitvector).
+ for (size_t i = 0; i < transferFunction.lattice.getSetSize(); ++i) {
+ result.set(i, rand.oneIn(2));
+ }
+ return result;
+ }
+
+ // Runs all checks for reaching definitions analysis.
+ void runChecks(CFG& cfg, Random& rand, bool verbose) {
+ FinitePowersetLattice<LocalSet*>::Element x = getRandomElement(rand);
+ FinitePowersetLattice<LocalSet*>::Element y = getRandomElement(rand);
+ FinitePowersetLattice<LocalSet*>::Element z = getRandomElement(rand);
+
+ if (verbose) {
+ checker.printVerboseFunctionCase(std::cout, x, y, z);
+ }
+
+ checker.checkLatticeElements(x, y, z);
+ checker.checkTransferFunction(cfg, x, y, z);
+ }
+};
+
+struct Fuzzer {
+ bool verbose;
+
+ Fuzzer(bool verbose) : verbose(verbose) {}
+
+ // Helper function to run per-function tests. latticeElementSeed is used to
+ // generate three lattice elements randomly. It is also used to select which
+ // analysis is to be tested for the function.
+ void runOnFunction(Function* func, uint64_t latticeElementSeed) {
+ RandEngine getFuncRand(latticeElementSeed);
+
+ // Fewer bytes are needed to generate three random lattices.
+ std::vector<char> funcBytes(128);
+ for (size_t i = 0; i < funcBytes.size(); i += sizeof(uint64_t)) {
+ *(uint64_t*)(funcBytes.data() + i) = getFuncRand();
+ }
+
+ Random rand(std::move(funcBytes));
+
+ CFG cfg = CFG::fromFunction(func);
+
+ switch (rand.upTo(2)) {
+ case 0: {
+ LivenessChecker livenessChecker(func, latticeElementSeed, func->name);
+ livenessChecker.runChecks(cfg, rand, verbose);
+ break;
+ }
+ default: {
+ ReachingDefinitionsChecker reachingDefinitionsChecker(
+ func, latticeElementSeed, func->name);
+ reachingDefinitionsChecker.runChecks(cfg, rand, verbose);
+ }
+ }
+ }
+
+ // Generates a module. The module is used as an input to fuzz transfer
+ // functions as well as randomly generated lattice element states. Lattice
+ // properties are also fuzzed from the randomly generated states.
+ void run(uint64_t seed,
+ uint64_t* latticeElementSeed = nullptr,
+ std::string* funcName = nullptr) {
+ RandEngine getRand(seed);
+ std::cout << "Running with seed " << seed << "\n";
+
+ // 4kb of random bytes should be enough for anyone!
+ std::vector<char> bytes(4096);
+ for (size_t i = 0; i < bytes.size(); i += sizeof(uint64_t)) {
+ *(uint64_t*)(bytes.data() + i) = getRand();
+ }
+
+ Module testModule;
+ TranslateToFuzzReader reader(testModule, std::move(bytes));
+ reader.build();
+
+ if (verbose) {
+ std::cout << "Generated test module: \n";
+ std::cout << testModule;
+ std::cout << "\n";
+ }
+
+ // If a specific function and lattice element seed is specified, only run
+ // that.
+ if (latticeElementSeed && funcName) {
+ runOnFunction(testModule.getFunction(*funcName), *latticeElementSeed);
+ return;
+ }
+
+ ModuleUtils::iterDefinedFunctions(testModule, [&](Function* func) {
+ uint64_t funcSeed = getRand();
+ runOnFunction(func, funcSeed);
+ });
+ }
+};
+
+} // namespace wasm
+
+int main(int argc, const char* argv[]) {
+ using namespace wasm;
+
+ const std::string WasmFuzzTypesOption = "wasm-fuzz-lattices options";
+
+ Options options("wasm-fuzz-lattices",
+ "Fuzz lattices for reflexivity, transitivity, and "
+ "anti-symmetry, and tranfer functions for monotonicity.");
+
+ std::optional<uint64_t> seed;
+ options.add("--seed",
+ "",
+ "Run a single workload generated by the given seed",
+ WasmFuzzTypesOption,
+ Options::Arguments::One,
+ [&](Options*, const std::string& arg) {
+ seed = uint64_t(std::stoull(arg));
+ });
+
+ std::optional<uint64_t> latticeElementSeed;
+ options.add("--lattice-element-seed",
+ "",
+ "Seed which generated the lattice elements to be checked.",
+ WasmFuzzTypesOption,
+ Options::Arguments::One,
+ [&](Options*, const std::string& arg) {
+ latticeElementSeed = uint64_t(std::stoull(arg));
+ });
+
+ std::optional<std::string> functionName;
+ options.add(
+ "--function-name",
+ "",
+ "Name of the function in the module generated by --seed to be checked.",
+ WasmFuzzTypesOption,
+ Options::Arguments::One,
+ [&](Options*, const std::string& arg) { functionName = arg; });
+
+ bool verbose = false;
+ options.add("--verbose",
+ "-v",
+ "Print extra information",
+ WasmFuzzTypesOption,
+ Options::Arguments::Zero,
+ [&](Options*, const std::string& arg) { verbose = true; });
+
+ options.parse(argc, argv);
+
+ Fuzzer fuzzer{verbose};
+ if (seed) {
+ if (latticeElementSeed && functionName) {
+ // Run test a single function and lattice element seed.
+ fuzzer.run(*seed, &(*latticeElementSeed), &(*functionName));
+ } else {
+ // Run just a single workload with the given seed.
+ fuzzer.run(*seed);
+ }
+ } else {
+ // Continuously run workloads with new randomly generated seeds.
+ size_t i = 0;
+ RandEngine nextSeed(getSeed());
+ while (true) {
+ std::cout << "Iteration " << ++i << "\n";
+ fuzzer.run(nextSeed());
+ }
+ }
+ return 0;
+}
diff --git a/test/lit/fuzz-lattices.test b/test/lit/fuzz-lattices.test
new file mode 100644
index 000000000..361c46930
--- /dev/null
+++ b/test/lit/fuzz-lattices.test
@@ -0,0 +1,1305 @@
+;; RUN: wasm-fuzz-lattices -v --seed=0 | filecheck %s
+
+;; CHECK: Running with seed 0
+;; CHECK-NEXT: Generated test module:
+;; CHECK-NEXT: (module
+;; CHECK-NEXT: (type $none_=>_none (func))
+;; CHECK-NEXT: (type $none_=>_i32 (func (result i32)))
+;; CHECK-NEXT: (type $none_=>_i64 (func (result i64)))
+;; CHECK-NEXT: (type $i32_=>_none (func (param i32)))
+;; CHECK-NEXT: (type $i64_=>_none (func (param i64)))
+;; CHECK-NEXT: (type $f32_=>_none (func (param f32)))
+;; CHECK-NEXT: (type $f64_=>_none (func (param f64)))
+;; CHECK-NEXT: (type $i32_=>_f32 (func (param i32) (result f32)))
+;; CHECK-NEXT: (type $i32_f32_f64_f32_=>_i32 (func (param i32 f32 f64 f32) (result i32)))
+;; CHECK-NEXT: (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
+;; CHECK-NEXT: (import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))
+;; CHECK-NEXT: (import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))
+;; CHECK-NEXT: (import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))
+;; CHECK-NEXT: (global $global$ i64 (i64.const -13))
+;; CHECK-NEXT: (global $global$_1 i64 (i64.const -281474976710655))
+;; CHECK-NEXT: (global $global$_2 (mut i32) (i32.const 32767))
+;; CHECK-NEXT: (global $global$_3 i64 (i64.const 65534))
+;; CHECK-NEXT: (global $global$_4 f32 (f32.const -0.484000027179718))
+;; CHECK-NEXT: (global $global$_5 (mut f32) (f32.const 3402823466385288598117041e14))
+;; CHECK-NEXT: (global $global$_6 (mut f64) (f64.const 392913192))
+;; CHECK-NEXT: (global $global$_7 i32 (i32.const -1))
+;; CHECK-NEXT: (global $global$_8 i32 (i32.const -7151))
+;; CHECK-NEXT: (global $global$_9 f64 (f64.const 64257))
+;; CHECK-NEXT: (global $global$_10 i32 (i32.const -511))
+;; CHECK-NEXT: (global $global$_11 (mut i32) (i32.const -2))
+;; CHECK-NEXT: (global $global$_12 (mut i32) (i32.const -101))
+;; CHECK-NEXT: (global $global$_13 (mut f64) (f64.const -17592186044415.012))
+;; CHECK-NEXT: (global $global$_14 i32 (i32.const 1))
+;; CHECK-NEXT: (global $hangLimit (mut i32) (i32.const 100))
+;; CHECK-NEXT: (memory $0 16 17)
+;; CHECK-NEXT: (data $0 (i32.const 0) "\00\00 ")
+;; CHECK-NEXT: (table $fuzzing_table 0 funcref)
+;; CHECK-NEXT: (elem $elem$ (i32.const 0))
+;; CHECK-NEXT: (export "func" (func $func))
+;; CHECK-NEXT: (export "func_invoker" (func $func_invoker))
+;; CHECK-NEXT: (export "func_6" (func $func_6))
+;; CHECK-NEXT: (export "func_6_invoker" (func $func_6_invoker))
+;; CHECK-NEXT: (export "func_8_invoker" (func $func_8_invoker))
+;; CHECK-NEXT: (export "func_10_invoker" (func $func_10_invoker))
+;; CHECK-NEXT: (export "hashMemory" (func $hashMemory))
+;; CHECK-NEXT: (export "memory" (memory $0))
+;; CHECK-NEXT: (func $func (param $0 i32) (result f32)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (f32.sub
+;; CHECK-NEXT: (f32.load offset=4 align=1
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.const -26294)
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (loop $label$12 (result f32)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$13 (result f32)
+;; CHECK-NEXT: (block $label$14
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (f64.ge
+;; CHECK-NEXT: (loop $label$15 (result f64)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block (result f64)
+;; CHECK-NEXT: (block $label$16
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$15
+;; CHECK-NEXT: (select
+;; CHECK-NEXT: (i32.const -4)
+;; CHECK-NEXT: (block $label$18 (result i32)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (if (result i32)
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (global.get $global$_14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.get $global$_6)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (f64.const -nan:0xfffffffffff9b)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$14
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (i32.const -112)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (if (result f32)
+;; CHECK-NEXT: (loop $label$24 (result i32)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block (result i32)
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$24
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$25 (result i32)
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (block $label$26
+;; CHECK-NEXT: (call $log-f32
+;; CHECK-NEXT: (br_if $label$13
+;; CHECK-NEXT: (f32.const -18446744073709551615)
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (loop $label$27 (result i32)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block (result i32)
+;; CHECK-NEXT: (block $label$28
+;; CHECK-NEXT: (call $log-f64
+;; CHECK-NEXT: (if (result f64)
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (i32.const 7)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (f64.const -64)
+;; CHECK-NEXT: (f64.const -nan:0xfffffffffff91)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i64
+;; CHECK-NEXT: (i64.shr_s
+;; CHECK-NEXT: (i64.const -128)
+;; CHECK-NEXT: (i64.add
+;; CHECK-NEXT: (i64.const -15324)
+;; CHECK-NEXT: (select
+;; CHECK-NEXT: (i64.load16_s offset=4 align=1
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.load offset=4 align=2
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (block $label$89 (result i32)
+;; CHECK-NEXT: (f64.store offset=22 align=1
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.const -72)
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.get $global$_6)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$89
+;; CHECK-NEXT: (br_if $label$89
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (i32.const 23873)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.get $global$_14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i64.const 5)
+;; CHECK-NEXT: (if (result i32)
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (loop $label$74
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$75
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$76
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (f32.const -nan:0x7fff9f)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$77 (result i32)
+;; CHECK-NEXT: (nop)
+;; CHECK-NEXT: (global.set $global$_6
+;; CHECK-NEXT: (f64.const -3402823466385288598117041e14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.get $global$_10)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$78 (result i32)
+;; CHECK-NEXT: (f32.store offset=22 align=1
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.load offset=22
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (loop $label$79 (result i32)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$80 (result i32)
+;; CHECK-NEXT: (call $log-f64
+;; CHECK-NEXT: (loop $label$81
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$82
+;; CHECK-NEXT: (br_if $label$81
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (f32.const 14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$83
+;; CHECK-NEXT: (loop $label$84
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (block $label$85
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (block $label$86
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$87
+;; CHECK-NEXT: (call $log-i64
+;; CHECK-NEXT: (i64.const 12616)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (f32.const 166)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (i32.load8_u offset=4
+;; CHECK-NEXT: (if (result i32)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const -2147483647)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$84
+;; CHECK-NEXT: (i32.const -1048575)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (f32.const 4294967296)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$88
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (f32.const 64541)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (f32.convert_i32_u
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$27
+;; CHECK-NEXT: (global.get $global$_2)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (i32.load8_s offset=4
+;; CHECK-NEXT: (i32.const -91)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store16 offset=22
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.gt_u
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (i32.load offset=2
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (if (result i32)
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (f32.const -nan:0x7fffd5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.get $global$_11)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$29 (result f32)
+;; CHECK-NEXT: (call $log-f32
+;; CHECK-NEXT: (call $func
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (f32.const 13)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$30
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (i32.trunc_f64_s
+;; CHECK-NEXT: (f64.reinterpret_i64
+;; CHECK-NEXT: (i64.const -2049)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br $label$12)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_invoker
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $func
+;; CHECK-NEXT: (i32.const 2)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_6
+;; CHECK-NEXT: (local $0 f64)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$0
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (i32.const 4)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (nop)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_6_invoker
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (call $func_6)
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_8 (result i32)
+;; CHECK-NEXT: (local $0 i64)
+;; CHECK-NEXT: (local $1 f32)
+;; CHECK-NEXT: (local $2 i32)
+;; CHECK-NEXT: (local $3 i64)
+;; CHECK-NEXT: (local $4 f32)
+;; CHECK-NEXT: (local $5 i64)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$0 (result i32)
+;; CHECK-NEXT: (local.set $3
+;; CHECK-NEXT: (loop $label$1 (result i64)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block (result i64)
+;; CHECK-NEXT: (block $label$2
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$1
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (i32.reinterpret_f32
+;; CHECK-NEXT: (f32.const -nan:0x7fc223)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i64.trunc_f32_u
+;; CHECK-NEXT: (global.get $global$_4)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.get $global$_14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_8_invoker
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $func_8)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_10 (result i64)
+;; CHECK-NEXT: (local $0 f64)
+;; CHECK-NEXT: (local $1 f64)
+;; CHECK-NEXT: (local $2 f64)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$0 (result i64)
+;; CHECK-NEXT: (nop)
+;; CHECK-NEXT: (nop)
+;; CHECK-NEXT: (i64.load32_s offset=22
+;; CHECK-NEXT: (global.get $global$_7)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_10_invoker
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $func_10)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $func_10)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (call $hashMemory)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $func_10)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $func_10)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_12 (result i64)
+;; CHECK-NEXT: (local $0 i64)
+;; CHECK-NEXT: (local $1 f64)
+;; CHECK-NEXT: (local $2 i64)
+;; CHECK-NEXT: (local $3 f32)
+;; CHECK-NEXT: (local $4 i64)
+;; CHECK-NEXT: (local $5 i64)
+;; CHECK-NEXT: (local $6 i64)
+;; CHECK-NEXT: (local $7 i64)
+;; CHECK-NEXT: (local $8 i32)
+;; CHECK-NEXT: (local $9 i32)
+;; CHECK-NEXT: (local $10 f32)
+;; CHECK-NEXT: (local $11 i64)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$1
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (i32.load16_s offset=22
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (local.get $9)
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (i64.const 3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $func_13 (param $0 i32) (param $1 f32) (param $2 f64) (param $3 f32) (result i32)
+;; CHECK-NEXT: (local $4 i32)
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$0 (result i32)
+;; CHECK-NEXT: (loop $label$1
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (block $label$2
+;; CHECK-NEXT: (global.set $global$_13
+;; CHECK-NEXT: (f64.load offset=3
+;; CHECK-NEXT: (br_if $label$0
+;; CHECK-NEXT: (i32.load offset=22 align=1
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=3
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.load offset=22 align=1
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.trunc_f32_s
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $2
+;; CHECK-NEXT: (f64.nearest
+;; CHECK-NEXT: (f64.const -3402823466385288598117041e14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$1
+;; CHECK-NEXT: (i32.le_u
+;; CHECK-NEXT: (select
+;; CHECK-NEXT: (block $label$32
+;; CHECK-NEXT: (loop $label$33
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (call $log-i32
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br_if $label$33
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (global.get $global$_11)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $global$_13
+;; CHECK-NEXT: (f64.nearest
+;; CHECK-NEXT: (f64.const -3402823466385288598117041e14)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (i32.const 2147483646)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load offset=4
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (i32.wrap_i64
+;; CHECK-NEXT: (i64.load32_s offset=4 align=2
+;; CHECK-NEXT: (i32.and
+;; CHECK-NEXT: (call $func_8)
+;; CHECK-NEXT: (i32.const 15)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (loop $label$14
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.eqz
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.const 100)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (unreachable)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $hangLimit
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $hangLimit)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $label$15
+;; CHECK-NEXT: (local.set $1
+;; CHECK-NEXT: (local.get $1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $4)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $4)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $2
+;; CHECK-NEXT: (f64.const -nan:0xfffffffffffb2)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return
+;; CHECK-NEXT: (i32.const -1217019)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (func $hashMemory (result i32)
+;; CHECK-NEXT: (local $0 i32)
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.const 5381)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=1
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=2
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=3
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=4
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=5
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=6
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=7
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=8
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=9
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=10
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=11
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=12
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=13
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=14
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (i32.xor
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (i32.shl
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (i32.const 5)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.load8_u offset=15
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 4234964801256893051
+;; CHECK-NEXT: Generated FinitePowersetLattice<LocalSet*> elements:
+;; CHECK-NEXT: 1111000011,
+;; CHECK-NEXT: 0110011101,
+;; CHECK-NEXT: 0010001110
+;; CHECK-NEXT: for func to test ReachingDefinitionsTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 4577570485573586799
+;; CHECK-NEXT: Generated FiniteIntPowersetLattice elements:
+;; CHECK-NEXT: ,
+;; CHECK-NEXT: ,
+;; CHECK-NEXT:
+;; CHECK-NEXT: for func_invoker to test LivenessTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 8191301589003135276
+;; CHECK-NEXT: Generated FinitePowersetLattice<LocalSet*> elements:
+;; CHECK-NEXT: 0,
+;; CHECK-NEXT: 1,
+;; CHECK-NEXT: 1
+;; CHECK-NEXT: for func_6 to test ReachingDefinitionsTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 8068299453651594774
+;; CHECK-NEXT: Generated FiniteIntPowersetLattice elements:
+;; CHECK-NEXT: ,
+;; CHECK-NEXT: ,
+;; CHECK-NEXT:
+;; CHECK-NEXT: for func_6_invoker to test LivenessTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 5852178751023674337
+;; CHECK-NEXT: Generated FiniteIntPowersetLattice elements:
+;; CHECK-NEXT: 111111,
+;; CHECK-NEXT: 000100,
+;; CHECK-NEXT: 010000
+;; CHECK-NEXT: for func_8 to test LivenessTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 13832862600605363478
+;; CHECK-NEXT: Generated FinitePowersetLattice<LocalSet*> elements:
+;; CHECK-NEXT: ,
+;; CHECK-NEXT: ,
+;; CHECK-NEXT:
+;; CHECK-NEXT: for func_8_invoker to test ReachingDefinitionsTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 7970088265179676333
+;; CHECK-NEXT: Generated FiniteIntPowersetLattice elements:
+;; CHECK-NEXT: 011,
+;; CHECK-NEXT: 011,
+;; CHECK-NEXT: 000
+;; CHECK-NEXT: for func_10 to test LivenessTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 14582942952639200251
+;; CHECK-NEXT: Generated FinitePowersetLattice<LocalSet*> elements:
+;; CHECK-NEXT: ,
+;; CHECK-NEXT: ,
+;; CHECK-NEXT:
+;; CHECK-NEXT: for func_10_invoker to test ReachingDefinitionsTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 16331556144677973625
+;; CHECK-NEXT: Generated FinitePowersetLattice<LocalSet*> elements:
+;; CHECK-NEXT: 001000110000,
+;; CHECK-NEXT: 011010100000,
+;; CHECK-NEXT: 001011001101
+;; CHECK-NEXT: for func_12 to test ReachingDefinitionsTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 6783688792201211800
+;; CHECK-NEXT: Generated FiniteIntPowersetLattice elements:
+;; CHECK-NEXT: 00001,
+;; CHECK-NEXT: 00011,
+;; CHECK-NEXT: 10000
+;; CHECK-NEXT: for func_13 to test LivenessTransferFunction.
+;; CHECK-NEXT:
+;; CHECK-NEXT: Using lattice element seed 15457352654905208821
+;; CHECK-NEXT: Generated FinitePowersetLattice<LocalSet*> elements:
+;; CHECK-NEXT: 111000100001010101,
+;; CHECK-NEXT: 001110111010000110,
+;; CHECK-NEXT: 111010111111110110
+;; CHECK-NEXT: for hashMemory to test ReachingDefinitionsTransferFunction.
+;; CHECK-NEXT: