diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-01-21 19:34:57 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-21 16:34:57 -0800 |
commit | 7a83bc744fff43349e6612263f11bce1fe8dbf34 (patch) | |
tree | 87bd8d4e3c1c3bea6e883f08848539e47f3f62f0 | |
parent | 3f4d3b3eff5d8112a9da3674a5f5eea696ca3c7d (diff) | |
download | binaryen-7a83bc744fff43349e6612263f11bce1fe8dbf34.tar.gz binaryen-7a83bc744fff43349e6612263f11bce1fe8dbf34.tar.bz2 binaryen-7a83bc744fff43349e6612263f11bce1fe8dbf34.zip |
Introduce a script for updating lit tests (#3503)
And demonstrate its capabilities by porting all tests of the
optimize-instructions pass to use lit and FileCheck.
16 files changed, 12820 insertions, 12655 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py index 1135adeb2..76728f8a7 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -138,6 +138,19 @@ def update_spec_tests(): o.write(stdout) +def update_lit_tests(): + print('\n[ updating lit testcases... ]\n') + script = os.path.join(shared.options.binaryen_root, + 'scripts', + 'update_lit_checks.py') + lit_dir = shared.get_test_dir('lit') + subprocess.check_output([sys.executable, + script, + '--binaryen-bin=' + shared.options.binaryen_bin, + os.path.join(lit_dir, '**', '*.wast'), + os.path.join(lit_dir, '**', '*.wat')]) + + TEST_SUITES = OrderedDict([ ('wasm-opt', wasm_opt.update_wasm_opt_tests), ('wasm-dis', update_wasm_dis_tests), @@ -149,6 +162,7 @@ TEST_SUITES = OrderedDict([ ('lld', lld.update_lld_tests), ('wasm2js', wasm2js.update_wasm2js_tests), ('binaryenjs', binaryenjs.update_binaryen_js_tests), + ('lit', update_lit_tests), ]) diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 7e6753700..d80829a10 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -151,7 +151,7 @@ def randomize_fuzz_settings(): IMPORTANT_INITIAL_CONTENTS = [ - os.path.join('passes', 'optimize-instructions_all-features.wast'), + os.path.join('lit', 'passes', 'optimize-instructions.wast'), os.path.join('passes', 'optimize-instructions_fuzz-exec.wast'), ] IMPORTANT_INITIAL_CONTENTS = [os.path.join(shared.get_test_dir('.'), t) for t in IMPORTANT_INITIAL_CONTENTS] @@ -833,7 +833,8 @@ spec_tests = shared.get_tests(shared.get_test_dir('spec'), test_suffixes) wasm2js_tests = shared.get_tests(shared.get_test_dir('wasm2js'), test_suffixes) lld_tests = shared.get_tests(shared.get_test_dir('lld'), test_suffixes) unit_tests = shared.get_tests(shared.get_test_dir(os.path.join('unit', 'input')), test_suffixes) -all_tests = core_tests + passes_tests + spec_tests + wasm2js_tests + lld_tests + unit_tests +lit_tests = shared.get_tests(shared.get_test_dir('lit'), test_suffixes, recursive=True) +all_tests = core_tests + passes_tests + spec_tests + wasm2js_tests + lld_tests + unit_tests + lit_tests # Do one test, given an input file for -ttf and some optimizations to run diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 174967b42..f782bb849 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -366,15 +366,16 @@ def get_test_dir(name): return os.path.join(options.binaryen_test, name) -def get_tests(test_dir, extensions=[]): +def get_tests(test_dir, extensions=[], recursive=False): """Returns the list of test files in a given directory. 'extensions' is a list of file extensions. If 'extensions' is empty, returns all files. """ tests = [] + star = '**/*' if recursive else '*' if not extensions: - tests += glob.glob(os.path.join(test_dir, '*')) + tests += glob.glob(os.path.join(test_dir, star), recursive=True) for ext in extensions: - tests += glob.glob(os.path.join(test_dir, '*' + ext)) + tests += glob.glob(os.path.join(test_dir, star + ext), recursive=True) if options.test_name_filter: tests = fnmatch.filter(tests, options.test_name_filter) return sorted(tests) diff --git a/scripts/update_lit_checks.py b/scripts/update_lit_checks.py new file mode 100755 index 000000000..d8446288a --- /dev/null +++ b/scripts/update_lit_checks.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python3 +# Copyright 2021 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. + +"""A test case update script. + +This script is a utility to update wasm-opt based lit tests with new FileCheck +patterns. It is based on LLVM's update_llc_test_checks.py script. +""" + +import argparse +import glob +import os +import re +import subprocess +import sys +import tempfile + + +script_name = os.path.basename(__file__) +NOTICE = (f';; NOTE: Assertions have been generated by {script_name} and ' + + 'should not be edited.') +RUN_LINE_RE = re.compile(r'^\s*;;\s*RUN:\s*(.*)$') +CHECK_PREFIX_RE = re.compile(r'.*--check-prefix[= ](\S+).*') +FUNC_RE = re.compile(r'(^\s*)\(func \$(\S*).*$', re.MULTILINE) + + +def warn(msg): + print(f'WARNING: {msg}', file=sys.stderr) + + +def itertests(args): + """ + Yield (filename, lines) for each test specified in the command line args + """ + for pattern in args.tests: + tests = glob.glob(pattern, recursive=True) + if not tests: + warn(f'No tests matched {pattern}. Ignoring it.') + continue + for test in tests: + with open(test) as f: + lines = [line.rstrip() for line in f] + first_line = lines[0] if lines else '' + if script_name not in first_line and not args.force: + warn(f'Skipping test {test} which was not generated by ' + f'{script_name}. Use -f to override.') + continue + yield test, lines + + +def find_run_lines(test, lines): + line_matches = [RUN_LINE_RE.match(l) for l in lines] + matches = [match.group(1) for match in line_matches if match] + if not matches: + warn(f'No RUN lines found in {test}. Ignoring.') + return [] + run_lines = [matches[0]] + for line in matches[1:]: + if run_lines[-1].endswith('\\'): + run_lines[-1] = run_lines[-1].rstrip('\\') + ' ' + line + else: + run_lines.append(line) + return run_lines + + +def run_command(args, test, tmp, command): + env = dict(os.environ) + env['PATH'] = args.binaryen_bin + os.pathsep + env['PATH'] + command = command.replace('%s', test) + command = command.replace('%t', tmp) + return subprocess.check_output(command, shell=True, env=env).decode('utf-8') + + +def find_funcs(module): + """Return a dict mapping each function name to lines in the function""" + result = {} + for match in FUNC_RE.finditer(module): + name = match.group(2) + depth = 1 + for end in range(match.end(), len(module)): + if depth == 0: + break + elif module[end] == '(': + depth += 1 + elif module[end] == ')': + depth -= 1 + result[name] = module[match.start():end].split('\n') + return result + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '--binaryen-bin', dest='binaryen_bin', default='bin', + help=('Specifies the path to the Binaryen executables in the CMake build' + ' directory. Default: bin/ of current directory (i.e. assume an' + ' in-tree build).')) + parser.add_argument( + '-f', '--force', action='store_true', + help=('Generate FileCheck patterns even for test files whose existing ' + 'patterns were not generated by this script.')) + parser.add_argument( + '--dry-run', action='store_true', + help=('Print the updated test file contents instead of changing the ' + 'test files')) + parser.add_argument('tests', nargs='+', help='The test files to update') + args = parser.parse_args() + args.binaryen_bin = os.path.abspath(args.binaryen_bin) + + tmp = tempfile.mktemp() + + for test, lines in itertests(args): + run_list = [] + for line in find_run_lines(test, lines): + commands = [cmd.strip() for cmd in line.rsplit('|', 1)] + filecheck_cmd = '' + if len(commands) > 1 and commands[1].startswith('filecheck '): + filecheck_cmd = commands[1] + commands = commands[:1] + + check_prefix = '' + if filecheck_cmd.startswith('filecheck '): + prefix_match = CHECK_PREFIX_RE.match(filecheck_cmd) + if prefix_match: + check_prefix = prefix_match.group(1) + else: + check_prefix = 'CHECK' + + run_list.append((check_prefix, commands[0])) + + # Map check prefixes and function names to the corresponding output + func_dict = {} + for prefix, command, in run_list: + output = run_command(args, test, tmp, command) + if prefix: + func_dict[prefix] = find_funcs(output) + + check_line_re = re.compile(r'^\s*;;\s*(' + '|'.join(func_dict.keys()) + + r')(?:-NEXT|-LABEL|-NOT)?: .*$') + output_lines = [NOTICE] + if lines and script_name in lines[0]: + lines = lines[1:] + for line in lines: + if check_line_re.match(line): + continue + func_match = FUNC_RE.match(line) + if func_match: + indent, name = func_match.groups() + for prefix, funcs in func_dict.items(): + body = funcs.get(name, []) + if not body: + continue + output_lines.append(f'{indent};; {prefix}: {body[0]}') + for l in body[1:]: + output_lines.append(f'{indent};; {prefix}-NEXT:{l}') + output_lines.append(line) + + if args.dry_run: + print('\n'.join(output_lines)) + else: + with open(test, 'w') as f: + for line in output_lines: + f.write(line + '\n') + + +if __name__ == '__main__': + main() diff --git a/test/lit/passes/optimize-instructions-atomics.wast b/test/lit/passes/optimize-instructions-atomics.wast new file mode 100644 index 000000000..83ad545ba --- /dev/null +++ b/test/lit/passes/optimize-instructions-atomics.wast @@ -0,0 +1,33 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions --enable-threads -S -o - | filecheck %s + +(module + (import "env" "memory" (memory $0 (shared 256 256))) + + ;; CHECK: (func $x + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.atomic.load8_u + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $x + (drop + (i32.shr_s + (i32.shl + (i32.atomic.load8_u ;; can't be signed + (i32.const 100) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) +) diff --git a/test/lit/passes/optimize-instructions-bulk-memory.wast b/test/lit/passes/optimize-instructions-bulk-memory.wast new file mode 100644 index 000000000..37d17dba8 --- /dev/null +++ b/test/lit/passes/optimize-instructions-bulk-memory.wast @@ -0,0 +1,160 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions --enable-bulk-memory -S -o - | filecheck %s + +(module + (memory 0) + ;; CHECK: (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $sz) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 align=1 + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (i32.load16_u align=1 + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store align=1 + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (i32.load align=1 + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store align=1 + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (i64.load align=1 + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (local.get $sz) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) + (memory.copy ;; skip + (local.get $dst) + (local.get $dst) + (local.get $sz) + ) + + (memory.copy ;; skip + (local.get $dst) + (local.get $src) + (i32.const 0) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 1) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 2) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 3) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 4) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 5) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 6) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 7) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 8) + ) + + (memory.copy + (local.get $dst) + (local.get $src) + (i32.const 16) + ) + + (memory.copy ;; skip + (local.get $dst) + (local.get $src) + (local.get $sz) + ) + + (memory.copy ;; skip + (i32.const 0) + (i32.const 0) + (i32.load + (i32.const 3) ;; side effect + ) + ) + ) +) diff --git a/test/lit/passes/optimize-instructions-exceptions.wast b/test/lit/passes/optimize-instructions-exceptions.wast new file mode 100644 index 000000000..e2b60e0f1 --- /dev/null +++ b/test/lit/passes/optimize-instructions-exceptions.wast @@ -0,0 +1,40 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions --enable-reference-types \ +;; RUN: --enable-exception-handling -S -o - | filecheck %s + +(module + ;; CHECK: (func $test + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (try (result i32) + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: (i32.const 123) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch_all + ;; CHECK-NEXT: (i32.const 456) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test + (if + (try (result i32) + (do + (i32.eqz + (i32.eqz + (i32.const 123) + ) + ) + ) + (catch_all + (i32.eqz + (i32.eqz + (i32.const 456) + ) + ) + ) + ) + (nop) + ) + ) +) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast new file mode 100644 index 000000000..31ecd0f63 --- /dev/null +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -0,0 +1,33 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions --enable-reference-types --enable-gc -S -o - \ +;; RUN: | filecheck %s + +(module + ;; These functions test if an `if` with subtyped arms is correctly folded + ;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold) + ;; CHECK: (func $if-arms-subtype-fold (result anyref) + ;; CHECK-NEXT: (ref.null extern) + ;; CHECK-NEXT: ) + (func $if-arms-subtype-fold (result anyref) + (if (result anyref) + (i32.const 0) + (ref.null extern) + (ref.null extern) + ) + ) + ;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold) + ;; CHECK: (func $if-arms-subtype-nofold (result anyref) + ;; CHECK-NEXT: (if (result anyref) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (ref.null extern) + ;; CHECK-NEXT: (ref.null func) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-arms-subtype-nofold (result anyref) + (if (result anyref) + (i32.const 0) + (ref.null extern) + (ref.null func) + ) + ) +) diff --git a/test/lit/passes/optimize-instructions-ignore-traps.wast b/test/lit/passes/optimize-instructions-ignore-traps.wast new file mode 100644 index 000000000..5c4784919 --- /dev/null +++ b/test/lit/passes/optimize-instructions-ignore-traps.wast @@ -0,0 +1,760 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --all-features --optimize-level=2 --ignore-implicit-traps -S -o - \ +;; RUN: | filecheck %s + +(module + (type $0 (func (param i32 i32) (result i32))) + (memory $0 0) + ;; CHECK: (func $conditionals (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in6 + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in6 + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 27000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $conditionals (type $0) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local.set $0 + (i32.const 0) + ) + (loop $while-in + (local.set $3 + (i32.const 0) + ) + (loop $while-in6 + (local.set $6 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (local.set $0 + (if (result i32) + (i32.or ;; this or is very expensive. we should compute one side, then see if we even need the other + (i32.eqz + (i32.rem_s + (i32.add + (i32.mul + (local.tee $7 ;; side effect, so we can't do this one + (i32.add + (local.get $0) + (i32.const 2) + ) + ) + (local.get $0) + ) + (i32.const 17) + ) + (i32.const 5) + ) + ) + (i32.eqz + (i32.rem_u + (i32.add + (i32.mul + (local.get $0) + (local.get $0) + ) + (i32.const 11) + ) + (i32.const 3) + ) + ) + ) + (local.get $7) + (local.get $6) + ) + ) + (br_if $while-in6 + (i32.lt_s + (local.tee $3 + (i32.add + (local.get $3) + (i32.const 1) + ) + ) + (local.get $4) + ) + ) + ) + (br_if $while-in + (i32.ne + (local.tee $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (i32.const 27000) + ) + ) + ) + (return + (local.get $5) + ) + ) + ;; CHECK: (func $side-effect (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in6 + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.tee $7 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in6 + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 27000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $side-effect (type $0) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local.set $0 + (i32.const 0) + ) + (loop $while-in + (local.set $3 + (i32.const 0) + ) + (loop $while-in6 + (local.set $6 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (local.set $0 + (if (result i32) + (i32.or ;; this or is very expensive, but has a side effect on both sides + (i32.eqz + (i32.rem_s + (i32.add + (i32.mul + (local.tee $7 + (i32.add + (local.get $0) + (i32.const 0) + ) + ) + (local.get $0) + ) + (i32.const 17) + ) + (i32.const 5) + ) + ) + (i32.eqz + (i32.rem_u + (i32.add + (i32.mul + (local.get $0) + (local.get $0) + ) + (unreachable) + ) + (i32.const 3) + ) + ) + ) + (local.get $7) + (local.get $6) + ) + ) + (br_if $while-in6 + (i32.lt_s + (local.tee $3 + (i32.add + (local.get $3) + (i32.const 1) + ) + ) + (local.get $4) + ) + ) + ) + (br_if $while-in + (i32.ne + (local.tee $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (i32.const 27000) + ) + ) + ) + (return + (local.get $5) + ) + ) + ;; CHECK: (func $flip (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $while-in6 + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in6 + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.tee $3 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $while-in + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 27000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $flip (type $0) (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local.set $0 + (i32.const 0) + ) + (loop $while-in + (local.set $3 + (i32.const 0) + ) + (loop $while-in6 + (local.set $6 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (local.set $0 + (if (result i32) + (i32.or ;; this or is very expensive, and the first side has no side effect + (i32.eqz + (i32.rem_s + (i32.add + (i32.mul + (i32.eqz + (i32.add + (local.get $0) + (i32.const 0) + ) + ) + (local.get $0) + ) + (i32.const 17) + ) + (i32.const 5) + ) + ) + (i32.eqz + (i32.rem_u + (i32.add + (i32.mul + (local.get $0) + (local.get $0) + ) + (i32.const 100) + ) + (i32.const 3) + ) + ) + ) + (local.get $7) + (local.get $6) + ) + ) + (br_if $while-in6 + (i32.lt_s + (local.tee $3 + (i32.add + (local.get $3) + (i32.const 1) + ) + ) + (local.get $4) + ) + ) + ) + (br_if $while-in + (i32.ne + (local.tee $1 + (i32.add + (local.get $1) + (i32.const 1) + ) + ) + (i32.const 27000) + ) + ) + ) + (return + (local.get $5) + ) + ) + ;; CHECK: (func $invalidate-conditionalizeExpensiveOnBitwise (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $invalidate-conditionalizeExpensiveOnBitwise (param $0 i32) (param $1 i32) (result i32) + (if + (i32.eqz + (i32.and + (i32.lt_s + (i32.and + (i32.shr_s + (i32.shl + (i32.add + (local.get $1) ;; conflict with tee + (i32.const -1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 255) + ) + (i32.const 3) + ) + (i32.ne + (local.tee $1 + (i32.const 0) + ) + (i32.const 0) + ) + ) + ) + (return (local.get $0)) + ) + (return (local.get $1)) + ) + ;; CHECK: (func $invalidate-conditionalizeExpensiveOnBitwise-ok (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $invalidate-conditionalizeExpensiveOnBitwise-ok (param $0 i32) (param $1 i32) (result i32) + (if + (i32.eqz + (i32.and + (i32.lt_s + (i32.and + (i32.shr_s + (i32.shl + (i32.add + (local.get $0) ;; no conflict + (i32.const -1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 255) + ) + (i32.const 3) + ) + (i32.ne + (local.tee $1 + (i32.const 0) + ) + (i32.const 0) + ) + ) + ) + (return (local.get $0)) + ) + (return (local.get $1)) + ) + + ;; CHECK: (func $conditionalize-if-type-change (result f64) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (loop $label$1 (result f32) + ;; CHECK-NEXT: (block $label$2 (result f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $label$3 (result f32) + ;; CHECK-NEXT: (br_if $label$1 + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (f32.gt + ;; CHECK-NEXT: (br_if $label$3 + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$2 + ;; CHECK-NEXT: (f32.const 71) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i64.const 58) + ;; CHECK-NEXT: (i64.const -982757) + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.const -nan:0xfffffffffffff) + ;; CHECK-NEXT: ) + (func $conditionalize-if-type-change (result f64) + (local $0 i32) + (drop + (loop $label$1 (result f32) + (block $label$2 (result f32) + (drop + (block $label$3 (result f32) + (br_if $label$1 + (i32.or ;; this turns into an if, but then the if might not be unreachable + (f32.gt + (br_if $label$3 + (f32.const 1) + (local.get $0) + ) + (br $label$2 + (f32.const 71) + ) + ) + (i64.eqz + (select + (i64.const 58) + (i64.const -982757) + (i64.eqz + (i64.const 0) + ) + ) + ) + ) + ) + ) + ) + (f32.const 1) + ) + ) + ) + (f64.const -nan:0xfffffffffffff) + ) + ;; CHECK: (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $sz) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (memory.copy + ;; CHECK-NEXT: (local.get $dst) + ;; CHECK-NEXT: (local.get $src) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) + (memory.copy ;; nop + (local.get $dst) + (local.get $dst) + (local.get $sz) + ) + + (memory.copy ;; nop + (local.get $dst) + (local.get $src) + (i32.const 0) + ) + ) +) diff --git a/test/lit/passes/optimize-instructions-sign-ext.wast b/test/lit/passes/optimize-instructions-sign-ext.wast new file mode 100644 index 000000000..142c2d2a4 --- /dev/null +++ b/test/lit/passes/optimize-instructions-sign-ext.wast @@ -0,0 +1,21 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions --enable-sign-ext -S -o - | filecheck %s + +(module + ;; CHECK: (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.extend8_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.extend16_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) + (drop (i32.extend8_s (i32.extend8_s (local.get $x)))) + (drop (i32.extend16_s (i32.extend16_s (local.get $x)))) + ) +) diff --git a/test/lit/passes/optimize-instructions-typed-function-references.wast b/test/lit/passes/optimize-instructions-typed-function-references.wast new file mode 100644 index 000000000..6a80d3d30 --- /dev/null +++ b/test/lit/passes/optimize-instructions-typed-function-references.wast @@ -0,0 +1,16 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions --enable-reference-types \ +;; RUN: --enable-typed-function-references -S -o - | filecheck %s + +(module + (type $i32-i32 (func (param i32) (result i32))) + ;; this function has a reference parameter. we analyze parameters, and should + ;; not be confused by a type that has no bit size, in particular. this test + ;; just verifies that we do not crash on that. + ;; CHECK: (func $call_from-param (param $f (ref null $i32_=>_i32)) (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $call_from-param (param $f (ref null $i32-i32)) (result i32) + (unreachable) + ) +) diff --git a/test/lit/passes/optimize-instructions.wast b/test/lit/passes/optimize-instructions.wast new file mode 100644 index 000000000..04d3f59fd --- /dev/null +++ b/test/lit/passes/optimize-instructions.wast @@ -0,0 +1,11557 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --optimize-instructions -S -o - | filecheck %s + +(module + (memory 0) + (type $0 (func (param i32 i64))) + ;; CHECK: (func $f (param $i1 i32) (param $i2 i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: (i32.const -10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: (i32.const -133169153) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (local.get $i2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f32.gt + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f32.ge + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f32.lt + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f32.le + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f64.gt + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f64.lt + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (f64.le + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.ne + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.eq + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: (f32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.eq + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (i64.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 123) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $i1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $i1 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $i1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $f (type $0) (param $i1 i32) (param $i2 i64) + (drop + (i32.and + (i32.and + (local.get $i1) + (i32.const 5) + ) + (i32.const 3) + ) + ) + (drop + (i32.or + (i32.or + (local.get $i1) + (i32.const 1) + ) + (i32.const 2) + ) + ) + (drop + (i32.xor + (i32.xor + (local.get $i1) + (i32.const -2) + ) + (i32.const -5) + ) + ) + (drop + (i32.mul + (i32.mul + (local.get $i1) + (i32.const -2) + ) + (i32.const 5) + ) + ) + ;; overflow also valid + (drop + (i32.mul + (i32.mul + (local.get $i1) + (i32.const 0xfffff) + ) + (i32.const 0x8000001) + ) + ) + (if + (i32.eqz + (local.get $i1) + ) + (drop + (i32.const 10) + ) + ) + (if + (i32.eqz + (local.get $i1) + ) + (drop + (i32.const 11) + ) + (drop + (i32.const 12) + ) + ) + (if + (i64.eqz + (local.get $i2) + ) + (drop + (i32.const 11) + ) + (drop + (i32.const 12) + ) + ) + (drop + (i32.eqz + (i32.gt_s + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.ge_s + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.lt_s + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.le_s + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.gt_u + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.ge_u + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.lt_u + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (i32.le_u + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f32.gt + (f32.const 1) + (f32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f32.ge + (f32.const 1) + (f32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f32.lt + (f32.const 1) + (f32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f32.le + (f32.const 1) + (f32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f64.gt + (f64.const 1) + (f64.const 2) + ) + ) + ) + (drop + (i32.eqz + (f64.ge + (f64.const 1) + (f64.const 2) + ) + ) + ) + (drop + (i32.eqz + (f64.lt + (f64.const 1) + (f64.const 2) + ) + ) + ) + (drop + (i32.eqz + (f64.le + (f64.const 1) + (f64.const 2) + ) + ) + ) + (drop + (i32.eqz + (f32.eq + (f32.const 1) + (f32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f32.ne + (f32.const 1) + (f32.const 2) + ) + ) + ) + (drop + (i32.eqz + (f64.eq + (f64.const 1) + (f64.const 2) + ) + ) + ) + (drop + (i32.eqz + (f64.ne + (f64.const 1) + (f64.const 2) + ) + ) + ) + ;; we handle only 0 in the right position, as we assume a const is there, and don't care about if + ;; both are consts here (precompute does that, so no need) + (drop + (i32.eq + (i32.const 100) + (i32.const 0) + ) + ) + (drop + (i32.eq + (i32.const 0) + (i32.const 100) + ) + ) + (drop + (i32.eq + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (i64.eq + (i64.const 100) + (i64.const 0) + ) + ) + (drop + (i64.eq + (i64.const 0) + (i64.const 100) + ) + ) + (drop + (i64.eq + (i64.const 0) + (i64.const 0) + ) + ) + (if + (i32.eqz + (i32.eqz + (i32.const 123) + ) + ) + (nop) + ) + (drop + (select + (i32.const 101) + (i32.const 102) + (i32.eqz + (local.get $i1) + ) + ) + ) + (drop + (select + (local.tee $i1 + (i32.const 103) + ) ;; these conflict + (local.tee $i1 + (i32.const 104) + ) + (i32.eqz + (local.get $i1) + ) + ) + ) + (drop + (select + (i32.const 0) + (i32.const 1) + (i32.eqz + (i32.eqz + (i32.const 2) + ) + ) + ) + ) + ) + ;; CHECK: (func $load-store + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 254) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load16_u + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load16_u + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load16_s + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 65534) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.load16_u + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const -2) + ;; CHECK-NEXT: (i32.const 254) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const -3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: (i32.const 65534) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store8 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store16 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store32 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: (i32.const 65536) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store8 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i64.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store8 + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store16 + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: (i64.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store16 + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store32 + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: (i64.const 4294967295) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store32 + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.store + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: (i64.const 4294967296) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $load-store + (drop (i32.and (i32.load8_s (i32.const 0)) (i32.const 255))) + (drop (i32.and (i32.load8_u (i32.const 1)) (i32.const 255))) + (drop (i32.and (i32.load8_s (i32.const 2)) (i32.const 254))) + (drop (i32.and (i32.load8_u (i32.const 3)) (i32.const 1))) + (drop (i32.and (i32.load16_s (i32.const 4)) (i32.const 65535))) + (drop (i32.and (i32.load16_u (i32.const 5)) (i32.const 65535))) + (drop (i32.and (i32.load16_s (i32.const 6)) (i32.const 65534))) + (drop (i32.and (i32.load16_u (i32.const 7)) (i32.const 1))) + ;; + (i32.store8 (i32.const 8) (i32.and (i32.const -1) (i32.const 255))) + (i32.store8 (i32.const 9) (i32.and (i32.const -2) (i32.const 254))) + (i32.store16 (i32.const 10) (i32.and (i32.const -3) (i32.const 65535))) + (i32.store16 (i32.const 11) (i32.and (i32.const -4) (i32.const 65534))) + ;; + (i32.store8 (i32.const 11) (i32.wrap_i64 (i64.const 1))) + (i32.store16 (i32.const 11) (i32.wrap_i64 (i64.const 2))) + (i32.store (i32.const 11) (i32.wrap_i64 (i64.const 3))) + ;; + (i32.store8 (i32.const 7) (i32.const -1)) ;; 255 + (i32.store8 (i32.const 8) (i32.const 255)) + (i32.store8 (i32.const 9) (i32.const 256)) ;; 0 + (i32.store16 (i32.const 10) (i32.const 65535)) + (i32.store16 (i32.const 11) (i32.const 65536)) ;; 0 + (i32.store16 (i32.const 13) (i32.const -1)) ;; 65535 + (i32.store (i32.const 14) (i32.const 65536)) + ;; + (i64.store8 (i32.const 8) (i64.const 255)) + (i64.store8 (i32.const 9) (i64.const 256)) ;; 0 + (i64.store16 (i32.const 10) (i64.const 65535)) + (i64.store16 (i32.const 11) (i64.const 65536)) ;; 0 + (i64.store32 (i32.const 12) (i64.const 4294967295)) + (i64.store32 (i32.const 13) (i64.const 4294967296)) ;; 0 + (i64.store (i32.const 14) (i64.const 4294967296)) + ) + ;; CHECK: (func $and-neg1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-neg1 + (drop (i32.and (i32.const 100) (i32.const -1))) + (drop (i32.and (i32.const 100) (i32.const 1))) + ) + ;; CHECK: (func $and-pos1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const 1000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const 1000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_u + ;; CHECK-NEXT: (i32.const 2000) + ;; CHECK-NEXT: (i32.const 3000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-pos1 + (drop (i32.and (i32.eqz (i32.const 1000)) (i32.const 1))) + (drop (i32.and (i32.const 1) (i32.eqz (i32.const 1000)))) + (drop (i32.and (i32.const 100) (i32.const 1))) + (drop (i32.and (i32.lt_s (i32.const 2000) (i32.const 3000)) (i32.const 1))) + ) + ;; CHECK: (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block (result i32) + ;; CHECK-NEXT: (i32.const -5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block3 (result i32) + ;; CHECK-NEXT: (i32.const -6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block4 (result i32) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $loop-in (result i32) + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block6 (result i32) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $loop-in5 (result i32) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block8 (result i32) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $loop-in7 (result i32) + ;; CHECK-NEXT: (call $and-pos1) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block10 (result i32) + ;; CHECK-NEXT: (call $and-pos1) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $loop-in9 (result i32) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (loop $loop-in11 (result i32) + ;; CHECK-NEXT: (call $and-pos1) + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block12 (result i32) + ;; CHECK-NEXT: (call $and-pos1) + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block13 (result i32) + ;; CHECK-NEXT: (call $and-pos1) + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (loop $loop-in14 (result i32) + ;; CHECK-NEXT: (call $and-pos1) + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block15 (result i32) + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (block $block16 (result i32) + ;; CHECK-NEXT: (i32.const 15) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.const 18) + ;; CHECK-NEXT: (i32.const 19) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (i32.const 21) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_u + ;; CHECK-NEXT: (i32.const 22) + ;; CHECK-NEXT: (i32.const 23) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.ne + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.gt + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f64.const -2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.le + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f64.const inf) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f64.const nan:0x8000000000000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.ge + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.ctz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64) + (drop (i32.and (unreachable) (i32.const 1))) ;; ok to reorder + (drop (i32.and (i32.const 1) (unreachable))) + (drop (i32.div_s (unreachable) (i32.const 1))) ;; not ok + (drop (i32.div_s (i32.const 1) (unreachable))) + ;; the various orderings + (drop (i32.and (i32.const 1) (i32.const 2))) + (drop (i32.and (local.get $x) (i32.const 3))) + (drop (i32.and (i32.const 4) (local.get $x))) + (drop (i32.and (local.get $x) (local.get $y))) + (drop (i32.and (local.get $y) (local.get $x))) + (drop (i32.and (local.get $y) (local.tee $x (i32.const -4)))) + (drop (i32.and + (block (result i32) + (i32.const -5) + ) + (local.get $x) + )) + (drop (i32.and + (local.get $x) + (block (result i32) + (i32.const -6) + ) + )) + (drop (i32.and + (block (result i32) + (i32.const 5) + ) + (loop (result i32) + (i32.const 6) + ) + )) + (drop (i32.and + (loop (result i32) + (i32.const 7) + ) + (block (result i32) + (i32.const 8) + ) + )) + (drop (i32.and + (loop (result i32) + (call $and-pos1) + (i32.const 9) + ) + (block (result i32) + (i32.const 10) + ) + )) + (drop (i32.and + (loop (result i32) + (i32.const 11) + ) + (block (result i32) + (call $and-pos1) + (i32.const 12) + ) + )) + (drop (i32.and + (loop (result i32) + (call $and-pos1) + (i32.const 13) + ) + (block (result i32) + (call $and-pos1) + (i32.const 14) + ) + )) + (drop (i32.and + (block (result i32) + (call $and-pos1) + (i32.const 14) + ) + (loop (result i32) + (call $and-pos1) + (i32.const 13) + ) + )) + (drop (i32.and + (block (result i32) + (i32.const 15) + ) + (local.get $x) + )) + (drop (i32.and + (local.get $x) + (block (result i32) + (i32.const 15) + ) + )) + (drop (i32.and + (i32.gt_s + (i32.const 16) + (i32.const 17) + ) + (i32.gt_u + (i32.const 18) + (i32.const 19) + ) + )) + (drop (i32.and + (i32.gt_u + (i32.const 20) + (i32.const 21) + ) + (i32.gt_s + (i32.const 22) + (i32.const 23) + ) + )) + (drop (i32.gt_s + (i32.const 1) + (local.get $x) + )) + (drop (i32.gt_u + (i32.const 0) + (local.get $x) + )) + (drop (i32.ne + (i32.const -1) + (local.get $x) + )) + (drop (f64.ne + (f64.const -1) + (local.get $fx) + )) + (drop (f64.lt + (f64.const -2) + (local.get $fx) + )) + (drop (f64.ge + (f64.const inf) + (local.get $fx) + )) + (drop (f64.le + (f64.const nan) + (local.get $fx) + )) + ;; skip + (drop (f64.ge + (f64.const 1) + (f64.const 2) + )) + (drop (i32.add (i32.ctz (local.get $x)) (i32.ctz (local.get $y)))) + (drop (i32.add (i32.ctz (local.get $y)) (i32.ctz (local.get $x)))) + (drop (i32.add (i32.ctz (local.get $x)) (i32.eqz (local.get $y)))) + (drop (i32.add (i32.eqz (local.get $x)) (i32.ctz (local.get $y)))) + ) + ;; CHECK: (func $ne0 (result i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $ne0 (result i32) + (if (i32.ne (call $ne0) (i32.const 0)) + (nop) + ) + (if (i32.ne (i32.const 0) (call $ne0)) + (nop) + ) + ;; through an or + (if + (i32.or + (i32.ne (i32.const 0) (call $ne0)) + (i32.ne (i32.const 0) (call $ne0)) + ) + (nop) + ) + ;; but not an and + (if + (i32.and + (i32.ne (i32.const 0) (call $ne0)) + (i32.ne (i32.const 0) (call $ne0)) + ) + (nop) + ) + (i32.const 1) + ) + ;; CHECK: (func $recurse-bool + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (call $ne1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (block $block (result i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $recurse-bool + (if + (if (result i32) + (i32.const 1) + (i32.ne (call $ne0) (i32.const 0)) + (i32.ne (call $ne1) (i32.const 0)) + ) + (nop) + ) + (if + (block (result i32) + (nop) + (i32.ne (call $ne0) (i32.const 0)) + ) + (nop) + ) + ) + ;; CHECK: (func $ne1 (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $ne1 (result i32) + (unreachable) + ) + ;; CHECK: (func $load-off-2 (param $0 i32) (result i32) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 13) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=2 + ;; CHECK-NEXT: (i32.const -2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store offset=2 + ;; CHECK-NEXT: (i32.const -25) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load offset=2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.load offset=2 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $load-off-2 "load-off-2" (param $0 i32) (result i32) + (i32.store offset=2 + (i32.add + (i32.const 1) + (i32.const 3) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (i32.const 3) + (i32.const 1) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (local.get $0) + (i32.const 5) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (i32.const 7) + (local.get $0) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -11) ;; do not fold this! + (local.get $0) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (local.get $0) + (i32.const -13) ;; do not fold this! + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -15) + (i32.const 17) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.add + (i32.const -21) + (i32.const 19) + ) + (local.get $0) + ) + (i32.store offset=2 + (i32.const 23) + (local.get $0) + ) + (i32.store offset=2 + (i32.const -25) + (local.get $0) + ) + (drop + (i32.load offset=2 + (i32.add + (i32.const 2) + (i32.const 4) + ) + ) + ) + (drop + (i32.load offset=2 + (i32.add + (i32.const 4) + (i32.const 2) + ) + ) + ) + (drop + (i32.load offset=2 + (i32.add + (local.get $0) + (i32.const 6) + ) + ) + ) + (drop + (i32.load offset=2 + (i32.const 8) + ) + ) + (i32.load offset=2 + (i32.add + (i32.const 10) + (local.get $0) + ) + ) + ) + ;; CHECK: (func $sign-ext (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 134217727) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 65535) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 23) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: (i32.const 222) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext (param $0 i32) (param $1 i32) + ;; eq of sign-ext to const, can be a zext + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 0) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 16) + ) + (i32.const 16) + ) + (i32.const 0) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 5) ;; weird size, but still valid + ) + (i32.const 5) + ) + (i32.const 0) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 100) ;; non-zero + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 32767) ;; non-zero and bigger than the mask, with sign bit + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const -149) ;; non-zero and bigger than the mask, without sign bit + ) + ) + ;; eq of two sign-ext, can both be a zext + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 16) + ) + (i32.const 16) + ) + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ) + ;; corner cases we should not opt + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 23) ;; different shift, smaller + ) + (i32.const 0) + ) + ) + (drop + (i32.eq + (i32.shr_u ;; unsigned + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 0) + ) + ) + (drop + (i32.lt_s ;; non-eq + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 0) + ) + ) + (drop + (if (result i32) + (i32.shr_s + (i32.shl + (unreachable) ;; ignore an unreachable value + (i32.const 16) + ) + (i32.const 16) + ) + (i32.const 111) + (i32.const 222) + ) + ) + ) + ;; CHECK: (func $sign-ext-input (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (i32.const 129) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: (i32.const 126) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: (i32.const 126) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (i32.const 26) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (i32.const 27) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.le + ;; CHECK-NEXT: (f32.const -1) + ;; CHECK-NEXT: (f32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 26) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 27) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.clz + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.clz + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.clz + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 26) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.extend_i32_s + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.extend_i32_s + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext-input (param $0 i32) (param $1 i32) + (drop + (i32.shr_s + (i32.shl + (i32.const 100) ;; small! + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.const 127) ;; just small enough + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.const 128) ;; just too big + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.get $0) ;; who knows... + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (unreachable) ;; ignore + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.div_s ;; this could be optimizable in theory, but currently we don't look into adds etc. + (i32.const 1) + (i32.const 2) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.and ;; takes the min, here it is ok + (i32.const 127) + (i32.const 128) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.and ;; takes the min, here it is not + (i32.const 128) + (i32.const 129) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.xor ;; takes the max, here it is ok + (i32.const 127) + (i32.const 126) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.xor ;; takes the max, here it is not + (i32.const 127) + (i32.const 128) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.or ;; takes the max, here it is ok + (i32.const 127) + (i32.const 126) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.or ;; takes the max, here it is not + (i32.const 127) + (i32.const 128) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl ;; adds, here it is too much + (i32.const 32) + (i32.const 2) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl ;; adds, here it is ok + (i32.const 32) + (i32.const 1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl ;; adds, here it is too much and "overflows" + (i32.const 32) + (i32.const 35) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u ;; subtracts, here it is still too much + (i32.const 256) + (i32.const 1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u ;; subtracts, here it is ok + (i32.const 256) + (i32.const 2) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u ;; subtracts, here it "overflows" + (i32.const 128) + (i32.const 35) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_s ;; subtracts, here it is still too much + (i32.const 256) + (i32.const 1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_s ;; subtracts, here it is ok + (i32.const 256) + (i32.const 2) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_s ;; subtracts, here it "overflows" + (i32.const 128) + (i32.const 35) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_s ;; subtracts, here there is a sign bit, so it stays 32 bits no matter how much we shift + (i32.const -1) + (i32.const 32) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_s ;; subtracts, here we mask out that sign bit + (i32.and + (i32.const -1) + (i32.const 2147483647) + ) + (i32.const 31) ;; adjusted after we fixed shift computation to just look at lower 5 bits + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.ne ;; 1 bit + (i32.const -1) + (i32.const -1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (f32.le + (f32.const -1) + (f32.const -1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.clz ;; assumed 5 bits + (i32.const 0) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl + (i32.clz ;; assumed 5 bits + (i32.const 0) + ) + (i32.const 2) ;; + 2, so 7 + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl + (i32.clz ;; assumed 5 bits + (i32.const 0) + ) + (i32.const 3) ;; + 3, so 8, too much + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.wrap_i64 ;; preserves 6 + (i64.clz ;; assumed 6 bits + (i64.const 0) + ) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl + (i32.wrap_i64 ;; preserves 6 + (i64.clz ;; assumed 6 bits + (i64.const 0) + ) + ) + (i32.const 1) ;; + 1, so 7 + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl + (i32.wrap_i64 ;; preserves 6 + (i64.clz ;; assumed 6 bits + (i64.const 0) + ) + ) + (i32.const 2) ;; + 2, so 8, too much + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.eqz ;; 1 bit + (i32.const -1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u + (i32.wrap_i64 ;; down to 32 + (i64.const -1) ;; 64 + ) + (i32.const 24) ;; 32 - 24 = 8 + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u + (i32.wrap_i64 ;; down to 32 + (i64.const -1) ;; 64 + ) + (i32.const 25) ;; 32 - 25 = 7, ok + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u + (i32.wrap_i64 ;; stay 32 + (i64.extend_i32_s + (i32.const -1) + ) + ) + (i32.const 24) ;; 32 - 24 = 8 + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u + (i32.wrap_i64 ;; stay 32 + (i64.extend_i32_s + (i32.const -1) + ) + ) + (i32.const 25) ;; 32 - 25 = 7, ok + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop ;; fuzz testcase + (i32.shr_s + (i32.shl + (i32.xor ;; should be 32 bits + (i32.le_u ;; 1 bit + (local.get $0) + (i32.const 2) + ) + (local.get $0) ;; unknown, so 32 bits + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ;; CHECK: (func $linear-sums (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 12) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 18) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 26) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 22) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 66) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 44) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 14) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 34) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $linear-sums (param $0 i32) (param $1 i32) + (drop + (i32.add + (i32.add + (local.get $1) + (i32.const 16) + ) + (i32.shl + (i32.add + (local.get $0) + (i32.const -1) ;; -16, so cancels out! + ) + (i32.const 4) + ) + ) + ) + (drop + (i32.add + (i32.add + (local.get $1) + (i32.const 20) + ) + (i32.shl + (i32.add + (local.get $0) + (i32.const -1) ;; -8, so sum is +12 + ) + (i32.const 3) + ) + ) + ) + (drop + (i32.add ;; simple sum + (i32.const 1) + (i32.const 3) + ) + ) + (drop + (i32.add ;; nested sum + (i32.add + (i32.const 1) + (i32.const 3) + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.add + (i32.const 1) + (i32.const 3) + ) + (i32.sub ;; internal sub + (i32.const 5) + (i32.const 3) + ) + ) + ) + (drop + (i32.sub ;; external sub + (i32.add + (i32.const 1) + (i32.const 3) + ) + (i32.add + (i32.const 5) + (i32.const 3) + ) + ) + ) + (drop + (i32.sub ;; external sub + (i32.add + (i32.const 1) + (i32.const 3) + ) + (i32.sub ;; and also internal sub + (i32.const 5) + (i32.const 3) + ) + ) + ) + (drop + (i32.add + (i32.add + (i32.const 1) + (i32.const 3) + ) + (i32.sub ;; negating sub + (i32.const 0) + (i32.const 3) + ) + ) + ) + (drop + (i32.add + (i32.sub + (i32.const 0) + (i32.sub ;; two negating subs + (i32.const 0) + (i32.add + (i32.const 3) + (i32.const 20) + ) + ) + ) + (i32.add + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.add + (i32.add + (i32.const 0) + (i32.sub ;; one negating sub + (i32.const 0) + (i32.add + (i32.const 3) + (i32.const 20) + ) + ) + ) + (i32.add + (i32.const 1) + (i32.const 2) + ) + ) + ) + (drop + (i32.add + (i32.shl ;; shifted value + (i32.const 1) + (i32.const 3) + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.shl ;; shifted value + (i32.const 1) + (local.get $0) ;; but not by const + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.shl ;; shifted nested value + (i32.sub + (local.get $1) + (i32.const 10) + ) + (i32.const 3) + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.mul ;; multiplied + (i32.const 10) + (i32.const 3) + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.mul ;; multiplied by nonconstant - can't recurse + (i32.const 10) + (local.get $0) + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.mul ;; nested mul + (i32.add + (i32.const 10) + (local.get $0) + ) + (i32.const 2) + ) + (i32.add + (i32.const 5) + (i32.const 9) + ) + ) + ) + (drop + (i32.add + (i32.add + (local.get $0) + (i32.const 10) ;; cancelled out with the below + ) + (i32.sub + (i32.const -5) + (i32.const 5) + ) + ) + ) + ) + ;; CHECK: (func $almost-sign-ext (param $0 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 50) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $almost-sign-ext (param $0 i32) + (drop + (i32.shr_s + (i32.shl + (i32.const 100) ;; too big, there is a sign bit, due to the extra shift + (i32.const 25) + ) + (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift, in theory + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.const 50) ;; small enough, no sign bit + (i32.const 25) + ) + (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift + ) + ) + ) + ;; CHECK: (func $squaring (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 203) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 19) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 19) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 19) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 11) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $squaring (param $0 i32) (param $1 i32) + (drop + (i32.and + (i32.and + (local.get $0) + (i32.const 11) + ) + (i32.const 200) + ) + ) + (drop + (i32.and + (i32.and + (local.get $0) + (i32.const 11) + ) + (local.get $0) ;; non-const, cannot optimize this! + ) + ) + (drop + (i32.and + (i32.and + (i32.const 11) ;; flipped order + (local.get $0) + ) + (i32.const 200) + ) + ) + (drop + (i32.or + (i32.or + (local.get $0) + (i32.const 11) + ) + (i32.const 200) + ) + ) + (drop + (i32.shl + (i32.shl + (local.get $0) + (i32.const 11) + ) + (i32.const 200) + ) + ) + (drop + (i32.shr_s + (i32.shr_s + (local.get $0) + (i32.const 11) + ) + (i32.const 200) + ) + ) + (drop + (i32.shr_u + (i32.shr_u + (local.get $0) + (i32.const 11) + ) + (i32.const 200) + ) + ) + (drop + (i32.shr_u + (i32.shr_s ;; but do not optimize a mixture or different shifts! + (local.get $0) + (i32.const 11) + ) + (i32.const 200) + ) + ) + ) + ;; CHECK: (func $sign-ext-ne (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext-ne (param $0 i32) (param $1 i32) + ;; ne of sign-ext to const, can be a zext + (drop + (i32.ne + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 65000) + ) + ) + (drop + (i32.ne + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 64872) ;; no sign bit + ) + ) + (drop + (i32.ne + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const -149) ;; no sign bit, not all ones + ) + ) + (drop + (i32.ne + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 111) + ) + ) + (drop + (i32.ne + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ) + ;; CHECK: (func $sign-ext-eqz (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext-eqz (param $0 i32) (param $1 i32) + (drop + (i32.eqz + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ) + ;; CHECK: (func $sign-ext-boolean (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: (i32.const 200) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext-boolean (param $0 i32) (param $1 i32) + (drop + (if (result i32) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 100) + (i32.const 200) + ) + ) + ) + ;; CHECK: (func $add-sub-zero (param $0 i32) (param $1 i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $add-sub-zero (param $0 i32) (param $1 i64) + (drop + (i32.add + (local.get $0) + (i32.const 0) + ) + ) + (drop + (i32.sub + (local.get $0) + (i32.const 0) + ) + ) + (drop + (i64.add + (local.get $1) + (i64.const 0) + ) + ) + (drop + (i64.sub + (local.get $1) + (i64.const 0) + ) + ) + ) + ;; CHECK: (func $store-signext (param $0 i32) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 25) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store16 + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $store-signext (param $0 i32) + (i32.store8 + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) ;; exact size we store, sign-ext of 8 bits + ) + (i32.const 24) + ) + ) + (i32.store8 + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 25) ;; 7 bits. so the ext can alter a bit we store, do not optimize + ) + (i32.const 25) + ) + ) + (i32.store8 + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 23) ;; 9 bits, this is good to optimize + ) + (i32.const 23) + ) + ) + (i32.store16 + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 16) ;; exact size we store, sign-ext of 16 bits + ) + (i32.const 16) + ) + ) + (i32.store16 + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 17) ;; 15 bits. so the ext can alter a bit we store, do not optimize + ) + (i32.const 17) + ) + ) + (i32.store16 + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 14) ;; 17 bits, this is good to optimize + ) + (i32.const 14) + ) + ) + (i32.store + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 16) ;; 4 bytes stored, do nothing + ) + (i32.const 16) + ) + ) + (i32.store + (i32.const 8) + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 8) ;; 4 bytes stored, do nothing + ) + (i32.const 8) + ) + ) + ) + ;; CHECK: (func $sign-ext-tee (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext-tee (param $0 i32) (param $1 i32) + (drop + (i32.shr_s + (i32.shl + (local.tee $0 + (i32.const 128) ;; too big + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.tee $0 + (i32.const 127) ;; just right + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ;; CHECK: (func $sign-ext-load (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.load16_s + ;; CHECK-NEXT: (i32.const 256) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $1 + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $sign-ext-load (param $0 i32) (param $1 i32) + (drop + (i32.shr_s + (i32.shl + (i32.load8_s ;; one byte, so perfect + (i32.const 256) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u + (i32.load8_s ;; one byte, but sexted to 32 + (i32.const 256) + ) + (i32.const 1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shr_u + (i32.load8_u ;; one byte, but reduced to 7 + (i32.const 256) + ) + (i32.const 1) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.load16_s ;; two, so perfect + (i32.const 256) + ) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ;; through tees, we cannot alter the load sign + (drop + (i32.shr_s + (i32.shl + (local.tee $1 + (i32.load8_s + (i32.const 1) + ) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.tee $1 + (i32.load8_u + (i32.const 1) + ) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.and + (local.tee $1 + (i32.load8_s + (i32.const 1) + ) + ) + (i32.const 255) + ) + ) + (drop + (i32.and + (local.tee $1 + (i32.load8_u + (i32.const 1) + ) + ) + (i32.const 255) + ) + ) + ) + ;; CHECK: (func $mask-bits (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 254) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1279) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1290) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $mask-bits (param $0 i32) (param $1 i32) + (drop + (i32.and + (local.tee $0 + (i32.const 127) ;; 7 bits + ) + (i32.const 255) ;; mask 8, so we don't need this + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) ;; 8 bits + ) + (i32.const 255) ;; mask 8, so we don't need this + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) + ) + (i32.const 254) ;; improper mask, small + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) + ) + (i32.const 1279) ;; improper mask, large + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) + ) + (i32.const 1290) ;; improper mask, large + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) + ) + (i32.const 4095) ;; proper mask, huge + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) + ) + (i32.const 511) ;; proper mask, large + ) + ) + (drop + (i32.and + (local.tee $0 + (i32.const 128) + ) + (i32.const 127) ;; proper mask, just too small + ) + ) + ) + ;; CHECK: (func $local-info-zero-ext (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (local $z i32) + ;; CHECK-NEXT: (local $w i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 212) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 500) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 212) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.const 212) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.const 220) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $w + ;; CHECK-NEXT: (i32.const 212) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $w + ;; CHECK-NEXT: (i32.const 1000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $local-info-zero-ext (param $0 i32) (param $1 i32) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (local.set $x + (i32.const 212) ;; mask is unneeded, we are small + ) + (drop + (i32.and + (local.get $x) + (i32.const 255) + ) + ) + (local.set $y + (i32.const 500) ;; mask is needed, we are too big + ) + (drop + (i32.and + (local.get $y) + (i32.const 255) + ) + ) + (local.set $0 + (i32.const 212) ;; mask is unneeded, but we are a param, not a var, so no + ) + (drop + (i32.and + (local.get $0) + (i32.const 255) + ) + ) + (local.set $z + (i32.const 212) ;; mask is unneeded, we are small + ) + (local.set $z + (i32.const 220) ;; mask is still unneeded even with 2 uses + ) + (drop + (i32.and + (local.get $z) + (i32.const 255) + ) + ) + (local.set $w + (i32.const 212) ;; mask is unneeded, we are small + ) + (local.set $w + (i32.const 1000) ;; mask is needed, one use is too big + ) + (drop + (i32.and + (local.get $w) + (i32.const 255) + ) + ) + ) + ;; CHECK: (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (local $z i32) + ;; CHECK-NEXT: (local $w i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 128) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $w + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $w + ;; CHECK-NEXT: (i32.const 150) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (local.set $x + (i32.const 127) ;; mask is unneeded, we are small + ) + (drop + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $y + (i32.const 128) ;; mask is needed, we are too big + ) + (drop + (i32.shr_s + (i32.shl + (local.get $y) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $0 + (i32.const 127) ;; mask is unneeded, but we are a param, not a var, so no + ) + (drop + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $z + (i32.const 127) ;; mask is unneeded, we are small + ) + (local.set $z + (i32.const 100) ;; mask is still unneeded even with 2 uses + ) + (drop + (i32.shr_s + (i32.shl + (local.get $z) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $w + (i32.const 127) ;; mask is unneeded, we are small + ) + (local.set $w + (i32.const 150) ;; mask is needed, one use is too big + ) + (drop + (i32.shr_s + (i32.shl + (local.get $w) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ;; CHECK: (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (local $z i32) + ;; CHECK-NEXT: (local $w i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $w + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $w + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 23) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 23) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (local.set $x + (i32.shr_s + (i32.shl + (local.get $0) ;; already sign-exted here, so no need later + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $y + (i32.shr_s + (i32.shl + (local.get $0) ;; already sign-exted here, but wrong bit size + (i32.const 16) + ) + (i32.const 16) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.get $y) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $0 + (i32.shr_s + (i32.shl + (local.get $0) ;; already sign-exted here, so no need later, but we are a param + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.get $0) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $z + (i32.shr_s + (i32.shl + (local.get $0) ;; already sign-exted here, so no need later + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $z + (i32.shr_s + (i32.shl + (local.get $1) ;; already sign-exted here, so no need later + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.get $z) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $w + (i32.shr_s + (i32.shl + (local.get $0) ;; already sign-exted here, so no need later + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $w + (i32.shr_s + (i32.shl + (local.get $0) ;; not quite a sign-ext + (i32.const 23) + ) + (i32.const 24) + ) + ) + (drop + (i32.shr_s + (i32.shl + (local.get $w) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (drop ;; odd corner case + (i32.shr_s + (i32.shl + (local.get $0) ;; param, so we should know nothing + (i32.const 24) + ) + (i32.const 23) ;; different shift, smaller + ) + ) + ) + ;; CHECK: (func $signed-loads-fill-the-bits (param $$e i32) (result i32) + ;; CHECK-NEXT: (local $$0 i32) + ;; CHECK-NEXT: (local $$conv i32) + ;; CHECK-NEXT: (local.set $$0 + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 1024) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $$conv + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $$0) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $$e) + ;; CHECK-NEXT: (local.get $$conv) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $signed-loads-fill-the-bits (param $$e i32) (result i32) + (local $$0 i32) + (local $$conv i32) + (local.set $$0 + (i32.load8_s ;; one byte, but 32 bits due to sign-extend + (i32.const 1024) + ) + ) + (local.set $$conv + (i32.and + (local.get $$0) + (i32.const 255) ;; so we need this zexting! + ) + ) + (return + (i32.eq + (local.get $$conv) + (local.get $$e) + ) + ) + ) + ;; CHECK: (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (local $z i32) + ;; CHECK-NEXT: (local $w i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (i32.const 1024) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (i32.const 1024) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $z + ;; CHECK-NEXT: (i32.load16_s + ;; CHECK-NEXT: (i32.const 1024) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (local.set $x + (i32.load8_s (i32.const 1024)) ;; 8 bits, sign extended, no need to do it again + ) + (drop + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $y + (i32.load8_u (i32.const 1024)) ;; 8 bits, zext, so bad + ) + (drop + (i32.shr_s + (i32.shl + (local.get $y) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (local.set $z + (i32.load16_s (i32.const 1024)) ;; 16 bits sign-extended, wrong size + ) + (drop + (i32.shr_s + (i32.shl + (local.get $z) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ;; CHECK: (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_u + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32) + (drop + (i32.eq + (i32.load8_s + (local.get $0) + ) + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.load8_s + (local.get $0) ;; flip order, we should canonicalize + ) + ) + ) + (drop + (i32.eq + (i32.load8_u ;; unsigned, bad + (local.get $0) + ) + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (drop + (i32.eq + (i32.load8_s + (local.get $0) + ) + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 16) ;; wrong size + ) + (i32.const 16) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.load8_u ;; unsigned, bad + (local.get $0) + ) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $1) + (i32.const 16) ;; wrong size + ) + (i32.const 16) + ) + (i32.load8_s + (local.get $0) + ) + ) + ) + ) + ;; CHECK: (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (call $unsign-diff-sizes + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 24) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (call $unsign-diff-sizes + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2006) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32) + (i32.ne + (i32.shr_s + (i32.shl + (call $unsign-diff-sizes + (i32.const -1) + (i32.const 5) + ) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.shr_s + (i32.shl + (call $unsign-diff-sizes + (i32.const 1) + (i32.const 2006) + ) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ) + ;; CHECK: (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32) + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (call $unsign-same-sizes + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (call $unsign-same-sizes + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2006) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32) + (i32.ne + (i32.shr_s + (i32.shl + (call $unsign-same-sizes + (i32.const -1) + (i32.const 5) + ) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.shr_s + (i32.shl + (call $unsign-same-sizes + (i32.const 1) + (i32.const 2006) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ;; CHECK: (func $fuzz-almost-sign-ext + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.load16_u + ;; CHECK-NEXT: (i32.const 2278) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.load16_u + ;; CHECK-NEXT: (i32.const 2278) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 17) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $fuzz-almost-sign-ext + (drop + (i32.shr_s + (i32.shl + (i32.load16_u + (i32.const 2278) + ) + (i32.const 17) + ) + (i32.const 16) + ) + ) + (drop + (i32.shr_s + (i32.shl + (i32.shl + (i32.load16_u + (i32.const 2278) + ) + (i32.const 1) + ) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ) + ;; CHECK: (func $fuzz-comp-impossible (param $x i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 252) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $fuzz-comp-impossible (param $x i32) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 16) + ) + (i32.const 16) + ) + (i32.const 65535) ;; impossible to be equal, the effective sign bit is set, but not the higher bits, which the sign-ext will set on the non-const value + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 255) + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 127) ;; safe + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 128) ;; unsafe again + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 4223) ;; more big bits, so sign bit though + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const 4224) ;; more big bits + ) + ) + (drop + (i32.eq + (i32.shr_s + (i32.shl + (local.get $x) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const -4) ;; safe even with more big bits, as they are all 1s + ) + ) + ) + ;; CHECK: (func $if-parallel (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-parallel (param $0 i32) (param $1 i32) + (drop + (if (result i32) + (local.get $0) + (i32.add (local.get $1) (i32.const 1)) + (i32.add (local.get $1) (i32.const 1)) + ) + ) + (drop + (if (result i32) + (local.tee $0 (local.get $1)) ;; side effects! + (i32.add (local.get $1) (i32.const 1)) + (i32.add (local.get $1) (i32.const 1)) + ) + ) + (drop + (if (result i32) + (local.get $0) + (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if + (i32.add (local.get $1) (unreachable)) + ) + ) + (drop + (if (result i32) + (local.tee $0 (local.get $1)) ;; side effects! + (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if + (i32.add (local.get $1) (unreachable)) + ) + ) + (drop + (if (result i32) + (unreachable) ;; !!! + (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if + (i32.add (local.get $1) (unreachable)) + ) + ) + ) + ;; CHECK: (func $select-parallel (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-parallel (param $0 i32) (param $1 i32) + (drop + (select + (i32.add (local.get $1) (i32.const 1)) + (i32.add (local.get $1) (i32.const 1)) + (local.get $0) + ) + ) + (drop + (select + (local.tee $0 (local.get $1)) ;; side effects! + (local.tee $0 (local.get $1)) ;; side effects! + (local.get $0) + ) + ) + (drop + (select + (i32.add (local.get $1) (i32.const 1)) + (i32.add (local.get $1) (i32.const 1)) + (local.tee $0 (local.get $1)) ;; side effects! (but no interference with values) + ) + ) + (drop + (select + (local.tee $0 (local.get $1)) ;; side effects! interference! + (local.tee $0 (local.get $1)) ;; side effects! interference! + (local.tee $0 (local.get $1)) ;; side effects! interference! + ) + ) + (drop + (select + (local.tee $0 (local.get $1)) ;; side effects! + (local.tee $0 (local.get $1)) ;; side effects! + (unreachable) ;; side effects! (but no interference with values) + ) + ) + ) + ;; CHECK: (func $zero-shifts-is-not-sign-ext + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load16_s align=1 + ;; CHECK-NEXT: (i32.const 790656516) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -5431187) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.load16_s align=1 + ;; CHECK-NEXT: (i32.const 790656516) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -5431187) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $zero-shifts-is-not-sign-ext + (drop + (i32.eq + (i32.const -5431187) + (i32.add + (i32.const 0) + (i32.shr_s + (i32.shl + (i32.load16_s align=1 + (i32.const 790656516) + ) + (i32.const 0) + ) + (i32.const 0) + ) + ) + ) + ) + (drop + (i32.eq + (i32.const -5431187) + (i32.add + (i32.const 0) + (i32.shr_s + (i32.shl + (i32.load16_s align=1 + (i32.const 790656516) + ) + (i32.const 1) + ) + (i32.const 0) + ) + ) + ) + ) + ) + ;; CHECK: (func $zero-ops (result i32) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.load16_s align=1 + ;; CHECK-NEXT: (i32.const 790656516) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1337) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $zero-ops (result i32) + (return + (i32.eq + (i32.const -1337) + (i32.shr_u + (i32.add + (i32.const 0) + (i32.shr_s + (i32.shl + (i32.load16_s align=1 + (i32.const 790656516) + ) + (i32.const 0) + ) + (i32.const 0) + ) + ) + (i32.const 0) + ) + ) + ) + ) + ;; CHECK: (func $zero-ops-64 (result i32) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (i64.load16_s align=1 + ;; CHECK-NEXT: (i32.const 790656516) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const -1337) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $zero-ops-64 (result i32) + (return + (i64.eq + (i64.const -1337) + (i64.shr_u + (i64.add + (i64.const 0) + (i64.shr_s + (i64.shl + (i64.load16_s align=1 + (i32.const 790656516) + ) + (i64.const 0) + ) + (i64.const 0) + ) + ) + (i64.const 0) + ) + ) + ) + ) + ;; CHECK: (func $zero-ops-64-special (result i32) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.popcnt + ;; CHECK-NEXT: (i64.const 7377) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $zero-ops-64-special (result i32) + (return + (i32.wrap_i64 + (i64.popcnt + (i64.sub + (i64.shl + (i64.const 4294783828) + (i64.const 17179869183) + ) + (i64.const -7377) + ) + ) + ) + ) + ) + ;; CHECK: (func $sign-ext-1-and-ne (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $sign-ext-1-and-ne) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $sign-ext-1-and-ne (result i32) + (select + (i32.ne + (i32.const 1333788672) + (i32.shr_s + (i32.shl + (call $sign-ext-1-and-ne) + (i32.const 1) + ) + (i32.const 1) + ) + ) + (i32.const 2) + (i32.const 1) + ) + ) + ;; CHECK: (func $neg-shifts-and-255 (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const -99) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $neg-shifts-and-255 (result i32) + (i32.and + (i32.shr_u + (i32.const -99) + (i32.const -32) ;; this shift does nothing + ) + (i32.const 255) + ) + ) + ;; CHECK: (func $neg-shifts-and-255-b (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.const -2349025) + ;; CHECK-NEXT: (i32.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $neg-shifts-and-255-b (result i32) + (i32.and + (i32.shl + (i32.const -2349025) + (i32.const -32) ;; this shift does nothing + ) + (i32.const 255) + ) + ) + ;; CHECK: (func $shifts-square-overflow (param $x i32) (result i32) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $shifts-square-overflow (param $x i32) (result i32) + (i32.shr_u + (i32.shr_u + (local.get $x) + (i32.const 65535) ;; 31 bits effectively + ) + (i32.const 32767) ;; also 31 bits, so two shifts that force the value into nothing for sure + ) + ) + ;; CHECK: (func $shifts-square-no-overflow-small (param $x i32) (result i32) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $shifts-square-no-overflow-small (param $x i32) (result i32) + (i32.shr_u + (i32.shr_u + (local.get $x) + (i32.const 1031) ;; 7 bits effectively + ) + (i32.const 4098) ;; 2 bits effectively + ) + ) + ;; CHECK: (func $shifts-square-overflow-64 (param $x i64) (result i64) + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $shifts-square-overflow-64 (param $x i64) (result i64) + (i64.shr_u + (i64.shr_u + (local.get $x) + (i64.const 65535) ;; 63 bits effectively + ) + (i64.const 64767) ;; also 63 bits, so two shifts that force the value into nothing for sure + ) + ) + ;; CHECK: (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64) + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64) + (i64.shr_u + (i64.shr_u + (local.get $x) + (i64.const 1031) ;; 7 bits effectively + ) + (i64.const 4098) ;; 2 bits effectively + ) + ) + ;; CHECK: (func $shifts-square-unreachable (param $x i32) (result i32) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 1031) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4098) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $shifts-square-unreachable (param $x i32) (result i32) + (i32.shr_u + (i32.shr_u + (unreachable) + (i32.const 1031) ;; 7 bits effectively + ) + (i32.const 4098) ;; 2 bits effectively + ) + ) + ;; CHECK: (func $mix-shifts (result i32) + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 23) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $mix-shifts (result i32) + (i32.shr_s + (i32.shl + (i32.const 23) + (i32.const -61) + ) + (i32.const 168) + ) + ) + ;; CHECK: (func $actually-no-shifts (result i32) + ;; CHECK-NEXT: (i32.const 33) + ;; CHECK-NEXT: ) + (func $actually-no-shifts (result i32) + (i32.add + (i32.shl + (i32.const 23) + (i32.const 32) ;; really 0 + ) + (i32.const 10) + ) + ) + ;; CHECK: (func $less-shifts-than-it-seems (param $x i32) (result i32) + ;; CHECK-NEXT: (i32.const 4800) + ;; CHECK-NEXT: ) + (func $less-shifts-than-it-seems (param $x i32) (result i32) + (i32.add + (i32.shl + (i32.const 200) + (i32.const 36) ;; really 4 + ) + (i32.shl + (i32.const 100) + (i32.const 4) + ) + ) + ) + ;; CHECK: (func $and-popcount32 (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.popcnt + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-popcount32 (result i32) + (i32.and + (i32.popcnt + (i32.const -1) + ) + (i32.const 31) + ) + ) + ;; CHECK: (func $and-popcount32-big (result i32) + ;; CHECK-NEXT: (i32.popcnt + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-popcount32-big (result i32) + (i32.and + (i32.popcnt + (i32.const -1) + ) + (i32.const 63) + ) + ) + ;; CHECK: (func $and-popcount64 (result i64) + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (i64.popcnt + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-popcount64 (result i64) ;; these are TODOs + (i64.and + (i64.popcnt + (i64.const -1) + ) + (i64.const 63) + ) + ) + ;; CHECK: (func $and-popcount64-big (result i64) + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (i64.popcnt + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 127) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-popcount64-big (result i64) + (i64.and + (i64.popcnt + (i64.const -1) + ) + (i64.const 127) + ) + ) + ;; CHECK: (func $and-popcount64-bigger (result i64) + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (i64.popcnt + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 255) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $and-popcount64-bigger (result i64) + (i64.and + (i64.popcnt + (i64.const -1) + ) + (i64.const 255) + ) + ) + ;; CHECK: (func $optimizeAddedConstants-filters-through-nonzero (result i32) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const -536870912) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31744) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimizeAddedConstants-filters-through-nonzero (result i32) + (i32.sub + (i32.add + (i32.shl + (i32.const -536870912) + (i32.wrap_i64 + (i64.const 0) + ) + ) + (i32.const -32768) + ) + (i32.const -1024) + ) + ) + ;; CHECK: (func $optimizeAddedConstants-filters-through-nonzero-b (result i32) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const -536870912) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 31744) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimizeAddedConstants-filters-through-nonzero-b (result i32) + (i32.sub + (i32.add + (i32.shl + (i32.const -536870912) + (i32.wrap_i64 + (i64.const -1) + ) + ) + (i32.const -32768) + ) + (i32.const -1024) + ) + ) + ;; CHECK: (func $return-proper-value-from-shift-left-by-zero (result i32) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (loop $label$0 (result i32) + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (br_if $label$1 + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -62) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 40) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $return-proper-value-from-shift-left-by-zero (result i32) + (if (result i32) + (i32.sub + (i32.add + (loop $label$0 (result i32) + (block $label$1 + (br_if $label$1 + (i32.shl + (i32.load + (i32.const 0) + ) + (i32.const -31904) ;; really 0 shifts + ) + ) + ) + (i32.const -62) + ) + (i32.const 38) + ) + (i32.const -2) + ) + (i32.const 1) + (i32.const 0) + ) + ) + ;; CHECK: (func $de-morgan-2 (param $x i32) (param $y i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $de-morgan-2 (param $x i32) (param $y i32) + (drop + (i32.and (i32.eqz (local.get $x)) (i32.eqz (local.get $y))) + ) + (drop + (i32.or (i32.eqz (local.get $x)) (i32.eqz (local.get $y))) + ) + (drop + (i32.xor (i32.eqz (local.get $x)) (i32.eqz (local.get $y))) + ) + (drop + (i32.and (i32.eqz (local.get $x)) (local.get $y)) + ) + (drop + (i32.and (local.get $x) (i32.eqz (local.get $y))) + ) + (drop + (i32.and (i32.eqz (local.get $x)) (i32.wrap_i64 (i64.const 2))) + ) + (drop + (i32.and (i32.wrap_i64 (i64.const 1)) (i32.eqz (local.get $y))) + ) + ) + ;; CHECK: (func $subzero1 (param $0 i32) (result i32) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $subzero1 (param $0 i32) (result i32) + (i32.add + (i32.sub + (i32.const 1) + (i32.clz + (local.get $0) + ) + ) + (i32.const 31) + ) + ) + ;; CHECK: (func $subzero2 (param $0 i32) (result i32) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 32) + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $subzero2 (param $0 i32) (result i32) + (i32.add + (i32.const 31) + (i32.sub + (i32.const 1) + (i32.clz + (local.get $0) + ) + ) + ) + ) + ;; CHECK: (func $subzero3 (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $subzero3 (param $0 i32) (param $1 i32) (result i32) + (i32.add + (i32.sub + (i32.const 0) + (i32.clz + (local.get $0) + ) + ) + (local.get $1) + ) + ) + ;; CHECK: (func $subzero4 (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.clz + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $subzero4 (param $0 i32) (param $1 i32) (result i32) + (i32.add + (local.get $0) + (i32.sub + (i32.const 0) + (i32.clz + (local.get $1) + ) + ) + ) + ) + ;; CHECK: (func $mul-32-power-2 (param $x i32) (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.mul + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.const 123) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-32-power-2 + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $mul-32-power-2 (param $x i32) (result i32) + (drop + (call $mul-32-power-2 + (i32.mul + (local.get $x) + (i32.const 4) + ) + ) + ) + (drop + (call $mul-32-power-2 + (i32.mul + (local.get $x) + (i32.const 5) + ) + ) + ) + (drop + (call $mul-32-power-2 + (i32.mul + (local.get $x) + (i32.const 1) + ) + ) + ) + (drop + (call $mul-32-power-2 + (i32.mul + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (call $mul-32-power-2 + (i32.mul + (call $mul-32-power-2 (i32.const 123)) ;; side effects + (i32.const 0) + ) + ) + ) + (drop + (call $mul-32-power-2 + (i32.mul + (local.get $x) + (i32.const 0xffffffff) + ) + ) + ) + (drop + (call $mul-32-power-2 + (i32.mul + (local.get $x) + (i32.const 0x80000000) + ) + ) + ) + (unreachable) + ) + ;; CHECK: (func $mul-64-power-2 (param $x i64) (result i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.shl + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.mul + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.const 123) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $mul-64-power-2 + ;; CHECK-NEXT: (i64.shl + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $mul-64-power-2 (param $x i64) (result i64) + (drop + (call $mul-64-power-2 + (i64.mul + (local.get $x) + (i64.const 4) + ) + ) + ) + (drop + (call $mul-64-power-2 + (i64.mul + (local.get $x) + (i64.const 5) + ) + ) + ) + (drop + (call $mul-64-power-2 + (i64.mul + (local.get $x) + (i64.const 1) + ) + ) + ) + (drop + (call $mul-64-power-2 + (i64.mul + (local.get $x) + (i64.const 0) + ) + ) + ) + (drop + (call $mul-64-power-2 + (i64.mul + (call $mul-64-power-2 (i64.const 123)) ;; side effects + (i64.const 0) + ) + ) + ) + (drop + (call $mul-64-power-2 + (i64.mul + (local.get $x) + (i64.const 0xffffffffffffffff) + ) + ) + ) + (drop + (call $mul-64-power-2 + (i64.mul + (local.get $x) + (i64.const 0x8000000000000000) + ) + ) + ) + (unreachable) + ) + ;; CHECK: (func $div-32-power-2 (param $x i32) (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.div_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.div_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.div_u + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.const 123) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $div-32-power-2 + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $div-32-power-2 (param $x i32) (result i32) + (drop + (call $div-32-power-2 + (i32.div_u + (local.get $x) + (i32.const 4) + ) + ) + ) + (drop + (call $div-32-power-2 + (i32.div_u + (local.get $x) + (i32.const 5) + ) + ) + ) + (drop + (call $div-32-power-2 + (i32.div_u + (local.get $x) + (i32.const 1) + ) + ) + ) + (drop + (call $div-32-power-2 + (i32.div_u + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (call $div-32-power-2 + (i32.div_u + (call $div-32-power-2 (i32.const 123)) ;; side effects + (i32.const 0) + ) + ) + ) + (drop + (call $div-32-power-2 + (i32.div_u + (local.get $x) + (i32.const 0xffffffff) + ) + ) + ) + (drop + (call $div-32-power-2 + (i32.div_u + (local.get $x) + (i32.const 0x80000000) + ) + ) + ) + (unreachable) + ) + ;; CHECK: (func $urem-32-power-2 (param $x i32) (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $urem-32-power-2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $urem-32-power-2 (param $x i32) (result i32) + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 4) + ) + ) + ) + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 5) + ) + ) + ) + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 1) + ) + ) + ) + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 0xffffffff) + ) + ) + ) + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 0x80000000) + ) + ) + ) + ;; (unsigned)x % 1 + (drop + (call $urem-32-power-2 + (i32.rem_u + (local.get $x) + (i32.const 1) + ) + ) + ) + (unreachable) + ) + ;; CHECK: (func $fdiv-32-power-2 (param $x f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 0.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const -0.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 2.3283064365386963e-10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 5.421010862427522e-20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 8507059173023461586584365e13) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 1.1754943508222875e-38) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const -8507059173023461586584365e13) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const -1.1754943508222875e-38) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 5.877471754111438e-39) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 5.877471754111438e-39) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const nan:0x400000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const inf) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f32.const -inf) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $fdiv-32-power-2 (param $x f32) + (drop (f32.div + (local.get $x) + (f32.const 2) + )) + (drop (f32.div + (local.get $x) + (f32.const -2) + )) + (drop (f32.div + (local.get $x) + (f32.const 4294967296) + )) + (drop (f32.div + (local.get $x) + (f32.const 18446744073709551616) + )) + (drop (f32.div + (local.get $x) + (f32.const 0x1p-126) + )) + (drop (f32.div + (local.get $x) + (f32.const 0x1p+126) + )) + (drop (f32.div + (local.get $x) + (f32.const -0x1p-126) + )) + (drop (f32.div + (local.get $x) + (f32.const -0x1p+126) + )) + (drop (f32.div + (local.get $x) + (f32.const 0x1p-127) ;; skip + )) + (drop (f32.div + (local.get $x) + (f32.const 0x1p-127) ;; skip + )) + (drop (f32.div + (local.get $x) + (f32.const 0) ;; skip + )) + (drop (f32.div + (local.get $x) + (f32.const nan) ;; skip + )) + (drop (f32.div + (local.get $x) + (f32.const inf) ;; skip + )) + (drop (f32.div + (local.get $x) + (f32.const -inf) ;; skip + )) + ) + ;; CHECK: (func $fdiv-64-power-2 (param $x f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 0.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const -0.5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 2.3283064365386963e-10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 5.421010862427522e-20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 4494232837155789769323262e283) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 2.2250738585072014e-308) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const -4494232837155789769323262e283) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const -2.2250738585072014e-308) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 1.1125369292536007e-308) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 8988465674311579538646525e283) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const nan:0x8000000000000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const inf) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (f64.const -inf) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $fdiv-64-power-2 (param $x f64) + (drop (f64.div + (local.get $x) + (f64.const 2) + )) + (drop (f64.div + (local.get $x) + (f64.const -2) + )) + (drop (f64.div + (local.get $x) + (f64.const 4294967296) + )) + (drop (f64.div + (local.get $x) + (f64.const 18446744073709551616) + )) + (drop (f64.div + (local.get $x) + (f64.const 0x1p-1022) + )) + (drop (f64.div + (local.get $x) + (f64.const 0x1p+1022) + )) + (drop (f64.div + (local.get $x) + (f64.const -0x1p-1022) + )) + (drop (f64.div + (local.get $x) + (f64.const -0x1p+1022) + )) + (drop (f64.div + (local.get $x) + (f64.const 0x1p-1023) ;; skip + )) + (drop (f64.div + (local.get $x) + (f64.const 0x1p+1023) ;; skip + )) + (drop (f64.div + (local.get $x) + (f64.const 0) ;; skip + )) + (drop (f64.div + (local.get $x) + (f64.const nan) ;; skip + )) + (drop (f64.div + (local.get $x) + (f64.const inf) ;; skip + )) + (drop (f64.div + (local.get $x) + (f64.const -inf) ;; skip + )) + ) + ;; CHECK: (func $srem-by-const (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.rem_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -9223372036854775808) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $srem-by-const (param $x i32) (param $y i64) + ;; (signed)x % 1 + (drop (i32.rem_s + (local.get $x) + (i32.const 1) + )) + (drop (i64.rem_s + (local.get $y) + (i64.const 1) + )) + ;; (signed)x % 0x80000000 -> x & 0x7FFFFFFF + (drop (i32.rem_s + (local.get $x) + (i32.const 0x80000000) + )) + ;; (signed)x % 0x8000000000000000 -> x & 0x7FFFFFFFFFFFFFFF + (drop (i64.rem_s + (local.get $y) + (i64.const 0x8000000000000000) + )) + ) + ;; CHECK: (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 9223372036854775807) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 9223372036854775807) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.rem_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64) + ;; eqz((signed)x % 4) + (drop (i32.eqz + (i32.rem_s + (local.get $x) + (i32.const 4) + ) + )) + (drop (i64.eqz + (i64.rem_s + (local.get $y) + (i64.const 4) + ) + )) + ;; eqz((signed)x % -4) + (drop (i32.eqz + (i32.rem_s + (local.get $x) + (i32.const -4) + ) + )) + (drop (i64.eqz + (i64.rem_s + (local.get $y) + (i64.const -4) + ) + )) + ;; (signed)x % 4 == 0 + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const 4) + ) + (i32.const 0) + )) + (drop (i64.eq + (i64.rem_s + (local.get $y) + (i64.const 2) + ) + (i64.const 0) + )) + ;; (signed)x % -4 == 0 + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const -4) + ) + (i32.const 0) + )) + (drop (i64.eq + (i64.rem_s + (local.get $y) + (i64.const -4) + ) + (i64.const 0) + )) + ;; (signed)x % 2 != 0 + (drop (i32.ne + (i32.rem_s + (local.get $x) + (i32.const 2) + ) + (i32.const 0) + )) + (drop (i64.ne + (i64.rem_s + (local.get $y) + (i64.const 2) + ) + (i64.const 0) + )) + ;; (signed)x % -1 == 0 -> 0 == 0 + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const -1) + ) + (i32.const 0) + )) + ;; (signed)x % 0x80000000 == 0 + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; (signed)x % 0x80000000 != 0 + (drop (i32.ne + (i32.rem_s + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; (signed)x % 0x8000000000000000 == 0 + (drop (i64.eq + (i64.rem_s + (local.get $y) + (i64.const 0x8000000000000000) + ) + (i64.const 0) + )) + ;; (signed)x % 0x8000000000000000 != 0 + (drop (i64.ne + (i64.rem_s + (local.get $y) + (i64.const 0x8000000000000000) + ) + (i64.const 0) + )) + ;; + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const 3) ;; skip + ) + (i32.const 0) + )) + (drop (i64.eq + (i64.rem_s + (local.get $y) + (i64.const 3) ;; skip + ) + (i64.const 0) + )) + ) + ;; CHECK: (func $orZero (param $0 i32) (result i32) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + (func $orZero (param $0 i32) (result i32) + (i32.or + (local.get $0) + (i32.const 0) + ) + ) + ;; CHECK: (func $andZero (param $0 i32) (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (call $andZero + ;; CHECK-NEXT: (i32.const 1234) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $andZero (param $0 i32) (result i32) + (drop + (i32.and + (local.get $0) + (i32.const 0) + ) + ) + (drop + (i32.and + (call $andZero (i32.const 1234)) ;; side effects + (i32.const 0) + ) + ) + (unreachable) + ) + ;; CHECK: (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $y32) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $y64) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $y32) + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $y64) + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $y32) + ;; CHECK-NEXT: (f32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $y64) + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $y32) + ;; CHECK-NEXT: (f32.const 1.2000000476837158) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: (local.get $y32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (f64.const -0) + ;; CHECK-NEXT: (local.get $y64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.le_u + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $x64) + ;; CHECK-NEXT: (i64.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 30) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64) + (drop + (i32.or + (i32.const 0) + (local.get $x32) + ) + ) + (drop + (i32.shl + (local.get $x32) + (i32.const 0) + ) + ) + (drop + (i32.shr_u + (local.get $x32) + (i32.const 0) + ) + ) + (drop + (i32.shr_s + (local.get $x32) + (i32.const 0) + ) + ) + (drop + (i64.or + (i64.const 0) + (local.get $x64) + ) + ) + (drop + (i64.shl + (local.get $x64) + (i64.const 0) + ) + ) + (drop + (i64.shr_u + (local.get $x64) + (i64.const 0) + ) + ) + (drop + (i64.shr_s + (local.get $x64) + (i64.const 0) + ) + ) + (drop + (i32.mul + (local.get $x32) + (i32.const 0) + ) + ) + (drop + (i64.mul + (local.get $x64) + (i64.const 0) + ) + ) + (drop + (f32.mul + (local.get $y32) + (f32.const 0) + ) + ) + (drop + (f64.mul + (local.get $y64) + (f64.const 0) + ) + ) + (drop + (i32.mul + (local.get $x32) + (i32.const 1) + ) + ) + (drop + (i64.mul + (local.get $x64) + (i64.const 1) + ) + ) + (drop + (f32.mul + (local.get $y32) + (f32.const 1) + ) + ) + (drop + (f64.mul + (local.get $y64) + (f64.const 1) + ) + ) + (drop + (i32.and + (local.get $x32) + (i32.const 0) + ) + ) + (drop + (i64.and + (local.get $x64) + (i64.const 0) + ) + ) + (drop + (i32.and + (unreachable) + (i32.const 0) + ) + ) + (drop + (i64.and + (unreachable) + (i64.const 0) + ) + ) + (drop + (i32.div_s + (local.get $x32) + (i32.const 1) + ) + ) + (drop + (i32.div_u + (local.get $x32) + (i32.const 1) + ) + ) + (drop + (i64.div_s + (local.get $x64) + (i64.const 1) + ) + ) + (drop + (i64.div_u + (local.get $x64) + (i64.const 1) + ) + ) + (drop + (f32.div + (local.get $y32) + (f32.const 1) + ) + ) + (drop + (f64.div + (local.get $y64) + (f64.const 1) + ) + ) + (drop + (f32.div + (local.get $y32) + (f32.const 1.2) + ) + ) + (drop + (i32.mul + (local.get $x32) + (i32.const -1) + ) + ) + (drop + (i64.mul + (local.get $x64) + (i64.const -1) + ) + ) + (drop + (f32.mul + (local.get $y32) + (f32.const -1) + ) + ) + (drop + (f64.mul + (local.get $y64) + (f64.const -1) + ) + ) + (drop + (i32.eq + (i32.add + (local.get $x32) + (i32.const 10) + ) + (i32.const 20) + ) + ) + (drop + (i32.le_u + (i32.add + (local.get $x32) + (i32.const 10) + ) + (i32.const 20) + ) + ) + (drop + (i32.eq + (i32.sub + (local.get $x32) + (i32.const 10) + ) + (i32.const 20) + ) + ) + (drop + (i64.eq + (i64.add + (local.get $x64) + (i64.const 10) + ) + (i64.const 20) + ) + ) + (drop + (i32.eq + (i32.const 20) + (i32.add + (local.get $x32) + (i32.const 10) + ) + ) + ) + (drop + (i32.eq + (i32.add + (local.get $x32) + (i32.const 10) + ) + (i32.add + (local.get $x32) + (i32.const 20) + ) + ) + ) + (drop + (i32.eq + (i32.sub + (local.get $x32) + (i32.const 10) + ) + (i32.const 20) + ) + ) + (drop + (i32.eq + (i32.add + (local.get $x32) + (i32.const 10) + ) + (i32.sub + (local.get $x32) + (i32.const 20) + ) + ) + ) + (drop + (i32.eq + (i32.sub + (local.get $x32) + (i32.const 10) + ) + (i32.add + (local.get $x32) + (i32.const 20) + ) + ) + ) + (drop + (i32.eq + (i32.sub + (local.get $x32) + (i32.const 10) + ) + (i32.sub + (local.get $x32) + (i32.const 20) + ) + ) + ) + (drop + (i64.le_s + (i64.sub + (local.get $x64) + (i64.const 288230376151711744) + ) + (i64.const 9223372036854775807) + ) + ) + ) + ;; CHECK: (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -134217728) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.add + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -134217728) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -17179869184) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -2199023255552) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -281474976710656) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -36028797018963968) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -4611686018427387904) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.add + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (f32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32) + (drop (i32.add (local.get $x) (i32.const 0x40))) + (drop (i32.sub (local.get $x) (i32.const 0x40))) + (drop (i32.add (local.get $x) (i32.const 0x2000))) + (drop (i32.add (local.get $x) (i32.const 0x100000))) + (drop (i32.add (local.get $x) (i32.const 0x8000000))) + + (drop (i64.add (local.get $y) (i64.const 0x40))) + (drop (i64.sub (local.get $y) (i64.const 0x40))) + (drop (i64.add (local.get $y) (i64.const 0x2000))) + (drop (i64.add (local.get $y) (i64.const 0x100000))) + (drop (i64.add (local.get $y) (i64.const 0x8000000))) + + (drop (i64.add (local.get $y) (i64.const 0x400000000))) + (drop (i64.add (local.get $y) (i64.const 0x20000000000))) + (drop (i64.add (local.get $y) (i64.const 0x1000000000000))) + (drop (i64.add (local.get $y) (i64.const 0x80000000000000))) + (drop (i64.add (local.get $y) (i64.const 0x4000000000000000))) + + (drop (f32.add (local.get $z) (f32.const 0x40))) + ) + ;; CHECK: (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32) + (drop + (i32.shl + (i32.const 0) + (local.get $x) + ) + ) + (drop + (i32.shr_u + (i32.const 0) + (local.get $x) + ) + ) + (drop + (i32.shr_s + (i32.const 0) + (local.get $x) + ) + ) + (drop + (i64.shl + (i64.const 0) + (local.get $y) + ) + ) + (drop + (i32.shl + (i32.const 0) + (unreachable) + ) + ) + ) + ;; CHECK: (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $xx) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32) + (drop + (i32.sub + (local.get $x) + (local.get $x) + ) + ) + (drop + (i64.sub + (local.get $y) + (local.get $y) + ) + ) + (drop + (f64.sub + (local.get $z) + (local.get $z) + ) + ) + (drop + (i32.sub + (local.get $x) + (local.get $xx) + ) + ) + (drop + (i32.sub + (unreachable) + (unreachable) + ) + ) + (drop + (i32.add + (local.get $x) + (local.get $x) + ) + ) + ;; more ops + (drop + (i32.xor + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.ne + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.lt_s + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.lt_u + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.gt_s + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.gt_u + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.and + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.or + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.eq + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.le_s + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.le_u + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.ge_s + (local.get $x) + (local.get $x) + ) + ) + (drop + (i32.ge_u + (local.get $x) + (local.get $x) + ) + ) + (drop + (i64.xor + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.ne + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.lt_s + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.lt_u + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.gt_s + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.gt_u + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.and + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.or + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.eq + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.le_s + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.le_u + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.ge_s + (local.get $y) + (local.get $y) + ) + ) + (drop + (i64.ge_u + (local.get $y) + (local.get $y) + ) + ) + ) + ;; CHECK: (func $all_ones (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 1337) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $all_ones (param $x i32) (param $y i64) + (drop + (i32.and + (local.get $x) + (i32.const -1) + ) + ) + (drop + (i32.or + (local.get $x) + (i32.const -1) + ) + ) + (drop + (i32.or + (local.tee $x + (i32.const 1337) + ) + (i32.const -1) + ) + ) + (drop + (i64.and + (local.get $y) + (i64.const -1) + ) + ) + (drop + (i64.or + (local.get $y) + (i64.const -1) + ) + ) + ) + ;; CHECK: (func $xor (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $xor (param $x i32) (param $y i64) + (drop + (i32.xor + (local.get $x) + (i32.const 0) + ) + ) + ) + ;; CHECK: (func $select-on-const (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.le_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.ge_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.lt_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.lt_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.ge_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-on-const (param $x i32) (param $y i64) + (drop + (select + (i32.const 2) + (local.get $x) + (i32.const 0) + ) + ) + (drop + (select + (i32.const 3) + (local.get $x) + (i32.const 1) + ) + ) + (drop + (select + (i32.const 4) + (local.tee $x + (i32.const 5) + ) + (i32.const 0) + ) + ) + (drop + (select + (local.tee $x + (i32.const 6) + ) + (i32.const 7) + (i32.const 0) + ) + ) + (drop + (select + (i32.const 4) + (local.tee $x + (i32.const 5) + ) + (i32.const 1) + ) + ) + (drop + (select + (local.tee $x + (i32.const 6) + ) + (i32.const 7) + (i32.const 1) + ) + ) + (drop + (select + (i32.const 1) + (i32.const 0) + (local.get $x) + ) + ) + (drop + (select + (i32.const 0) + (i32.const 1) + (local.get $x) + ) + ) + (drop + (select + (i32.const 0) + (i32.const 1) + (i32.lt_s + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (select + (i32.const 1) + (i32.const 0) + (i32.lt_s + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (select + (i32.const 0) + (i32.const 1) + (i32.ge_s + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (select + (i32.const 1) + (i32.const 0) + (i32.gt_s + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (select + (i32.const 0) + (i32.const 1) + (i32.gt_s + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (select + (i32.const 1) + (i32.const 0) + (i32.ge_s + (local.get $x) + (i32.const 0) + ) + ) + ) + (drop + (select + (i64.const 1) + (i64.const 0) + (local.get $x) + ) + ) + (drop + (select + (i64.const 0) + (i64.const 1) + (local.get $x) + ) + ) + (drop + (select + (i64.const 1) + (i64.const 0) + (i64.eqz + (local.get $y) + ) + ) + ) + (drop + (select + (i64.const 0) + (i64.const 1) + (i64.eqz + (local.get $y) + ) + ) + ) + (drop + (select + (i64.const 0) + (i64.const 1) + (i64.lt_s + (local.get $y) + (i64.const 0) + ) + ) + ) + (drop + (select + (i64.const 1) + (i64.const 0) + (i64.lt_s + (local.get $y) + (i64.const 0) + ) + ) + ) + (drop + (select + (i64.const 0) + (i64.const 1) + (i64.ge_s + (local.get $y) + (i64.const 0) + ) + ) + ) + (drop + (select + (i64.const 1) + (i64.const 0) + (i64.ge_s + (local.get $y) + (i64.const 0) + ) + ) + ) + ;; optimize boolean + (drop + (select + (local.get $x) + (i32.const 0) + (i32.eqz + (i32.const 0) + ) + ) + ) + (drop + (select + (local.get $x) + (i32.const 2) + (i32.eqz + (i32.const 2) + ) + ) + ) + (drop + (select + (local.get $x) + (i32.const 2) + (i32.eqz + (i32.eqz + (local.get $x) + ) + ) + ) + ) + (drop + (select + (local.get $y) + (i64.const 0) + (i64.eqz + (i64.const 0) + ) + ) + ) + (drop + (select + (local.get $y) + (i64.const 2) + (i64.eqz + (i64.const 2) + ) + ) + ) + ) + ;; CHECK: (func $optimize-boolean (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.wrap_i64 + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-boolean (param $x i32) (param $y i64) + ;; bool(-x) -> bool(x) + (drop + (select + (i32.const 1) + (i32.const 2) + (i32.sub + (i32.const 0) + (local.get $x) + ) + ) + ) + ;; i32(bool(expr)) == 1 -> bool(expr) + (drop (i32.eq + (i32.and + (local.get $x) + (i32.const 1) + ) + (i32.const 1) + )) + ;; i32(bool(expr)) != 1 -> !bool(expr) + (drop (i32.ne + (i32.and + (local.get $x) + (i32.const 1) + ) + (i32.const 1) + )) + ;; i64(bool(expr)) != 0 -> i32(bool(expr)) + (drop (i64.ne + (i64.shr_u + (local.get $y) + (i64.const 63) + ) + (i64.const 0) + )) + ;; eqz((i32(bool(expr)) != 0) != 0) + (drop (i32.eqz + (i32.ne + (i32.ne + (i32.shr_u + (local.get $x) + (i32.const 31) + ) + (i32.const 0) + ) + (i32.const 0) + ) + )) + ;; i32.eqz(wrap(i64(x))) + (drop (i32.eqz + (i32.wrap_i64 + (i64.shr_u + (local.get $y) + (i64.const 63) + ) + ) + )) + ;; eqz((i64(bool(expr)) != 0) != 0) + (drop (i32.eqz + (i32.ne + (i64.ne + (i64.shr_u + (local.get $y) + (i64.const 63) + ) + (i64.const 0) + ) + (i32.const 0) + ) + )) + ;; eqz((i64(bool(expr)) != 0) != 0) + (drop (i32.eqz + (i32.ne + (i64.ne + (local.get $y) + (i64.const 0) + ) + (i32.const 0) + ) + )) + ;; i32.eqz(wrap(i64(x))) -> skip + (drop (i32.eqz + (i32.wrap_i64 + (local.get $y) + ) + )) + ;; i64(bool(expr)) == 1 -> i32(bool(expr)) + (drop (i64.eq + (i64.and + (local.get $y) + (i64.const 1) + ) + (i64.const 1) + )) + ;; i64(bool(expr)) != 1 -> !i64(bool(expr)) + (drop (i64.ne + (i64.and + (local.get $y) + (i64.const 1) + ) + (i64.const 1) + )) + ;; i32(bool(expr)) & 1 -> bool(expr) + (drop (i32.and + (i32.and + (local.get $x) + (i32.const 1) + ) + (i32.const 1) + )) + ;; i32(bool(expr)) | 1 -> 1 + (drop (i32.or + (i32.and + (local.get $x) + (i32.const 1) + ) + (i32.const 1) + )) + ;; i64(bool(expr)) & 1 -> i64(bool(expr)) + (drop (i64.and + (i64.and + (local.get $y) + (i64.const 1) + ) + (i64.const 1) + )) + ;; i64(bool(expr)) | 1 -> 1 + (drop (i64.or + (i64.and + (local.get $y) + (i64.const 1) + ) + (i64.const 1) + )) + ;; i32(bool(expr)) != 0 -> i32(bool(expr)) + (drop (i32.ne + (i32.and + (local.get $x) + (i32.const 1) + ) + (i32.const 0) + )) + ;; i32(bool(expr)) != 0 -> i32(bool(expr)) + (drop (i32.ne + (i64.ne + (local.get $y) + (i64.const 0) + ) + (i32.const 0) + )) + ;; (i32(expr) != 0) != 0 -> (expr != 0) + (drop (i32.ne + (i32.ne + (local.get $x) + (i32.const 0) + ) + (i32.const 0) + )) + ;; (signed)x % 4 ? 1 : 0 + (drop (if (result i32) + (i32.rem_s + (local.get $x) + (i32.const 4) + ) + (i32.const 1) + (i32.const 0) + )) + ;; (signed)x % min_s ? 1 : 0 + (drop (if (result i32) + (i32.rem_s + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 1) + (i32.const 0) + )) + ) + ;; CHECK: (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rotl + ;; CHECK-NEXT: (i32.const -2) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.rotl + ;; CHECK-NEXT: (i64.const -2) + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64) + ;; ~(1 << x) -> rotl(-2, x) + (drop (i32.xor + (i32.shl + (i32.const 1) + (local.get $x) + ) + (i32.const -1) + )) + (drop (i64.xor + (i64.shl + (i64.const 1) + (local.get $z) + ) + (i64.const -1) + )) + ) + ;; CHECK: (func $getFallthrough + ;; CHECK-NEXT: (local $x0 i32) + ;; CHECK-NEXT: (local $x1 i32) + ;; CHECK-NEXT: (local $x2 i32) + ;; CHECK-NEXT: (local $x3 i32) + ;; CHECK-NEXT: (local $x4 i32) + ;; CHECK-NEXT: (local $x5 i32) + ;; CHECK-NEXT: (local $x6 i32) + ;; CHECK-NEXT: (local $x7 i32) + ;; CHECK-NEXT: (local.set $x0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x1 + ;; CHECK-NEXT: (local.tee $x2 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x3 + ;; CHECK-NEXT: (loop $loop-in (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x4 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x4) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x5 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x6 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $out (result i32) + ;; CHECK-NEXT: (local.set $x7 + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $getFallthrough ;; unit tests for Properties::getFallthrough + (local $x0 i32) + (local $x1 i32) + (local $x2 i32) + (local $x3 i32) + (local $x4 i32) + (local $x5 i32) + (local $x6 i32) + (local $x7 i32) + ;; the trivial case + (local.set $x0 (i32.const 1)) + (drop (i32.and (local.get $x0) (i32.const 7))) + ;; tees + (local.set $x1 (local.tee $x2 (i32.const 1))) + (drop (i32.and (local.get $x1) (i32.const 7))) + ;; loop + (local.set $x3 (loop (result i32) (i32.const 1))) + (drop (i32.and (local.get $x3) (i32.const 7))) + ;; if - two sides, can't + (local.set $x4 (if (result i32) (i32.const 1) (i32.const 2) (i32.const 3))) + (drop (i32.and (local.get $x4) (i32.const 7))) + ;; if - one side, can + (local.set $x5 (if (result i32) (i32.const 1) (unreachable) (i32.const 3))) + (drop (i32.and (local.get $x5) (i32.const 7))) + ;; if - one side, can + (local.set $x6 (if (result i32) (i32.const 1) (i32.const 3) (unreachable))) + (drop (i32.and (local.get $x6) (i32.const 7))) + ;; br_if with value + (drop + (block $out (result i32) + (local.set $x7 (br_if $out (i32.const 1) (i32.const 1))) + (drop (i32.and (local.get $x7) (i32.const 7))) + (unreachable) + ) + ) + ) + ;; CHECK: (func $tee-with-unreachable-value (result f64) + ;; CHECK-NEXT: (local $var$0 i32) + ;; CHECK-NEXT: (block $label$1 (result f64) + ;; CHECK-NEXT: (local.tee $var$0 + ;; CHECK-NEXT: (br_if $label$1 + ;; CHECK-NEXT: (f64.const 1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $tee-with-unreachable-value (result f64) + (local $var$0 i32) + (block $label$1 (result f64) + (local.tee $var$0 + (br_if $label$1 ;; the f64 does not actually flow through this, it's unreachable (and the type is wrong - but unchecked) + (f64.const 1) + (unreachable) + ) + ) + ) + ) + ;; CHECK: (func $add-sub-zero-reorder-1 (param $temp i32) (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.tee $temp + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $add-sub-zero-reorder-1 (param $temp i32) (result i32) + (i32.add + (i32.add + (i32.sub + (i32.const 0) ;; this zero looks like we could remove it by subtracting the get of $temp from the parent, but that would reorder it *after* the tee :( + (local.get $temp) + ) + (local.tee $temp ;; cannot move this tee before the get + (i32.const 1) + ) + ) + (i32.const 2) + ) + ) + ;; CHECK: (func $add-sub-zero-reorder-2 (param $temp i32) (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.tee $temp + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $add-sub-zero-reorder-2 (param $temp i32) (result i32) + (i32.add + (i32.add + (local.tee $temp ;; in this order, the tee already comes first, so all is good for the optimization + (i32.const 1) + ) + (i32.sub + (i32.const 0) + (local.get $temp) + ) + ) + (i32.const 2) + ) + ) + ;; CHECK: (func $const-float-zero (param $fx f32) (param $fy f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.add + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const -0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.add + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.add + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (f32.const -nan:0x34546d) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $const-float-zero (param $fx f32) (param $fy f64) + ;; x - 0.0 ==> x + (drop (f32.sub + (local.get $fx) + (f32.const 0) + )) + (drop (f64.sub + (local.get $fy) + (f64.const 0) + )) + ;; x + (-0.0) ==> x + (drop (f32.add + (local.get $fx) + (f32.const -0) + )) + (drop (f64.add + (local.get $fy) + (f64.const -0) + )) + ;; x - (-0.0) ==> x + 0.0 + (drop (f32.sub + (local.get $fx) + (f32.const -0) ;; skip + )) + (drop (f64.sub + (local.get $fy) + (f64.const -0) ;; skip + )) + ;; 0.0 - x ==> 0.0 - x + (drop (f32.sub + (f32.const 0) + (local.get $fx) ;; skip + )) + (drop (f64.sub + (f64.const 0) + (local.get $fy) ;; skip + )) + ;; x + 0.0 ==> x + 0.0 + (drop (f32.add + (local.get $fx) ;; skip + (f32.const 0) + )) + (drop (f64.add + (local.get $fy) ;; skip + (f64.const 0) + )) + (drop (f32.sub + (f32.const -nan:0x34546d) ;; skip + (f32.const 0) + )) + ) + ;; CHECK: (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.add + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.gt_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_s + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.le_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.le_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (f64.const -0) + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) + (drop (i32.sub + (local.get $x) + (i32.const -1) + )) + (drop (i64.sub + (local.get $y) + (i64.const -1) + )) + ;; (unsigned)x > -1 ==> 0 + (drop (i32.gt_u + (local.get $x) + (i32.const -1) + )) + (drop (i64.gt_u + (local.get $y) + (i64.const -1) + )) + (drop (i32.gt_s + (local.get $x) + (i32.const -1) + )) + (drop (i64.gt_s + (local.get $y) + (i64.const -1) + )) + (drop (i64.extend_i32_s + (i64.gt_u + (i64.const 0) + (i64.const -1) + ) + )) + ;; (unsigned)x <= -1 ==> 1 + (drop (i32.le_u + (local.get $x) + (i32.const -1) + )) + (drop (i64.le_u + (local.get $y) + (i64.const -1) + )) + (drop (i32.le_s + (local.get $x) + (i32.const -1) + )) + (drop (i64.le_s + (local.get $y) + (i64.const -1) + )) + ;; (unsigned)x >= -1 ==> x == -1 + (drop (i32.ge_u + (local.get $x) + (i32.const -1) + )) + (drop (i64.ge_u + (local.get $y) + (i64.const -1) + )) + ;; (unsigned)x < -1 ==> x != -1 + (drop (i32.lt_u + (local.get $x) + (i32.const -1) + )) + (drop (i64.lt_u + (local.get $y) + (i64.const -1) + )) + ;; x * -1 + (drop (i32.mul + (local.get $x) + (i32.const -1) + )) + (drop (i64.mul + (local.get $y) + (i64.const -1) + )) + (drop (f32.mul ;; skip + (local.get $fx) + (f32.const -1) + )) + (drop (f64.mul ;; skip + (local.get $fy) + (f64.const -1) + )) + ;; (unsigned)x / -1 + (drop (i32.div_u + (local.get $x) + (i32.const -1) + )) + (drop (i64.div_u + (local.get $y) + (i64.const -1) + )) + ) + ;; CHECK: (func $rhs-is-const (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -9223372036854775808) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.div_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.extend_i32_u + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 9223372036854775807) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -9223372036854775808) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const -9223372036854775808) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 9223372036854775807) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const 2.1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const -2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $fx) + ;; CHECK-NEXT: (f32.const -inf) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: (f64.const -nan:0x8000000000000) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (f64.const -5) + ;; CHECK-NEXT: (local.get $fy) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $rhs-is-const (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) + ;; signed divs + ;; i32(x) / -2147483648 -> x == -2147483648 + (drop (i32.div_s + (local.get $x) + (i32.const -2147483648) + )) + ;; i64(x) / -9223372036854775808 -> x == -9223372036854775808 + (drop (i64.div_s + (local.get $y) + (i64.const -9223372036854775808) + )) + ;; skip + (drop (i64.div_s + (local.get $y) + (i64.const -2147483648) + )) + + ;; unsigned divs + ;; u32(x) / -2 => x >= -2 + (drop (i32.div_u + (local.get $x) + (i32.const -2) + )) + ;; u32(x) / -1 => x == -1 + (drop (i32.div_u + (local.get $x) + (i32.const -1) + )) + ;; u32(x) / (i32.min + 1) + (drop (i32.div_u + (local.get $x) + (i32.const -2147483647) + )) + ;; u32(x) / i32.min => x >>> 31 + (drop (i32.div_u + (local.get $x) + (i32.const -2147483648) + )) + ;; u64(x) / -1 => u64(x == -1) + (drop (i64.div_u + (local.get $y) + (i64.const -1) + )) + ;; u64(x) / i64.min => x >>> 63 + (drop (i64.div_u + (local.get $y) + (i64.const -9223372036854775808) + )) + + ;; (unsigned)x >= 0 => i32(1) + (drop (i32.ge_u + (local.get $x) + (i32.const 0) + )) + (drop (i64.ge_u + (local.get $y) + (i64.const 0) + )) + + ;; (unsigned)x < 0 => i32(0) + (drop (i32.lt_u + (local.get $x) + (i32.const 0) + )) + (drop (i64.lt_u + (local.get $y) + (i64.const 0) + )) + + ;; (unsigned)x > 0 => x != 0 + (drop (i32.gt_u + (local.get $x) + (i32.const 0) + )) + (drop (i64.gt_u + (local.get $y) + (i64.const 0) + )) + + ;; (unsigned)x <= 0 => x == 0 + (drop (i32.le_u + (local.get $x) + (i32.const 0) + )) + (drop (i64.le_u + (local.get $y) + (i64.const 0) + )) + + ;; i32(x) <= 0x7fffffff => i32(1) + (drop (i32.le_s + (local.get $x) + (i32.const 0x7fffffff) + )) + ;; i64(x) <= 0x7fffffffffffffff => i32(1) + (drop (i64.le_s + (local.get $y) + (i64.const 0x7fffffffffffffff) + )) + + ;; i32(x) >= 0x80000000 => i32(1) + (drop (i32.ge_s + (local.get $x) + (i32.const 0x80000000) + )) + ;; i64(x) >= 0x8000000000000000 => i32(1) + (drop (i64.ge_s + (local.get $y) + (i64.const 0x8000000000000000) + )) + + ;; i32(x) < 0x80000000 => 0 + (drop (i32.lt_s + (local.get $x) + (i32.const 0x80000000) + )) + ;; i64(x) < 0x8000000000000000 => 0 + (drop (i64.lt_s + (local.get $y) + (i64.const 0x8000000000000000) + )) + + ;; i32(x) > 0x7fffffff => 0 + (drop (i32.gt_s + (local.get $x) + (i32.const 0x7fffffff) + )) + ;; i64(x) > 0x7fffffffffffffff => 0 + (drop (i64.gt_s + (local.get $y) + (i64.const 0x7fffffffffffffff) + )) + + ;; i32(x) < 0x7fffffff => x != 0x7fffffff + (drop (i32.lt_s + (local.get $x) + (i32.const 0x7fffffff) + )) + ;; i64(x) < 0x7fffffffffffffff => x != 0x7fffffffffffffff + (drop (i64.lt_s + (local.get $y) + (i64.const 0x7fffffffffffffff) + )) + + ;; i32(x) > 0x80000000 => x != 0x80000000 + (drop (i32.gt_s + (local.get $x) + (i32.const 0x80000000) + )) + ;; i64(x) > 0x8000000000000000 => x != 0x8000000000000000 + (drop (i64.gt_s + (local.get $y) + (i64.const 0x8000000000000000) + )) + + ;; i32(x) <= 0x80000000 => x == 0x80000000 + (drop (i32.le_s + (local.get $x) + (i32.const 0x80000000) + )) + ;; i64(x) <= 0x8000000000000000 => x == 0x8000000000000000 + (drop (i64.le_s + (local.get $y) + (i64.const 0x8000000000000000) + )) + + ;; i32(x) >= 0x7fffffff => x == 0x7fffffff + (drop (i32.ge_s + (local.get $x) + (i32.const 0x7fffffff) + )) + ;; i64(x) >= 0x7fffffffffffffff => x == 0x7fffffffffffffff + (drop (i64.ge_s + (local.get $y) + (i64.const 0x7fffffffffffffff) + )) + + ;; -x * 1 => x * -1 + (drop (f32.mul + (f32.neg + (local.get $fx) + ) + (f32.const 1) + )) + ;; -x * -2.1 => x * 2.1 + (drop (f64.mul + (f64.neg + (local.get $fy) + ) + (f64.const -2.1) + )) + ;; 2 * -x => x * -2 + (drop (f64.mul + (f64.const 2) + (f64.neg + (local.get $fy) + ) + )) + ;; -x / inf => x / -inf + (drop (f32.div + (f32.neg + (local.get $fx) + ) + (f32.const inf) + )) + ;; -x / -0.0 => x / 0.0 + (drop (f64.div + (f64.neg + (local.get $fy) + ) + (f64.const -0.0) + )) + ;; -x / nan => x / -nan + (drop (f64.div + (f64.neg + (local.get $fy) + ) + (f64.const nan) + )) + ;; 5.0 / -x => -5 / x + (drop (f64.div + (f64.const 5) + (f64.neg + (local.get $fy) + ) + )) + ) + ;; CHECK: (func $lhs-is-neg-one (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $lhs-is-neg-one (param $x i32) (param $y i64) + ;; -1 >> x ==> -1 + (drop (i32.shr_s + (i32.const -1) + (local.get $x) + )) + (drop (i64.shr_s + (i64.const -1) + (local.get $y) + )) + ;; rotl(-1, x) ==> -1 + (drop (i32.rotl + (i32.const -1) + (local.get $x) + )) + (drop (i64.rotl + (i64.const -1) + (local.get $y) + )) + ;; rotr(-1, x) ==> -1 + (drop (i32.rotr + (i32.const -1) + (local.get $x) + )) + (drop (i64.rotr + (i64.const -1) + (local.get $y) + )) + ;; skip + (drop (i32.shr_s + (i32.const -1) + (call $ne0) ;; side effect + )) + ;; skip + (drop (i32.shr_u + (i32.const -1) + (local.get $x) + )) + ) + ;; CHECK: (func $lhs-is-const (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (i32.const -2) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (i64.const -2) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $lhs-is-const (param $x i32) (param $y i64) + ;; 0 - (x - 1) + (drop (i32.sub + (i32.const 0) + (i32.sub + (local.get $x) + (i32.const 1) + ) + )) + (drop (i64.sub + (i64.const 0) + (i64.sub + (local.get $y) + (i64.const 1) + ) + )) + ;; -1 - (x + 1) + (drop (i32.sub + (i32.const -1) + (i32.add + (local.get $x) + (i32.const 1) + ) + )) + (drop (i64.sub + (i64.const -1) + (i64.add + (local.get $y) + (i64.const 1) + ) + )) + ;; 1 - (2 - x) + (drop (i32.sub + (i32.const 1) + (i32.sub + (i32.const 2) + (local.get $x) + ) + )) + (drop (i64.sub + (i64.const 1) + (i64.sub + (i64.const 2) + (local.get $y) + ) + )) + ;; 0 - (0x80000000 - x) + (drop (i32.sub + (i32.const 0) + (i32.sub + (i32.const 0x80000000) + (local.get $x) + ) + )) + ) + ;; CHECK: (func $pre-combine-or (param $x i32) (param $y i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $pre-combine-or (param $x i32) (param $y i32) + (drop (i32.or + (i32.gt_s + (local.get $x) + (local.get $y) + ) + (i32.eq + (local.get $y) ;; ordering should not stop us + (local.get $x) + ) + )) + (drop (i32.or + (i32.eq ;; ordering should not stop us + (local.get $y) + (local.get $x) + ) + (i32.gt_s + (local.get $x) + (local.get $y) + ) + )) + (drop (i32.or + (i32.gt_s + (local.get $x) + (local.get $y) + ) + (i32.eq + (local.get $x) + (i32.const 1) ;; not equal + ) + )) + (drop (i32.or + (i32.gt_s + (local.get $x) + (i32.const 1) ;; not equal + ) + (i32.eq + (local.get $x) + (local.get $y) + ) + )) + (drop (i32.or + (i32.gt_s + (call $ne0) ;; side effects + (local.get $y) + ) + (i32.eq + (call $ne0) + (local.get $y) + ) + )) + (drop (i32.or + (i32.gt_s + (local.get $y) + (call $ne0) ;; side effects + ) + (i32.eq + (local.get $y) + (call $ne0) + ) + )) + ) + ;; CHECK: (func $combine-or (param $x i32) (param $y i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $combine-or (param $x i32) (param $y i32) + (drop (i32.or + (i32.gt_s + (local.get $x) + (local.get $y) + ) + (i32.eq + (local.get $x) + (local.get $y) + ) + )) + ;; TODO: more stuff here + ) + ;; CHECK: (func $select-into-arms (param $x i32) (param $y i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $select-into-arms (param $x i32) (param $y i32) + (if + (select + (i32.eqz (i32.eqz (local.get $x))) + (i32.eqz (i32.eqz (local.get $y))) + (local.get $y) + ) + (unreachable) + ) + ) + ;; CHECK: (func $optimize-boolean-context (param $x i32) (param $y i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-boolean-context (param $x i32) (param $y i32) + ;; 0 - x ==> x + (if + (i32.sub + (i32.const 0) + (local.get $x) + ) + (unreachable) + ) + (drop (select + (local.get $x) + (local.get $y) + (i32.sub + (i32.const 0) + (local.get $x) + ) + )) + ) + ;; CHECK: (func $optimize-relationals (param $x i32) (param $y i32) (param $X i64) (param $Y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $X) + ;; CHECK-NEXT: (local.get $Y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eq + ;; CHECK-NEXT: (local.get $X) + ;; CHECK-NEXT: (local.get $Y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.ne + ;; CHECK-NEXT: (local.get $X) + ;; CHECK-NEXT: (local.get $Y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.le_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.lt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (block $block (result i32) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (block $block29 (result i32) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-relationals (param $x i32) (param $y i32) (param $X i64) (param $Y i64) + ;; eqz(x + 0x7FFFFFFF) -> x == -2147483647 + (drop (i32.eqz + (i32.add + (local.get $x) + (i32.const 0x7FFFFFFF) + ) + )) + ;; eqz(x + 0x80000000) -> x == -2147483648 + (drop (i32.eqz + (i32.add + (local.get $x) + (i32.const 0x80000000) + ) + )) + ;; eqz(x + 0x80000001) -> x == 2147483647 + (drop (i32.eqz + (i32.add + (local.get $x) + (i32.const 0x80000001) + ) + )) + ;; eqz(x - y) + (drop (i32.eqz + (i32.sub + (local.get $x) + (local.get $y) + ) + )) + (drop (i64.eqz + (i64.sub + (local.get $X) + (local.get $Y) + ) + )) + ;; x - y == 0 + (drop (i32.eq + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + (drop (i64.eq + (i64.sub + (local.get $X) + (local.get $Y) + ) + (i64.const 0) + )) + ;; x - y != 0 + (drop (i32.ne + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + (drop (i64.ne + (i64.sub + (local.get $X) + (local.get $Y) + ) + (i64.const 0) + )) + ;; i32(x - y) > 0 -> x > y + (drop (i32.gt_s + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; i32(x - y) >= 0 -> x >= y + (drop (i32.ge_s + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; u32(x - y) > 0 -> x != y + (drop (i32.gt_u + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; u32(x - y) >= 0 -> 1 + (drop (i32.ge_u + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; u64(x - y) >= 0 -> i32(1) + (drop (i64.ge_u + (i64.sub + (local.get $X) + (local.get $Y) + ) + (i64.const 0) + )) + ;; i32(x - y) < 0 -> x < y + (drop (i32.lt_s + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; i32(x - y) <= 0 -> x <= y + (drop (i32.le_s + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; u32(x - y) < 0 -> 0 + (drop (i32.lt_u + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; u64(x - y) < 0 -> i32(0) + (drop (i64.lt_u + (i64.sub + (local.get $X) + (local.get $Y) + ) + (i64.const 0) + )) + ;; u32(x - y) <= 0 -> x == y + (drop (i32.le_u + (i32.sub + (local.get $x) + (local.get $y) + ) + (i32.const 0) + )) + ;; i32(x - 0x80000000) == 0 -> x == 0x80000000 + (drop (i32.eq + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - 0x80000000) != 0 -> x == 0x80000000 + (drop (i32.ne + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) < 0 -> skip + (drop (i32.lt_s + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) >= 0 -> skip + (drop (i32.ge_s + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) > 0 -> skip + (drop (i32.gt_s + (i32.sub + (local.get $x) + (block (result i32) + (i32.const 0x80000000) + ) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) <= 0 -> skip + (drop (i32.gt_s + (i32.sub + (local.get $x) + (block (result i32) + (i32.const 0x80000000) + ) + ) + (i32.const 0) + )) + ) + ;; CHECK: (func $unsigned-context (param $x i32) (param $y i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.div_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.div_s + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -2147483648) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 9223372036854775807) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.div_s + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i64.const 9223372036854775807) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i64.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_u + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2147483647) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unsigned-context (param $x i32) (param $y i64) + (drop (i32.div_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const 3) + )) + (drop (i32.div_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const -3) ;; skip + )) + (drop (i32.div_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const 0x80000000) ;; skip + )) + (drop (i64.div_s + (i64.and + (local.get $y) + (i64.const 0x7fffffffffffffff) + ) + (i64.const 2) + )) + (drop (i64.div_s + (i64.and + (local.get $y) + (i64.const 0x7fffffffffffffff) + ) + (i64.const -1) ;; skip + )) + (drop (i32.rem_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const 3) + )) + (drop (i32.shr_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const 7) + )) + (drop (i32.ge_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const 7) + )) + (drop (i32.ge_s + (i32.and + (local.get $x) + (i32.const 0x7fffffff) + ) + (i32.const -7) ;; skip + )) + ) + ;; CHECK: (func $optimize-float-mul-by-two (param $0 f64) (param $1 f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (call $tee-with-unreachable-value) + ;; CHECK-NEXT: (f64.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (f64.const -2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-float-mul-by-two (param $0 f64) (param $1 f32) + (drop (f64.mul + (local.get $0) + (f64.const 2) + )) + (drop (f32.mul + (local.get $1) + (f32.const 2) + )) + + (drop (f64.mul + (call $tee-with-unreachable-value) ;; side effect + (f64.const 2) + )) + (drop (f64.mul + (f64.neg (local.get $0)) ;; complex expression + (f64.const 2) + )) + ) + ;; CHECK: (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.ceil + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.floor + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.trunc + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.nearest + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.nearest + ;; CHECK-NEXT: (f64.trunc + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.trunc + ;; CHECK-NEXT: (f64.nearest + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.neg + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.eqz + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.ne + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (call $ne0) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (i32.rem_s + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: (i32.rem_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (i32.or + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) + ;; unary + (drop (f64.abs (f64.abs (local.get $w)))) + (drop (f64.ceil (f64.ceil (local.get $w)))) + (drop (f64.floor (f64.floor (local.get $w)))) + (drop (f64.trunc (f64.trunc (local.get $w)))) + (drop (f64.nearest (f64.nearest (local.get $w)))) + + (drop (f64.nearest (f64.trunc (local.get $w)))) ;; skip + (drop (f64.trunc (f64.nearest (local.get $w)))) ;; skip + + (drop (f64.neg (f64.neg (local.get $w)))) + (drop (f64.neg (f64.neg (f64.neg (local.get $w))))) + (drop (f64.neg (f64.neg (f64.neg (f64.neg (local.get $w)))))) + + (drop (i32.eqz (i32.eqz (local.get $x)))) ;; skip + (drop (i32.eqz (i32.eqz (i32.eqz (local.get $x))))) + (drop (i32.eqz (i32.eqz (i64.eqz (i64.const 1))))) + (drop (i32.eqz (i32.eqz (i32.ne (local.get $x) (i32.const 2))))) + + (drop (i32.eqz + (i32.eqz + (i32.and + (local.get $x) + (i32.const 1) + ) + ) + )) + + ;; binary + ;; ((signed)x % y) % y + (drop (i32.rem_s + (i32.rem_s + (local.get $x) + (local.get $y) + ) + (local.get $y) + )) + ;; ((unsigned)x % y) % y + (drop (i32.rem_u + (i32.rem_u + (local.get $x) + (local.get $y) + ) + (local.get $y) + )) + ;; 0 - (0 - y) + (drop (i32.sub + (i32.const 0) + (i32.sub + (i32.const 0) + (local.get $y) + ) + )) + ;; x - (x - y) + (drop (i32.sub + (local.get $x) + (i32.sub + (local.get $x) + (local.get $y) + ) + )) + ;; y - (x - y) - skip + (drop (i32.sub + (local.get $y) + (i32.sub + (local.get $x) + (local.get $y) + ) + )) + ;; x ^ (x ^ y) + (drop (i32.xor + (local.get $x) + (i32.xor + (local.get $x) + (local.get $y) + ) + )) + ;; x ^ (y ^ x) + (drop (i32.xor + (local.get $x) + (i32.xor + (local.get $y) + (local.get $x) + ) + )) + ;; (x ^ y) ^ x + (drop (i32.xor + (i32.xor + (local.get $x) + (local.get $y) + ) + (local.get $x) + )) + ;; (y ^ x) ^ x + (drop (i32.xor + (i32.xor + (local.get $y) + (local.get $x) + ) + (local.get $x) + )) + ;; x ^ (x ^ x) + (drop (i32.xor + (local.get $x) + (i32.xor + (local.get $x) + (local.get $x) + ) + )) + ;; x & (x & y) + (drop (i32.and + (local.get $x) + (i32.and + (local.get $x) + (local.get $y) + ) + )) + ;; x & (y & x) + (drop (i32.and + (local.get $x) + (i32.and + (local.get $y) + (local.get $x) + ) + )) + ;; (x & y) & x + (drop (i32.and + (i32.and + (local.get $x) + (local.get $y) + ) + (local.get $x) + )) + ;; (y & x) & x + (drop (i32.and + (i32.and + (local.get $y) + (local.get $x) + ) + (local.get $x) + )) + ;; x | (x | y) + (drop (i32.or + (local.get $x) + (i32.or + (local.get $x) + (local.get $y) + ) + )) + ;; x | (y | x) + (drop (i32.or + (local.get $x) + (i32.or + (local.get $y) + (local.get $x) + ) + )) + ;; (x | y) | x + (drop (i32.or + (i32.or + (local.get $x) + (local.get $y) + ) + (local.get $x) + )) + ;; (y | x) | x + (drop (i32.or + (i32.or + (local.get $y) + (local.get $x) + ) + (local.get $x) + )) + ;; (y | x) | z - skip + (drop (i32.or + (i32.or + (local.get $y) + (local.get $x) + ) + (local.get $z) + )) + ;; (z | x) | y - skip + (drop (i32.or + (i32.or + (local.get $z) + (local.get $x) + ) + (local.get $y) + )) + ;; (SE() | x) | x + (drop (i32.or + (i32.or + (call $ne0) ;; side effect + (local.get $x) + ) + (local.get $x) + )) + ;; (x | SE()) | SE() - skip + (drop (i32.or + (i32.or + (local.get $x) + (call $ne0) ;; side effect + ) + (call $ne0) ;; side effect + )) + ;; x | (SE() | x) + (drop (i32.or + (local.get $x) + (i32.or + (local.get $x) + (call $ne0) ;; side effect + ) + )) + ;; SE() | (x | SE()) - skip + (drop (i32.or + (call $ne0) ;; side effect + (i32.or + (call $ne0) ;; side effect + (local.get $x) + ) + )) + ;; (y % x) % y - skip + (drop (i32.rem_s + (i32.rem_s + (local.get $y) + (local.get $x) + ) + (local.get $y) + )) + ;; y % (x % y) - skip + (drop (i32.rem_u + (local.get $y) + (i32.rem_u + (local.get $x) + (local.get $y) + ) + )) + ;; x | (y | x) where x and y cannot be reordered - skip + (drop + (i32.or + (local.get $x) + (i32.or + (local.tee $x + (i32.const 1) + ) + (local.get $x) + ) + ) + ) + (drop + (i32.or + (i32.or + (local.get $x) + (local.tee $x + (i32.const 1) + ) + ) + (local.get $x) + ) + ) + ;; x ^ (y ^ x) where x and y cannot be reordered - skip + (drop + (i32.xor + (local.get $x) + (i32.xor + (local.tee $x + (i32.const 1) + ) + (local.get $x) + ) + ) + ) + (drop + (i32.xor + (i32.xor + (local.get $x) + (local.tee $x + (i32.const 1) + ) + ) + (local.get $x) + ) + ) + ) + ;; CHECK: (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.shr_u + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shl + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shl + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shr_s + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shl + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: (i64.const 32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i64.shr_u + ;; CHECK-NEXT: (local.get $z) + ;; CHECK-NEXT: (i64.and + ;; CHECK-NEXT: (local.get $w) + ;; CHECK-NEXT: (i64.const 31) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64) + ;; i32 + (drop (i32.shl + (local.get $x) + (i32.const 32) + )) + (drop (i32.shr_s + (local.get $x) + (i32.const 32) + )) + (drop (i32.shr_u + (local.get $x) + (i32.const 64) + )) + (drop (i32.rotl + (local.get $x) + (i32.const 64) + )) + (drop (i32.rotr + (local.get $x) + (i32.const 64) + )) + ;; i64 + (drop (i64.shl + (local.get $z) + (i64.const 64) + )) + (drop (i64.shr_s + (local.get $z) + (i64.const 64) + )) + (drop (i64.shr_u + (local.get $z) + (i64.const 128) + )) + (drop (i64.rotl + (local.get $z) + (i64.const 128) + )) + (drop (i64.rotr + (local.get $z) + (i64.const 128) + )) + + ;; i32 + (drop (i32.shl + (local.get $x) + (i32.and + (local.get $y) + (i32.const 31) + ) + )) + (drop (i32.shl + (local.get $x) + (i32.and + (local.get $y) + (i32.const 63) + ) + )) + (drop (i32.shr_s + (local.get $x) + (i32.and + (local.get $y) + (i32.const 31) + ) + )) + (drop (i32.shr_u + (local.get $x) + (i32.and + (local.get $y) + (i32.const 31) + ) + )) + ;; i64 + (drop (i64.shl + (local.get $z) + (i64.and + (local.get $w) + (i64.const 63) + ) + )) + (drop (i64.shl + (local.get $z) + (i64.and + (local.get $w) + (i64.const 127) + ) + )) + (drop (i64.shr_s + (local.get $z) + (i64.and + (local.get $w) + (i64.const 63) + ) + )) + (drop (i64.shr_u + (local.get $z) + (i64.and + (local.get $w) + (i64.const 63) + ) + )) + ;; i32(x) >> (y & 32) -> x + (drop (i32.shr_u + (local.get $x) + (i32.and + (local.get $y) + (i32.const 32) + ) + )) + ;; i64(x) >> (y & 64) -> x + (drop (i64.shr_u + (local.get $z) + (i64.and + (local.get $w) + (i64.const 128) + ) + )) + + ;; skip + (drop (i64.shl + (local.get $z) + (i64.and + (local.get $w) + (i64.const 32) + ) + )) + ;; skip + (drop (i64.shr_u + (local.get $z) + (i64.and + (local.get $w) + (i64.const 31) + ) + )) + ) + ;; CHECK: (func $optimize-float-points (param $x0 f64) (param $x1 f64) (param $y0 f32) (param $y1 f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $y1) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.sub + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (f32.sub + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $y1) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.mul + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.mul + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.abs + ;; CHECK-NEXT: (f32.div + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: (local.get $y0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.abs + ;; CHECK-NEXT: (f64.div + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.add + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: (local.get $x0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $optimize-float-points (param $x0 f64) (param $x1 f64) (param $y0 f32) (param $y1 f32) + ;; abs(x) * abs(x) ==> x * x + (drop (f64.mul + (f64.abs (local.get $x0)) + (f64.abs (local.get $x0)) + )) + (drop (f32.mul + (f32.abs (local.get $y0)) + (f32.abs (local.get $y0)) + )) + (drop (f64.mul + (f64.abs (f64.add (local.get $x0) (local.get $x1))) + (f64.abs (f64.add (local.get $x0) (local.get $x1))) + )) + + ;; abs(x) * abs(y) ==> abs(x * y) + (drop (f64.mul + (f64.abs (local.get $x0)) + (f64.abs (local.get $x1)) + )) + (drop (f32.mul + (f32.abs (local.get $y1)) + (f32.abs (local.get $y0)) + )) + + (drop (f64.mul + (f64.abs (local.get $x0)) + (f64.abs (f64.const 0)) ;; skip + )) + (drop (f32.mul + (f32.abs (f32.const 0)) ;; skip + (f32.abs (local.get $y0)) + )) + (drop (f64.mul + (f64.abs (f64.add (local.get $x0) (local.get $x1))) + (f64.abs (f64.add (local.get $x0) (local.get $x0))) + )) + + + ;; abs(-x) ==> abs(x) + (drop (f64.abs + (f64.neg (local.get $x0)) + )) + (drop (f32.abs + (f32.neg (local.get $y0)) + )) + + ;; abs(0 - x) ==> skip for non-fast math + (drop (f64.abs + (f64.sub + (f64.const 0) + (local.get $x0) + ) + )) + (drop (f32.abs + (f32.sub + (f32.const 0) + (local.get $y0) + ) + )) + + ;; abs(x) / abs(x) ==> x / x + (drop (f64.div + (f64.abs (local.get $x0)) + (f64.abs (local.get $x0)) + )) + (drop (f32.div + (f32.abs (local.get $y0)) + (f32.abs (local.get $y0)) + )) + (drop (f64.div + (f64.abs (f64.add (local.get $x0) (local.get $x1))) + (f64.abs (f64.add (local.get $x0) (local.get $x1))) + )) + + ;; abs(x) / abs(y) ==> abs(x / y) + (drop (f64.div + (f64.abs (local.get $x0)) + (f64.abs (local.get $x1)) + )) + (drop (f32.div + (f32.abs (local.get $y1)) + (f32.abs (local.get $y0)) + )) + + ;; abs(x * x) ==> x * x + (drop (f64.abs + (f64.mul + (local.get $x0) + (local.get $x0) + ) + )) + (drop (f32.abs + (f32.mul + (local.get $y0) + (local.get $y0) + ) + )) + + ;; abs(x / x) ==> x / x + (drop (f64.abs + (f64.div + (local.get $x0) + (local.get $x0) + ) + )) + (drop (f32.abs + (f32.div + (local.get $y0) + (local.get $y0) + ) + )) + + (drop (f64.div + (f64.abs (local.get $x0)) + (f64.abs (f64.const 0)) ;; skip + )) + (drop (f32.div + (f32.abs (f32.const 0)) ;; skip + (f32.abs (local.get $y0)) + )) + (drop (f64.div + (f64.abs (f64.add (local.get $x0) (local.get $x1))) + (f64.abs (f64.add (local.get $x0) (local.get $x0))) + )) + ) +) diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt deleted file mode 100644 index df60ebfaa..000000000 --- a/test/passes/optimize-instructions_all-features.txt +++ /dev/null @@ -1,5704 +0,0 @@ -(module - (type $i32_i32_=>_none (func (param i32 i32))) - (type $none_=>_i32 (func (result i32))) - (type $i32_=>_i32 (func (param i32) (result i32))) - (type $i32_i64_=>_none (func (param i32 i64))) - (type $none_=>_none (func)) - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) - (type $i32_=>_none (func (param i32))) - (type $i32_i32_i64_i64_=>_none (func (param i32 i32 i64 i64))) - (type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64))) - (type $none_=>_i64 (func (result i64))) - (type $i64_=>_i64 (func (param i64) (result i64))) - (type $i32_i64_f32_=>_none (func (param i32 i64 f32))) - (type $f32_=>_none (func (param f32))) - (type $f64_=>_none (func (param f64))) - (type $i32_i32_i32_f64_=>_none (func (param i32 i32 i32 f64))) - (type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64))) - (type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32))) - (type $f32_f64_=>_none (func (param f32 f64))) - (type $f64_f32_=>_none (func (param f64 f32))) - (type $f64_f64_f32_f32_=>_none (func (param f64 f64 f32 f32))) - (type $none_=>_f64 (func (result f64))) - (memory $0 0) - (export "load-off-2" (func $load-off-2)) - (func $f (param $i1 i32) (param $i2 i64) - (drop - (i32.and - (local.get $i1) - (i32.const 1) - ) - ) - (drop - (i32.or - (local.get $i1) - (i32.const 3) - ) - ) - (drop - (i32.xor - (local.get $i1) - (i32.const 5) - ) - ) - (drop - (i32.mul - (local.get $i1) - (i32.const -10) - ) - ) - (drop - (i32.mul - (local.get $i1) - (i32.const -133169153) - ) - ) - (if - (i32.eqz - (local.get $i1) - ) - (drop - (i32.const 10) - ) - ) - (if - (local.get $i1) - (drop - (i32.const 12) - ) - (drop - (i32.const 11) - ) - ) - (if - (i64.eqz - (local.get $i2) - ) - (drop - (i32.const 11) - ) - (drop - (i32.const 12) - ) - ) - (drop - (i32.le_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.lt_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.ge_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.gt_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.le_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.lt_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.ge_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.gt_u - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.eqz - (f32.gt - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.ge - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.lt - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.le - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.gt - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.ge - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.lt - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.le - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (f32.ne - (f32.const 1) - (f32.const 2) - ) - ) - (drop - (f32.eq - (f32.const 1) - (f32.const 2) - ) - ) - (drop - (f64.ne - (f64.const 1) - (f64.const 2) - ) - ) - (drop - (f64.eq - (f64.const 1) - (f64.const 2) - ) - ) - (drop - (i32.eqz - (i32.const 100) - ) - ) - (drop - (i32.eq - (i32.const 0) - (i32.const 100) - ) - ) - (drop - (i32.eqz - (i32.const 0) - ) - ) - (drop - (i64.eqz - (i64.const 100) - ) - ) - (drop - (i64.eq - (i64.const 0) - (i64.const 100) - ) - ) - (drop - (i64.eqz - (i64.const 0) - ) - ) - (if - (i32.const 123) - (nop) - ) - (drop - (select - (i32.const 102) - (i32.const 101) - (local.get $i1) - ) - ) - (drop - (select - (local.tee $i1 - (i32.const 103) - ) - (local.tee $i1 - (i32.const 104) - ) - (i32.eqz - (local.get $i1) - ) - ) - ) - (drop - (i32.const 0) - ) - ) - (func $load-store - (drop - (i32.load8_u - (i32.const 0) - ) - ) - (drop - (i32.load8_u - (i32.const 1) - ) - ) - (drop - (i32.and - (i32.load8_s - (i32.const 2) - ) - (i32.const 254) - ) - ) - (drop - (i32.and - (i32.load8_u - (i32.const 3) - ) - (i32.const 1) - ) - ) - (drop - (i32.load16_u - (i32.const 4) - ) - ) - (drop - (i32.load16_u - (i32.const 5) - ) - ) - (drop - (i32.and - (i32.load16_s - (i32.const 6) - ) - (i32.const 65534) - ) - ) - (drop - (i32.and - (i32.load16_u - (i32.const 7) - ) - (i32.const 1) - ) - ) - (i32.store8 - (i32.const 8) - (i32.const -1) - ) - (i32.store8 - (i32.const 9) - (i32.and - (i32.const -2) - (i32.const 254) - ) - ) - (i32.store16 - (i32.const 10) - (i32.const -3) - ) - (i32.store16 - (i32.const 11) - (i32.and - (i32.const -4) - (i32.const 65534) - ) - ) - (i64.store8 - (i32.const 11) - (i64.const 1) - ) - (i64.store16 - (i32.const 11) - (i64.const 2) - ) - (i64.store32 - (i32.const 11) - (i64.const 3) - ) - (i32.store8 - (i32.const 7) - (i32.const 255) - ) - (i32.store8 - (i32.const 8) - (i32.const 255) - ) - (i32.store8 - (i32.const 9) - (i32.const 0) - ) - (i32.store16 - (i32.const 10) - (i32.const 65535) - ) - (i32.store16 - (i32.const 11) - (i32.const 0) - ) - (i32.store16 - (i32.const 13) - (i32.const 65535) - ) - (i32.store - (i32.const 14) - (i32.const 65536) - ) - (i64.store8 - (i32.const 8) - (i64.const 255) - ) - (i64.store8 - (i32.const 9) - (i64.const 0) - ) - (i64.store16 - (i32.const 10) - (i64.const 65535) - ) - (i64.store16 - (i32.const 11) - (i64.const 0) - ) - (i64.store32 - (i32.const 12) - (i64.const 4294967295) - ) - (i64.store32 - (i32.const 13) - (i64.const 0) - ) - (i64.store - (i32.const 14) - (i64.const 4294967296) - ) - ) - (func $and-neg1 - (drop - (i32.const 100) - ) - (drop - (i32.and - (i32.const 100) - (i32.const 1) - ) - ) - ) - (func $and-pos1 - (drop - (i32.eqz - (i32.const 1000) - ) - ) - (drop - (i32.eqz - (i32.const 1000) - ) - ) - (drop - (i32.and - (i32.const 100) - (i32.const 1) - ) - ) - (drop - (i32.lt_u - (i32.const 2000) - (i32.const 3000) - ) - ) - ) - (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64) - (drop - (i32.and - (unreachable) - (i32.const 1) - ) - ) - (drop - (i32.and - (i32.const 1) - (unreachable) - ) - ) - (drop - (i32.div_s - (unreachable) - (i32.const 1) - ) - ) - (drop - (i32.div_s - (i32.const 1) - (unreachable) - ) - ) - (drop - (i32.and - (i32.const 1) - (i32.const 2) - ) - ) - (drop - (i32.and - (local.get $x) - (i32.const 3) - ) - ) - (drop - (i32.and - (local.get $x) - (i32.const 4) - ) - ) - (drop - (i32.and - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.and - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.and - (local.tee $x - (i32.const -4) - ) - (local.get $y) - ) - ) - (drop - (i32.and - (block $block (result i32) - (i32.const -5) - ) - (local.get $x) - ) - ) - (drop - (i32.and - (block $block3 (result i32) - (i32.const -6) - ) - (local.get $x) - ) - ) - (drop - (i32.and - (block $block4 (result i32) - (i32.const 5) - ) - (loop $loop-in (result i32) - (i32.const 6) - ) - ) - ) - (drop - (i32.and - (block $block6 (result i32) - (i32.const 8) - ) - (loop $loop-in5 (result i32) - (i32.const 7) - ) - ) - ) - (drop - (i32.and - (block $block8 (result i32) - (i32.const 10) - ) - (loop $loop-in7 (result i32) - (call $and-pos1) - (i32.const 9) - ) - ) - ) - (drop - (i32.and - (block $block10 (result i32) - (call $and-pos1) - (i32.const 12) - ) - (loop $loop-in9 (result i32) - (i32.const 11) - ) - ) - ) - (drop - (i32.and - (loop $loop-in11 (result i32) - (call $and-pos1) - (i32.const 13) - ) - (block $block12 (result i32) - (call $and-pos1) - (i32.const 14) - ) - ) - ) - (drop - (i32.and - (block $block13 (result i32) - (call $and-pos1) - (i32.const 14) - ) - (loop $loop-in14 (result i32) - (call $and-pos1) - (i32.const 13) - ) - ) - ) - (drop - (i32.and - (block $block15 (result i32) - (i32.const 15) - ) - (local.get $x) - ) - ) - (drop - (i32.and - (block $block16 (result i32) - (i32.const 15) - ) - (local.get $x) - ) - ) - (drop - (i32.and - (i32.gt_u - (i32.const 16) - (i32.const 17) - ) - (i32.gt_u - (i32.const 18) - (i32.const 19) - ) - ) - ) - (drop - (i32.and - (i32.gt_u - (i32.const 20) - (i32.const 21) - ) - (i32.gt_u - (i32.const 22) - (i32.const 23) - ) - ) - ) - (drop - (i32.lt_s - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i32.const 0) - ) - (drop - (i32.ne - (local.get $x) - (i32.const -1) - ) - ) - (drop - (f64.ne - (local.get $fx) - (f64.const -1) - ) - ) - (drop - (f64.gt - (local.get $fx) - (f64.const -2) - ) - ) - (drop - (f64.le - (local.get $fx) - (f64.const inf) - ) - ) - (drop - (f64.ge - (local.get $fx) - (f64.const nan:0x8000000000000) - ) - ) - (drop - (f64.ge - (f64.const 1) - (f64.const 2) - ) - ) - (drop - (i32.add - (i32.ctz - (local.get $x) - ) - (i32.ctz - (local.get $y) - ) - ) - ) - (drop - (i32.add - (i32.ctz - (local.get $y) - ) - (i32.ctz - (local.get $x) - ) - ) - ) - (drop - (i32.add - (i32.ctz - (local.get $x) - ) - (i32.eqz - (local.get $y) - ) - ) - ) - (drop - (i32.add - (i32.ctz - (local.get $y) - ) - (i32.eqz - (local.get $x) - ) - ) - ) - ) - (func $ne0 (result i32) - (if - (call $ne0) - (nop) - ) - (if - (call $ne0) - (nop) - ) - (if - (i32.or - (call $ne0) - (call $ne0) - ) - (nop) - ) - (if - (i32.and - (i32.ne - (call $ne0) - (i32.const 0) - ) - (i32.ne - (call $ne0) - (i32.const 0) - ) - ) - (nop) - ) - (i32.const 1) - ) - (func $recurse-bool - (if - (if (result i32) - (i32.const 1) - (call $ne0) - (call $ne1) - ) - (nop) - ) - (if - (block $block (result i32) - (nop) - (call $ne0) - ) - (nop) - ) - ) - (func $ne1 (result i32) - (unreachable) - ) - (func $load-off-2 (param $0 i32) (result i32) - (i32.store - (i32.const 6) - (local.get $0) - ) - (i32.store - (i32.const 6) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (local.get $0) - (i32.const 7) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.sub - (local.get $0) - (i32.const 11) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.sub - (local.get $0) - (i32.const 13) - ) - (local.get $0) - ) - (i32.store - (i32.const 4) - (local.get $0) - ) - (i32.store offset=2 - (i32.const -2) - (local.get $0) - ) - (i32.store - (i32.const 25) - (local.get $0) - ) - (i32.store offset=2 - (i32.const -25) - (local.get $0) - ) - (drop - (i32.load - (i32.const 8) - ) - ) - (drop - (i32.load - (i32.const 8) - ) - ) - (drop - (i32.load offset=2 - (i32.add - (local.get $0) - (i32.const 6) - ) - ) - ) - (drop - (i32.load - (i32.const 10) - ) - ) - (i32.load offset=2 - (i32.add - (local.get $0) - (i32.const 10) - ) - ) - ) - (func $sign-ext (param $0 i32) (param $1 i32) - (drop - (i32.eqz - (i32.and - (local.get $0) - (i32.const 255) - ) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $0) - (i32.const 65535) - ) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $0) - (i32.const 134217727) - ) - ) - ) - (drop - (i32.eq - (i32.and - (local.get $0) - (i32.const 255) - ) - (i32.const 100) - ) - ) - (drop - (block (result i32) - (drop - (local.get $0) - ) - (i32.const 0) - ) - ) - (drop - (block (result i32) - (drop - (local.get $0) - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.and - (local.get $0) - (i32.const 255) - ) - (i32.and - (local.get $1) - (i32.const 255) - ) - ) - ) - (drop - (i32.eq - (i32.and - (local.get $0) - (i32.const 65535) - ) - (i32.and - (local.get $1) - (i32.const 65535) - ) - ) - ) - (drop - (i32.eqz - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 23) - ) - ) - ) - (drop - (i32.eqz - (i32.shr_u - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (drop - (i32.lt_s - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 0) - ) - ) - (drop - (if (result i32) - (i32.shr_s - (i32.shl - (unreachable) - (i32.const 16) - ) - (i32.const 16) - ) - (i32.const 111) - (i32.const 222) - ) - ) - ) - (func $sign-ext-input (param $0 i32) (param $1 i32) - (drop - (i32.const 100) - ) - (drop - (i32.const 127) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const 128) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (unreachable) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.const 1) - (i32.const 1) - ) - ) - (drop - (i32.and - (i32.const 127) - (i32.const 128) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.and - (i32.const 128) - (i32.const 129) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.xor - (i32.const 127) - (i32.const 126) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.xor - (i32.const 127) - (i32.const 128) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.or - (i32.const 127) - (i32.const 126) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.or - (i32.const 127) - (i32.const 128) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const 32) - (i32.const 26) - ) - (i32.const 24) - ) - ) - (drop - (i32.shl - (i32.const 32) - (i32.const 1) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const 32) - (i32.const 27) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.const 256) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.const 256) - (i32.const 2) - ) - ) - (drop - (i32.shr_u - (i32.const 128) - (i32.const 3) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.const 256) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.const 256) - (i32.const 2) - ) - ) - (drop - (i32.shr_u - (i32.const 128) - (i32.const 3) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const -1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.and - (i32.const -1) - (i32.const 2147483647) - ) - (i32.const 31) - ) - ) - (drop - (i32.const 0) - ) - (drop - (f32.le - (f32.const -1) - (f32.const -1) - ) - ) - (drop - (i32.clz - (i32.const 0) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.clz - (i32.const 0) - ) - (i32.const 26) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.clz - (i32.const 0) - ) - (i32.const 27) - ) - (i32.const 24) - ) - ) - (drop - (i32.wrap_i64 - (i64.clz - (i64.const 0) - ) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.wrap_i64 - (i64.clz - (i64.const 0) - ) - ) - (i32.const 25) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.wrap_i64 - (i64.clz - (i64.const 0) - ) - ) - (i32.const 26) - ) - (i32.const 24) - ) - ) - (drop - (i32.eqz - (i32.const -1) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.wrap_i64 - (i64.const -1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.wrap_i64 - (i64.const -1) - ) - (i32.const 25) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.wrap_i64 - (i64.extend_i32_s - (i32.const -1) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.wrap_i64 - (i64.extend_i32_s - (i32.const -1) - ) - ) - (i32.const 25) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.xor - (local.get $0) - (i32.le_u - (local.get $0) - (i32.const 2) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $linear-sums (param $0 i32) (param $1 i32) - (drop - (i32.add - (i32.shl - (local.get $0) - (i32.const 4) - ) - (local.get $1) - ) - ) - (drop - (i32.add - (i32.add - (local.get $1) - (i32.shl - (local.get $0) - (i32.const 3) - ) - ) - (i32.const 12) - ) - ) - (drop - (i32.const 4) - ) - (drop - (i32.const 18) - ) - (drop - (i32.const 6) - ) - (drop - (i32.const -4) - ) - (drop - (i32.const 2) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 26) - ) - (drop - (i32.const -20) - ) - (drop - (i32.const 22) - ) - (drop - (i32.add - (i32.shl - (i32.const 1) - (local.get $0) - ) - (i32.const 14) - ) - ) - (drop - (i32.sub - (i32.shl - (local.get $1) - (i32.const 3) - ) - (i32.const 66) - ) - ) - (drop - (i32.const 44) - ) - (drop - (i32.add - (i32.mul - (local.get $0) - (i32.const 10) - ) - (i32.const 14) - ) - ) - (drop - (i32.add - (i32.shl - (local.get $0) - (i32.const 1) - ) - (i32.const 34) - ) - ) - (drop - (local.get $0) - ) - ) - (func $almost-sign-ext (param $0 i32) - (drop - (i32.shr_s - (i32.shl - (i32.const 100) - (i32.const 25) - ) - (i32.const 24) - ) - ) - (drop - (i32.shl - (i32.const 50) - (i32.const 1) - ) - ) - ) - (func $squaring (param $0 i32) (param $1 i32) - (drop - (i32.and - (local.get $0) - (i32.const 8) - ) - ) - (drop - (i32.and - (local.get $0) - (i32.const 11) - ) - ) - (drop - (i32.and - (local.get $0) - (i32.const 8) - ) - ) - (drop - (i32.or - (local.get $0) - (i32.const 203) - ) - ) - (drop - (i32.shl - (local.get $0) - (i32.const 19) - ) - ) - (drop - (i32.shr_s - (local.get $0) - (i32.const 19) - ) - ) - (drop - (i32.shr_u - (local.get $0) - (i32.const 19) - ) - ) - (drop - (i32.shr_u - (i32.shr_s - (local.get $0) - (i32.const 11) - ) - (i32.const 8) - ) - ) - ) - (func $sign-ext-ne (param $0 i32) (param $1 i32) - (drop - (block (result i32) - (drop - (local.get $0) - ) - (i32.const 1) - ) - ) - (drop - (block (result i32) - (drop - (local.get $0) - ) - (i32.const 1) - ) - ) - (drop - (block (result i32) - (drop - (local.get $0) - ) - (i32.const 1) - ) - ) - (drop - (i32.ne - (i32.and - (local.get $0) - (i32.const 255) - ) - (i32.const 111) - ) - ) - (drop - (i32.ne - (i32.and - (local.get $0) - (i32.const 255) - ) - (i32.and - (local.get $1) - (i32.const 255) - ) - ) - ) - ) - (func $sign-ext-eqz (param $0 i32) (param $1 i32) - (drop - (i32.eqz - (i32.and - (local.get $0) - (i32.const 255) - ) - ) - ) - ) - (func $sign-ext-boolean (param $0 i32) (param $1 i32) - (drop - (if (result i32) - (i32.and - (local.get $0) - (i32.const 255) - ) - (i32.const 100) - (i32.const 200) - ) - ) - ) - (func $add-sub-zero (param $0 i32) (param $1 i64) - (drop - (local.get $0) - ) - (drop - (local.get $0) - ) - (drop - (local.get $1) - ) - (drop - (local.get $1) - ) - ) - (func $store-signext (param $0 i32) - (i32.store8 - (i32.const 8) - (local.get $0) - ) - (i32.store8 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 25) - ) - (i32.const 25) - ) - ) - (i32.store8 - (i32.const 8) - (local.get $0) - ) - (i32.store16 - (i32.const 8) - (local.get $0) - ) - (i32.store16 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 17) - ) - (i32.const 17) - ) - ) - (i32.store16 - (i32.const 8) - (local.get $0) - ) - (i32.store - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 16) - ) - (i32.const 16) - ) - ) - (i32.store - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 8) - ) - (i32.const 8) - ) - ) - ) - (func $sign-ext-tee (param $0 i32) (param $1 i32) - (drop - (i32.shr_s - (i32.shl - (local.tee $0 - (i32.const 128) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (local.tee $0 - (i32.const 127) - ) - ) - ) - (func $sign-ext-load (param $0 i32) (param $1 i32) - (drop - (i32.load8_s - (i32.const 256) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.load8_s - (i32.const 256) - ) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_u - (i32.load8_u - (i32.const 256) - ) - (i32.const 1) - ) - ) - (drop - (i32.load16_s - (i32.const 256) - ) - ) - (drop - (local.tee $1 - (i32.load8_s - (i32.const 1) - ) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.tee $1 - (i32.load8_u - (i32.const 1) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.and - (local.tee $1 - (i32.load8_s - (i32.const 1) - ) - ) - (i32.const 255) - ) - ) - (drop - (local.tee $1 - (i32.load8_u - (i32.const 1) - ) - ) - ) - ) - (func $mask-bits (param $0 i32) (param $1 i32) - (drop - (local.tee $0 - (i32.const 127) - ) - ) - (drop - (local.tee $0 - (i32.const 128) - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 254) - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 1279) - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 1290) - ) - ) - (drop - (local.tee $0 - (i32.const 128) - ) - ) - (drop - (local.tee $0 - (i32.const 128) - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 127) - ) - ) - ) - (func $local-info-zero-ext (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.const 212) - ) - (drop - (local.get $x) - ) - (local.set $y - (i32.const 500) - ) - (drop - (i32.and - (local.get $y) - (i32.const 255) - ) - ) - (local.set $0 - (i32.const 212) - ) - (drop - (i32.and - (local.get $0) - (i32.const 255) - ) - ) - (local.set $z - (i32.const 212) - ) - (local.set $z - (i32.const 220) - ) - (drop - (local.get $z) - ) - (local.set $w - (i32.const 212) - ) - (local.set $w - (i32.const 1000) - ) - (drop - (i32.and - (local.get $w) - (i32.const 255) - ) - ) - ) - (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.const 127) - ) - (drop - (local.get $x) - ) - (local.set $y - (i32.const 128) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $y) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $0 - (i32.const 127) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.const 127) - ) - (local.set $z - (i32.const 100) - ) - (drop - (local.get $z) - ) - (local.set $w - (i32.const 127) - ) - (local.set $w - (i32.const 150) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $w) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (local.get $x) - ) - (local.set $y - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 16) - ) - (i32.const 16) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $y) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $0 - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (local.get $z) - ) - (local.set $w - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $w - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 23) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $w) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 23) - ) - ) - ) - (func $signed-loads-fill-the-bits (param $$e i32) (result i32) - (local $$0 i32) - (local $$conv i32) - (local.set $$0 - (i32.load8_s - (i32.const 1024) - ) - ) - (local.set $$conv - (i32.and - (local.get $$0) - (i32.const 255) - ) - ) - (return - (i32.eq - (local.get $$e) - (local.get $$conv) - ) - ) - ) - (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.load8_s - (i32.const 1024) - ) - ) - (drop - (local.get $x) - ) - (local.set $y - (i32.load8_u - (i32.const 1024) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $y) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.load16_s - (i32.const 1024) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $z) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32) - (drop - (i32.eq - (i32.load8_u - (local.get $0) - ) - (i32.and - (local.get $1) - (i32.const 255) - ) - ) - ) - (drop - (i32.eq - (i32.load8_u - (local.get $0) - ) - (i32.and - (local.get $1) - (i32.const 255) - ) - ) - ) - (drop - (i32.eq - (i32.load8_u - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (drop - (i32.eq - (i32.load8_s - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - (drop - (i32.eq - (i32.load8_u - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (drop - (i32.eq - (i32.load8_s - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - ) - (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32) - (i32.ne - (i32.shr_s - (i32.shl - (call $unsign-diff-sizes - (i32.const -1) - (i32.const 5) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.shr_s - (i32.shl - (call $unsign-diff-sizes - (i32.const 1) - (i32.const 2006) - ) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32) - (i32.ne - (i32.and - (call $unsign-same-sizes - (i32.const -1) - (i32.const 5) - ) - (i32.const 255) - ) - (i32.and - (call $unsign-same-sizes - (i32.const 1) - (i32.const 2006) - ) - (i32.const 255) - ) - ) - ) - (func $fuzz-almost-sign-ext - (drop - (i32.shr_s - (i32.shl - (i32.load16_u - (i32.const 2278) - ) - (i32.const 17) - ) - (i32.const 16) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.load16_u - (i32.const 2278) - ) - (i32.const 17) - ) - (i32.const 16) - ) - ) - ) - (func $fuzz-comp-impossible (param $x i32) - (drop - (block (result i32) - (drop - (local.get $x) - ) - (i32.const 0) - ) - ) - (drop - (block (result i32) - (drop - (local.get $x) - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.and - (local.get $x) - (i32.const 255) - ) - (i32.const 127) - ) - ) - (drop - (block (result i32) - (drop - (local.get $x) - ) - (i32.const 0) - ) - ) - (drop - (block (result i32) - (drop - (local.get $x) - ) - (i32.const 0) - ) - ) - (drop - (block (result i32) - (drop - (local.get $x) - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.and - (local.get $x) - (i32.const 255) - ) - (i32.const 252) - ) - ) - ) - (func $if-parallel (param $0 i32) (param $1 i32) - (drop - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (drop - (block (result i32) - (drop - (local.tee $0 - (local.get $1) - ) - ) - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - ) - (drop - (block (result i32) - (i32.add - (local.get $1) - (unreachable) - ) - ) - ) - (drop - (block (result i32) - (drop - (local.tee $0 - (local.get $1) - ) - ) - (i32.add - (local.get $1) - (unreachable) - ) - ) - ) - (drop - (if (result i32) - (unreachable) - (i32.add - (local.get $1) - (unreachable) - ) - (i32.add - (local.get $1) - (unreachable) - ) - ) - ) - ) - (func $select-parallel (param $0 i32) (param $1 i32) - (drop - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (drop - (select - (local.tee $0 - (local.get $1) - ) - (local.tee $0 - (local.get $1) - ) - (local.get $0) - ) - ) - (drop - (block (result i32) - (drop - (local.tee $0 - (local.get $1) - ) - ) - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - ) - (drop - (select - (local.tee $0 - (local.get $1) - ) - (local.tee $0 - (local.get $1) - ) - (local.tee $0 - (local.get $1) - ) - ) - ) - (drop - (select - (local.tee $0 - (local.get $1) - ) - (local.tee $0 - (local.get $1) - ) - (unreachable) - ) - ) - ) - (func $zero-shifts-is-not-sign-ext - (drop - (i32.eq - (i32.load16_s align=1 - (i32.const 790656516) - ) - (i32.const -5431187) - ) - ) - (drop - (i32.eq - (i32.shl - (i32.load16_s align=1 - (i32.const 790656516) - ) - (i32.const 1) - ) - (i32.const -5431187) - ) - ) - ) - (func $zero-ops (result i32) - (return - (i32.eq - (i32.load16_s align=1 - (i32.const 790656516) - ) - (i32.const -1337) - ) - ) - ) - (func $zero-ops-64 (result i32) - (return - (i64.eq - (i64.load16_s align=1 - (i32.const 790656516) - ) - (i64.const -1337) - ) - ) - ) - (func $zero-ops-64-special (result i32) - (return - (i32.wrap_i64 - (i64.popcnt - (i64.const 7377) - ) - ) - ) - ) - (func $sign-ext-1-and-ne (result i32) - (drop - (call $sign-ext-1-and-ne) - ) - (i32.const 1) - ) - (func $neg-shifts-and-255 (result i32) - (i32.and - (i32.const -99) - (i32.const 255) - ) - ) - (func $neg-shifts-and-255-b (result i32) - (i32.and - (i32.const -2349025) - (i32.const 255) - ) - ) - (func $shifts-square-overflow (param $x i32) (result i32) - (i32.shr_u - (i32.shr_u - (local.get $x) - (i32.const 31) - ) - (i32.const 31) - ) - ) - (func $shifts-square-no-overflow-small (param $x i32) (result i32) - (i32.shr_u - (local.get $x) - (i32.const 9) - ) - ) - (func $shifts-square-overflow-64 (param $x i64) (result i64) - (i64.shr_u - (i64.shr_u - (local.get $x) - (i64.const 63) - ) - (i64.const 63) - ) - ) - (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64) - (i64.shr_u - (local.get $x) - (i64.const 9) - ) - ) - (func $shifts-square-unreachable (param $x i32) (result i32) - (i32.shr_u - (i32.shr_u - (unreachable) - (i32.const 1031) - ) - (i32.const 4098) - ) - ) - (func $mix-shifts (result i32) - (i32.shr_u - (i32.shl - (i32.const 23) - (i32.const 3) - ) - (i32.const 8) - ) - ) - (func $actually-no-shifts (result i32) - (i32.const 33) - ) - (func $less-shifts-than-it-seems (param $x i32) (result i32) - (i32.const 4800) - ) - (func $and-popcount32 (result i32) - (i32.and - (i32.popcnt - (i32.const -1) - ) - (i32.const 31) - ) - ) - (func $and-popcount32-big (result i32) - (i32.popcnt - (i32.const -1) - ) - ) - (func $and-popcount64 (result i64) - (i64.and - (i64.popcnt - (i64.const -1) - ) - (i64.const 63) - ) - ) - (func $and-popcount64-big (result i64) - (i64.and - (i64.popcnt - (i64.const -1) - ) - (i64.const 127) - ) - ) - (func $and-popcount64-bigger (result i64) - (i64.and - (i64.popcnt - (i64.const -1) - ) - (i64.const 255) - ) - ) - (func $optimizeAddedConstants-filters-through-nonzero (result i32) - (i32.sub - (i32.shl - (i32.const -536870912) - (i32.wrap_i64 - (i64.const 0) - ) - ) - (i32.const 31744) - ) - ) - (func $optimizeAddedConstants-filters-through-nonzero-b (result i32) - (i32.sub - (i32.shl - (i32.const -536870912) - (i32.wrap_i64 - (i64.const -1) - ) - ) - (i32.const 31744) - ) - ) - (func $return-proper-value-from-shift-left-by-zero (result i32) - (if (result i32) - (i32.add - (loop $label$0 (result i32) - (block $label$1 - (br_if $label$1 - (i32.load - (i32.const 0) - ) - ) - ) - (i32.const -62) - ) - (i32.const 40) - ) - (i32.const 1) - (i32.const 0) - ) - ) - (func $de-morgan-2 (param $x i32) (param $y i32) - (drop - (i32.eqz - (i32.or - (local.get $x) - (local.get $y) - ) - ) - ) - (drop - (i32.or - (i32.eqz - (local.get $x) - ) - (i32.eqz - (local.get $y) - ) - ) - ) - (drop - (i32.xor - (i32.eqz - (local.get $x) - ) - (i32.eqz - (local.get $y) - ) - ) - ) - (drop - (i32.and - (local.get $y) - (i32.eqz - (local.get $x) - ) - ) - ) - (drop - (i32.and - (i32.eqz - (local.get $y) - ) - (local.get $x) - ) - ) - (drop - (i32.and - (i32.eqz - (local.get $x) - ) - (i32.wrap_i64 - (i64.const 2) - ) - ) - ) - (drop - (i32.and - (i32.eqz - (local.get $y) - ) - (i32.wrap_i64 - (i64.const 1) - ) - ) - ) - ) - (func $subzero1 (param $0 i32) (result i32) - (i32.sub - (i32.const 32) - (i32.clz - (local.get $0) - ) - ) - ) - (func $subzero2 (param $0 i32) (result i32) - (i32.sub - (i32.const 32) - (i32.clz - (local.get $0) - ) - ) - ) - (func $subzero3 (param $0 i32) (param $1 i32) (result i32) - (i32.sub - (local.get $1) - (i32.clz - (local.get $0) - ) - ) - ) - (func $subzero4 (param $0 i32) (param $1 i32) (result i32) - (i32.sub - (local.get $0) - (i32.clz - (local.get $1) - ) - ) - ) - (func $mul-32-power-2 (param $x i32) (result i32) - (drop - (call $mul-32-power-2 - (i32.shl - (local.get $x) - (i32.const 2) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 5) - ) - ) - ) - (drop - (call $mul-32-power-2 - (local.get $x) - ) - ) - (drop - (call $mul-32-power-2 - (i32.const 0) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (call $mul-32-power-2 - (i32.const 123) - ) - (i32.const 0) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.sub - (i32.const 0) - (local.get $x) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.shl - (local.get $x) - (i32.const 31) - ) - ) - ) - (unreachable) - ) - (func $mul-64-power-2 (param $x i64) (result i64) - (drop - (call $mul-64-power-2 - (i64.shl - (local.get $x) - (i64.const 2) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 5) - ) - ) - ) - (drop - (call $mul-64-power-2 - (local.get $x) - ) - ) - (drop - (call $mul-64-power-2 - (i64.const 0) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (call $mul-64-power-2 - (i64.const 123) - ) - (i64.const 0) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.sub - (i64.const 0) - (local.get $x) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.shl - (local.get $x) - (i64.const 63) - ) - ) - ) - (unreachable) - ) - (func $div-32-power-2 (param $x i32) (result i32) - (drop - (call $div-32-power-2 - (i32.shr_u - (local.get $x) - (i32.const 2) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 5) - ) - ) - ) - (drop - (call $div-32-power-2 - (local.get $x) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (call $div-32-power-2 - (i32.const 123) - ) - (i32.const 0) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.eq - (local.get $x) - (i32.const -1) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.shr_u - (local.get $x) - (i32.const 31) - ) - ) - ) - (unreachable) - ) - (func $urem-32-power-2 (param $x i32) (result i32) - (drop - (call $urem-32-power-2 - (i32.and - (local.get $x) - (i32.const 3) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 5) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.const 0) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const -1) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.const 0) - ) - ) - (unreachable) - ) - (func $fdiv-32-power-2 (param $x f32) - (drop - (f32.mul - (local.get $x) - (f32.const 0.5) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const -0.5) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const 2.3283064365386963e-10) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const 5.421010862427522e-20) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const 8507059173023461586584365e13) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const 1.1754943508222875e-38) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const -8507059173023461586584365e13) - ) - ) - (drop - (f32.mul - (local.get $x) - (f32.const -1.1754943508222875e-38) - ) - ) - (drop - (f32.div - (local.get $x) - (f32.const 5.877471754111438e-39) - ) - ) - (drop - (f32.div - (local.get $x) - (f32.const 5.877471754111438e-39) - ) - ) - (drop - (f32.div - (local.get $x) - (f32.const 0) - ) - ) - (drop - (f32.div - (local.get $x) - (f32.const nan:0x400000) - ) - ) - (drop - (f32.div - (local.get $x) - (f32.const inf) - ) - ) - (drop - (f32.div - (local.get $x) - (f32.const -inf) - ) - ) - ) - (func $fdiv-64-power-2 (param $x f64) - (drop - (f64.mul - (local.get $x) - (f64.const 0.5) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const -0.5) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const 2.3283064365386963e-10) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const 5.421010862427522e-20) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const 4494232837155789769323262e283) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const 2.2250738585072014e-308) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const -4494232837155789769323262e283) - ) - ) - (drop - (f64.mul - (local.get $x) - (f64.const -2.2250738585072014e-308) - ) - ) - (drop - (f64.div - (local.get $x) - (f64.const 1.1125369292536007e-308) - ) - ) - (drop - (f64.div - (local.get $x) - (f64.const 8988465674311579538646525e283) - ) - ) - (drop - (f64.div - (local.get $x) - (f64.const 0) - ) - ) - (drop - (f64.div - (local.get $x) - (f64.const nan:0x8000000000000) - ) - ) - (drop - (f64.div - (local.get $x) - (f64.const inf) - ) - ) - (drop - (f64.div - (local.get $x) - (f64.const -inf) - ) - ) - ) - (func $srem-by-const (param $x i32) (param $y i64) - (drop - (i32.const 0) - ) - (drop - (i64.const 0) - ) - (drop - (i32.rem_s - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i64.rem_s - (local.get $y) - (i64.const -9223372036854775808) - ) - ) - ) - (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64) - (drop - (i32.eqz - (i32.and - (local.get $x) - (i32.const 3) - ) - ) - ) - (drop - (i64.eqz - (i64.and - (local.get $y) - (i64.const 3) - ) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $x) - (i32.const 3) - ) - ) - ) - (drop - (i64.eqz - (i64.and - (local.get $y) - (i64.const 3) - ) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $x) - (i32.const 3) - ) - ) - ) - (drop - (i64.eqz - (i64.and - (local.get $y) - (i64.const 1) - ) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $x) - (i32.const 3) - ) - ) - ) - (drop - (i64.eqz - (i64.and - (local.get $y) - (i64.const 3) - ) - ) - ) - (drop - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i32.wrap_i64 - (i64.and - (local.get $y) - (i64.const 1) - ) - ) - ) - (drop - (i32.eqz - (i32.const 0) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - ) - ) - (drop - (i32.ne - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const 0) - ) - ) - (drop - (i64.eqz - (i64.and - (local.get $y) - (i64.const 9223372036854775807) - ) - ) - ) - (drop - (i64.ne - (i64.and - (local.get $y) - (i64.const 9223372036854775807) - ) - (i64.const 0) - ) - ) - (drop - (i32.eqz - (i32.rem_s - (local.get $x) - (i32.const 3) - ) - ) - ) - (drop - (i64.eqz - (i64.rem_s - (local.get $y) - (i64.const 3) - ) - ) - ) - ) - (func $orZero (param $0 i32) (result i32) - (local.get $0) - ) - (func $andZero (param $0 i32) (result i32) - (drop - (i32.const 0) - ) - (drop - (i32.and - (call $andZero - (i32.const 1234) - ) - (i32.const 0) - ) - ) - (unreachable) - ) - (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64) - (drop - (local.get $x32) - ) - (drop - (local.get $x32) - ) - (drop - (local.get $x32) - ) - (drop - (local.get $x32) - ) - (drop - (local.get $x64) - ) - (drop - (local.get $x64) - ) - (drop - (local.get $x64) - ) - (drop - (local.get $x64) - ) - (drop - (i32.const 0) - ) - (drop - (i64.const 0) - ) - (drop - (f32.mul - (local.get $y32) - (f32.const 0) - ) - ) - (drop - (f64.mul - (local.get $y64) - (f64.const 0) - ) - ) - (drop - (local.get $x32) - ) - (drop - (local.get $x64) - ) - (drop - (f32.mul - (local.get $y32) - (f32.const 1) - ) - ) - (drop - (f64.mul - (local.get $y64) - (f64.const 1) - ) - ) - (drop - (i32.const 0) - ) - (drop - (i64.const 0) - ) - (drop - (i32.and - (unreachable) - (i32.const 0) - ) - ) - (drop - (i64.and - (unreachable) - (i64.const 0) - ) - ) - (drop - (local.get $x32) - ) - (drop - (local.get $x32) - ) - (drop - (local.get $x64) - ) - (drop - (local.get $x64) - ) - (drop - (f32.mul - (local.get $y32) - (f32.const 1) - ) - ) - (drop - (f64.mul - (local.get $y64) - (f64.const 1) - ) - ) - (drop - (f32.div - (local.get $y32) - (f32.const 1.2000000476837158) - ) - ) - (drop - (i32.sub - (i32.const 0) - (local.get $x32) - ) - ) - (drop - (i64.sub - (i64.const 0) - (local.get $x64) - ) - ) - (drop - (f32.sub - (f32.const -0) - (local.get $y32) - ) - ) - (drop - (f64.sub - (f64.const -0) - (local.get $y64) - ) - ) - (drop - (i32.eq - (local.get $x32) - (i32.const 10) - ) - ) - (drop - (i32.le_u - (i32.add - (local.get $x32) - (i32.const 10) - ) - (i32.const 20) - ) - ) - (drop - (i32.eq - (local.get $x32) - (i32.const 30) - ) - ) - (drop - (i64.eq - (local.get $x64) - (i64.const 10) - ) - ) - (drop - (i32.eq - (local.get $x32) - (i32.const 10) - ) - ) - (drop - (i32.eq - (i32.add - (local.get $x32) - (i32.const 10) - ) - (local.get $x32) - ) - ) - (drop - (i32.eq - (local.get $x32) - (i32.const 30) - ) - ) - (drop - (i32.eq - (i32.sub - (local.get $x32) - (i32.const 30) - ) - (local.get $x32) - ) - ) - (drop - (i32.eq - (i32.add - (local.get $x32) - (i32.const 30) - ) - (local.get $x32) - ) - ) - (drop - (i32.eq - (i32.sub - (local.get $x32) - (i32.const 10) - ) - (local.get $x32) - ) - ) - (drop - (i32.const 1) - ) - ) - (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32) - (drop - (i32.sub - (local.get $x) - (i32.const -64) - ) - ) - (drop - (i32.add - (local.get $x) - (i32.const -64) - ) - ) - (drop - (i32.sub - (local.get $x) - (i32.const -8192) - ) - ) - (drop - (i32.sub - (local.get $x) - (i32.const -1048576) - ) - ) - (drop - (i32.sub - (local.get $x) - (i32.const -134217728) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -64) - ) - ) - (drop - (i64.add - (local.get $y) - (i64.const -64) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -8192) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -1048576) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -134217728) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -17179869184) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -2199023255552) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -281474976710656) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -36028797018963968) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const -4611686018427387904) - ) - ) - (drop - (f32.add - (local.get $z) - (f32.const 64) - ) - ) - ) - (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i64.const 0) - ) - (drop - (i32.shl - (i32.const 0) - (unreachable) - ) - ) - ) - (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32) - (drop - (i32.const 0) - ) - (drop - (i64.const 0) - ) - (drop - (f64.sub - (local.get $z) - (local.get $z) - ) - ) - (drop - (i32.sub - (local.get $x) - (local.get $xx) - ) - ) - (drop - (i32.sub - (unreachable) - (unreachable) - ) - ) - (drop - (i32.add - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (local.get $x) - ) - (drop - (local.get $x) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i64.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (local.get $y) - ) - (drop - (local.get $y) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - ) - (func $all_ones (param $x i32) (param $y i64) - (drop - (local.get $x) - ) - (drop - (i32.const -1) - ) - (drop - (i32.or - (local.tee $x - (i32.const 1337) - ) - (i32.const -1) - ) - ) - (drop - (local.get $y) - ) - (drop - (i64.const -1) - ) - ) - (func $xor (param $x i32) (param $y i64) - (drop - (local.get $x) - ) - ) - (func $select-on-const (param $x i32) (param $y i64) - (drop - (local.get $x) - ) - (drop - (i32.const 3) - ) - (drop - (local.tee $x - (i32.const 5) - ) - ) - (drop - (block (result i32) - (drop - (local.tee $x - (i32.const 6) - ) - ) - (i32.const 7) - ) - ) - (drop - (select - (i32.const 4) - (local.tee $x - (i32.const 5) - ) - (i32.const 1) - ) - ) - (drop - (local.tee $x - (i32.const 6) - ) - ) - (drop - (i32.eqz - (i32.eqz - (local.get $x) - ) - ) - ) - (drop - (i32.eqz - (local.get $x) - ) - ) - (drop - (i32.ge_s - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i32.lt_s - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i32.lt_s - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i32.gt_s - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i32.le_s - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i32.ge_s - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i64.extend_i32_u - (i32.eqz - (i32.eqz - (local.get $x) - ) - ) - ) - ) - (drop - (i64.extend_i32_u - (i32.eqz - (local.get $x) - ) - ) - ) - (drop - (i64.extend_i32_u - (i64.eqz - (local.get $y) - ) - ) - ) - (drop - (i64.extend_i32_u - (i32.eqz - (i64.eqz - (local.get $y) - ) - ) - ) - ) - (drop - (i64.extend_i32_u - (i64.ge_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (i64.extend_i32_u - (i64.lt_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (i64.extend_i32_u - (i64.lt_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (i64.extend_i32_u - (i64.ge_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (select - (i32.const 0) - (local.get $x) - (i32.const 0) - ) - ) - (drop - (select - (i32.const 2) - (local.get $x) - (i32.const 2) - ) - ) - (drop - (select - (local.get $x) - (i32.const 2) - (local.get $x) - ) - ) - (drop - (select - (local.get $y) - (i64.const 0) - (i64.eqz - (i64.const 0) - ) - ) - ) - (drop - (select - (local.get $y) - (i64.const 2) - (i64.eqz - (i64.const 2) - ) - ) - ) - ) - (func $optimize-boolean (param $x i32) (param $y i64) - (drop - (select - (i32.const 1) - (i32.const 2) - (local.get $x) - ) - ) - (drop - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i32.eqz - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - ) - (drop - (i32.wrap_i64 - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - ) - ) - (drop - (i32.eqz - (i32.shr_u - (local.get $x) - (i32.const 31) - ) - ) - ) - (drop - (i64.eqz - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - ) - ) - (drop - (i64.eqz - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - ) - ) - (drop - (i64.eqz - (local.get $y) - ) - ) - (drop - (i32.eqz - (i32.wrap_i64 - (local.get $y) - ) - ) - ) - (drop - (i32.wrap_i64 - (i64.and - (local.get $y) - (i64.const 1) - ) - ) - ) - (drop - (i64.eqz - (i64.and - (local.get $y) - (i64.const 1) - ) - ) - ) - (drop - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i32.const 1) - ) - (drop - (i64.and - (local.get $y) - (i64.const 1) - ) - ) - (drop - (i64.const 1) - ) - (drop - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i64.ne - (local.get $y) - (i64.const 0) - ) - ) - (drop - (i32.ne - (local.get $x) - (i32.const 0) - ) - ) - (drop - (if (result i32) - (i32.and - (local.get $x) - (i32.const 3) - ) - (i32.const 1) - (i32.const 0) - ) - ) - (drop - (if (result i32) - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const 1) - (i32.const 0) - ) - ) - ) - (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64) - (drop - (i32.rotl - (i32.const -2) - (local.get $x) - ) - ) - (drop - (i64.rotl - (i64.const -2) - (local.get $z) - ) - ) - ) - (func $getFallthrough - (local $x0 i32) - (local $x1 i32) - (local $x2 i32) - (local $x3 i32) - (local $x4 i32) - (local $x5 i32) - (local $x6 i32) - (local $x7 i32) - (local.set $x0 - (i32.const 1) - ) - (drop - (local.get $x0) - ) - (local.set $x1 - (local.tee $x2 - (i32.const 1) - ) - ) - (drop - (local.get $x1) - ) - (local.set $x3 - (loop $loop-in (result i32) - (i32.const 1) - ) - ) - (drop - (local.get $x3) - ) - (local.set $x4 - (if (result i32) - (i32.const 1) - (i32.const 2) - (i32.const 3) - ) - ) - (drop - (i32.and - (local.get $x4) - (i32.const 7) - ) - ) - (local.set $x5 - (if (result i32) - (i32.const 1) - (unreachable) - (i32.const 3) - ) - ) - (drop - (local.get $x5) - ) - (local.set $x6 - (if (result i32) - (i32.const 1) - (i32.const 3) - (unreachable) - ) - ) - (drop - (local.get $x6) - ) - (drop - (block $out (result i32) - (local.set $x7 - (br_if $out - (i32.const 1) - (i32.const 1) - ) - ) - (drop - (local.get $x7) - ) - (unreachable) - ) - ) - ) - (func $tee-with-unreachable-value (result f64) - (local $var$0 i32) - (block $label$1 (result f64) - (local.tee $var$0 - (br_if $label$1 - (f64.const 1) - (unreachable) - ) - ) - ) - ) - (func $add-sub-zero-reorder-1 (param $temp i32) (result i32) - (i32.add - (i32.add - (i32.sub - (i32.const 0) - (local.get $temp) - ) - (local.tee $temp - (i32.const 1) - ) - ) - (i32.const 2) - ) - ) - (func $add-sub-zero-reorder-2 (param $temp i32) (result i32) - (i32.add - (i32.sub - (local.tee $temp - (i32.const 1) - ) - (local.get $temp) - ) - (i32.const 2) - ) - ) - (func $const-float-zero (param $fx f32) (param $fy f64) - (drop - (f32.sub - (local.get $fx) - (f32.const 0) - ) - ) - (drop - (f64.sub - (local.get $fy) - (f64.const 0) - ) - ) - (drop - (f32.add - (local.get $fx) - (f32.const -0) - ) - ) - (drop - (f64.add - (local.get $fy) - (f64.const -0) - ) - ) - (drop - (f32.add - (local.get $fx) - (f32.const 0) - ) - ) - (drop - (f64.add - (local.get $fy) - (f64.const 0) - ) - ) - (drop - (f32.sub - (f32.const 0) - (local.get $fx) - ) - ) - (drop - (f64.sub - (f64.const 0) - (local.get $fy) - ) - ) - (drop - (f32.add - (local.get $fx) - (f32.const 0) - ) - ) - (drop - (f64.add - (local.get $fy) - (f64.const 0) - ) - ) - (drop - (f32.sub - (f32.const -nan:0x34546d) - (f32.const 0) - ) - ) - ) - (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) - (drop - (i32.add - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i64.add - (local.get $y) - (i64.const 1) - ) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.gt_s - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i64.gt_s - (local.get $y) - (i64.const -1) - ) - ) - (drop - (i64.extend_i32_s - (i32.const 0) - ) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.le_s - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i64.le_s - (local.get $y) - (i64.const -1) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i64.eq - (local.get $y) - (i64.const -1) - ) - ) - (drop - (i32.ne - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i64.ne - (local.get $y) - (i64.const -1) - ) - ) - (drop - (i32.sub - (i32.const 0) - (local.get $x) - ) - ) - (drop - (i64.sub - (i64.const 0) - (local.get $y) - ) - ) - (drop - (f32.sub - (f32.const -0) - (local.get $fx) - ) - ) - (drop - (f64.sub - (f64.const -0) - (local.get $fy) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i64.extend_i32_u - (i64.eq - (local.get $y) - (i64.const -1) - ) - ) - ) - ) - (func $rhs-is-const (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) - (drop - (i32.eq - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i64.extend_i32_u - (i64.eq - (local.get $y) - (i64.const -9223372036854775808) - ) - ) - ) - (drop - (i64.div_s - (local.get $y) - (i64.const -2147483648) - ) - ) - (drop - (i32.ge_u - (local.get $x) - (i32.const -2) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i32.ge_u - (local.get $x) - (i32.const -2147483647) - ) - ) - (drop - (i32.shr_u - (local.get $x) - (i32.const 31) - ) - ) - (drop - (i64.extend_i32_u - (i64.eq - (local.get $y) - (i64.const -1) - ) - ) - ) - (drop - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.ne - (local.get $x) - (i32.const 0) - ) - ) - (drop - (i64.ne - (local.get $y) - (i64.const 0) - ) - ) - (drop - (i32.eqz - (local.get $x) - ) - ) - (drop - (i64.eqz - (local.get $y) - ) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.ne - (local.get $x) - (i32.const 2147483647) - ) - ) - (drop - (i64.ne - (local.get $y) - (i64.const 9223372036854775807) - ) - ) - (drop - (i32.ne - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i64.ne - (local.get $y) - (i64.const -9223372036854775808) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i64.eq - (local.get $y) - (i64.const -9223372036854775808) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const 2147483647) - ) - ) - (drop - (i64.eq - (local.get $y) - (i64.const 9223372036854775807) - ) - ) - (drop - (f32.sub - (f32.const -0) - (local.get $fx) - ) - ) - (drop - (f64.mul - (local.get $fy) - (f64.const 2.1) - ) - ) - (drop - (f64.mul - (local.get $fy) - (f64.const -2) - ) - ) - (drop - (f32.div - (local.get $fx) - (f32.const -inf) - ) - ) - (drop - (f64.div - (local.get $fy) - (f64.const 0) - ) - ) - (drop - (f64.div - (local.get $fy) - (f64.const -nan:0x8000000000000) - ) - ) - (drop - (f64.div - (f64.const -5) - (local.get $fy) - ) - ) - ) - (func $lhs-is-neg-one (param $x i32) (param $y i64) - (drop - (i32.const -1) - ) - (drop - (i64.const -1) - ) - (drop - (i32.const -1) - ) - (drop - (i64.const -1) - ) - (drop - (i32.const -1) - ) - (drop - (i64.const -1) - ) - (drop - (i32.shr_s - (i32.const -1) - (call $ne0) - ) - ) - (drop - (i32.shr_u - (i32.const -1) - (local.get $x) - ) - ) - ) - (func $lhs-is-const (param $x i32) (param $y i64) - (drop - (i32.sub - (i32.const 1) - (local.get $x) - ) - ) - (drop - (i64.sub - (i64.const 1) - (local.get $y) - ) - ) - (drop - (i32.sub - (i32.const -2) - (local.get $x) - ) - ) - (drop - (i64.sub - (i64.const -2) - (local.get $y) - ) - ) - (drop - (i32.sub - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i64.sub - (local.get $y) - (i64.const 1) - ) - ) - (drop - (i32.sub - (local.get $x) - (i32.const -2147483648) - ) - ) - ) - (func $pre-combine-or (param $x i32) (param $y i32) - (drop - (i32.ge_s - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.ge_s - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.or - (i32.eq - (local.get $x) - (i32.const 1) - ) - (i32.gt_s - (local.get $x) - (local.get $y) - ) - ) - ) - (drop - (i32.or - (i32.eq - (local.get $x) - (local.get $y) - ) - (i32.gt_s - (local.get $x) - (i32.const 1) - ) - ) - ) - (drop - (i32.or - (i32.gt_s - (call $ne0) - (local.get $y) - ) - (i32.eq - (call $ne0) - (local.get $y) - ) - ) - ) - (drop - (i32.or - (i32.lt_s - (call $ne0) - (local.get $y) - ) - (i32.eq - (call $ne0) - (local.get $y) - ) - ) - ) - ) - (func $combine-or (param $x i32) (param $y i32) - (drop - (i32.ge_s - (local.get $x) - (local.get $y) - ) - ) - ) - (func $select-into-arms (param $x i32) (param $y i32) - (if - (select - (local.get $x) - (local.get $y) - (local.get $y) - ) - (unreachable) - ) - ) - (func $optimize-boolean-context (param $x i32) (param $y i32) - (if - (local.get $x) - (unreachable) - ) - (drop - (select - (local.get $x) - (local.get $y) - (local.get $x) - ) - ) - ) - (func $optimize-relationals (param $x i32) (param $y i32) (param $X i64) (param $Y i64) - (drop - (i32.eq - (local.get $x) - (i32.const -2147483647) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const 2147483647) - ) - ) - (drop - (i32.eq - (local.get $x) - (local.get $y) - ) - ) - (drop - (i64.eq - (local.get $X) - (local.get $Y) - ) - ) - (drop - (i32.eq - (local.get $x) - (local.get $y) - ) - ) - (drop - (i64.eq - (local.get $X) - (local.get $Y) - ) - ) - (drop - (i32.ne - (local.get $x) - (local.get $y) - ) - ) - (drop - (i64.ne - (local.get $X) - (local.get $Y) - ) - ) - (drop - (i32.gt_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - ) - ) - (drop - (i32.ge_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - ) - ) - (drop - (i32.ne - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.const 1) - ) - (drop - (i32.const 1) - ) - (drop - (i32.lt_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - ) - ) - (drop - (i32.le_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - ) - ) - (drop - (i32.const 0) - ) - (drop - (i32.const 0) - ) - (drop - (i32.eq - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.eq - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i32.ne - (local.get $x) - (i32.const -2147483648) - ) - ) - (drop - (i32.lt_s - (i32.sub - (local.get $x) - (i32.const -2147483648) - ) - (i32.const 0) - ) - ) - (drop - (i32.ge_s - (i32.sub - (local.get $x) - (i32.const -2147483648) - ) - (i32.const 0) - ) - ) - (drop - (i32.gt_s - (i32.sub - (local.get $x) - (block $block (result i32) - (i32.const -2147483648) - ) - ) - (i32.const 0) - ) - ) - (drop - (i32.gt_s - (i32.sub - (local.get $x) - (block $block29 (result i32) - (i32.const -2147483648) - ) - ) - (i32.const 0) - ) - ) - ) - (func $unsigned-context (param $x i32) (param $y i64) - (drop - (i32.div_u - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const 3) - ) - ) - (drop - (i32.div_s - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const -3) - ) - ) - (drop - (i32.eq - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const -2147483648) - ) - ) - (drop - (i64.shr_u - (i64.and - (local.get $y) - (i64.const 9223372036854775807) - ) - (i64.const 1) - ) - ) - (drop - (i64.div_s - (i64.and - (local.get $y) - (i64.const 9223372036854775807) - ) - (i64.const -1) - ) - ) - (drop - (i32.rem_u - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const 3) - ) - ) - (drop - (i32.shr_u - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const 7) - ) - ) - (drop - (i32.ge_u - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const 7) - ) - ) - (drop - (i32.ge_s - (i32.and - (local.get $x) - (i32.const 2147483647) - ) - (i32.const -7) - ) - ) - ) - (func $optimize-float-mul-by-two (param $0 f64) (param $1 f32) - (drop - (f64.add - (local.get $0) - (local.get $0) - ) - ) - (drop - (f32.add - (local.get $1) - (local.get $1) - ) - ) - (drop - (f64.mul - (call $tee-with-unreachable-value) - (f64.const 2) - ) - ) - (drop - (f64.mul - (local.get $0) - (f64.const -2) - ) - ) - ) - (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) - (drop - (f64.abs - (local.get $w) - ) - ) - (drop - (f64.ceil - (local.get $w) - ) - ) - (drop - (f64.floor - (local.get $w) - ) - ) - (drop - (f64.trunc - (local.get $w) - ) - ) - (drop - (f64.nearest - (local.get $w) - ) - ) - (drop - (f64.nearest - (f64.trunc - (local.get $w) - ) - ) - ) - (drop - (f64.trunc - (f64.nearest - (local.get $w) - ) - ) - ) - (drop - (local.get $w) - ) - (drop - (f64.neg - (local.get $w) - ) - ) - (drop - (local.get $w) - ) - (drop - (i32.eqz - (i32.eqz - (local.get $x) - ) - ) - ) - (drop - (i32.eqz - (local.get $x) - ) - ) - (drop - (i64.eqz - (i64.const 1) - ) - ) - (drop - (i32.ne - (local.get $x) - (i32.const 2) - ) - ) - (drop - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - (drop - (i32.rem_s - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.rem_u - (local.get $x) - (local.get $y) - ) - ) - (drop - (local.get $y) - ) - (drop - (local.get $y) - ) - (drop - (i32.sub - (local.get $y) - (i32.sub - (local.get $x) - (local.get $y) - ) - ) - ) - (drop - (local.get $y) - ) - (drop - (local.get $y) - ) - (drop - (local.get $y) - ) - (drop - (local.get $y) - ) - (drop - (local.get $x) - ) - (drop - (i32.and - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.and - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.and - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.and - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.or - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.or - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.or - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.or - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.or - (local.get $z) - (i32.or - (local.get $x) - (local.get $y) - ) - ) - ) - (drop - (i32.or - (local.get $y) - (i32.or - (local.get $x) - (local.get $z) - ) - ) - ) - (drop - (i32.or - (call $ne0) - (local.get $x) - ) - ) - (drop - (i32.or - (i32.or - (call $ne0) - (local.get $x) - ) - (call $ne0) - ) - ) - (drop - (i32.or - (call $ne0) - (local.get $x) - ) - ) - (drop - (i32.or - (call $ne0) - (i32.or - (call $ne0) - (local.get $x) - ) - ) - ) - (drop - (i32.rem_s - (i32.rem_s - (local.get $y) - (local.get $x) - ) - (local.get $y) - ) - ) - (drop - (i32.rem_u - (local.get $y) - (i32.rem_u - (local.get $x) - (local.get $y) - ) - ) - ) - (drop - (i32.or - (local.get $x) - (i32.or - (local.tee $x - (i32.const 1) - ) - (local.get $x) - ) - ) - ) - (drop - (i32.or - (i32.or - (local.get $x) - (local.tee $x - (i32.const 1) - ) - ) - (local.get $x) - ) - ) - (drop - (i32.xor - (local.get $x) - (i32.xor - (local.tee $x - (i32.const 1) - ) - (local.get $x) - ) - ) - ) - (drop - (i32.xor - (i32.xor - (local.get $x) - (local.tee $x - (i32.const 1) - ) - ) - (local.get $x) - ) - ) - ) - (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64) - (drop - (local.get $x) - ) - (drop - (local.get $x) - ) - (drop - (local.get $x) - ) - (drop - (local.get $x) - ) - (drop - (local.get $x) - ) - (drop - (local.get $z) - ) - (drop - (local.get $z) - ) - (drop - (local.get $z) - ) - (drop - (local.get $z) - ) - (drop - (local.get $z) - ) - (drop - (i32.shl - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.shl - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.shr_s - (local.get $x) - (local.get $y) - ) - ) - (drop - (i32.shr_u - (local.get $x) - (local.get $y) - ) - ) - (drop - (i64.shl - (local.get $z) - (local.get $w) - ) - ) - (drop - (i64.shl - (local.get $z) - (local.get $w) - ) - ) - (drop - (i64.shr_s - (local.get $z) - (local.get $w) - ) - ) - (drop - (i64.shr_u - (local.get $z) - (local.get $w) - ) - ) - (drop - (local.get $x) - ) - (drop - (local.get $z) - ) - (drop - (i64.shl - (local.get $z) - (i64.and - (local.get $w) - (i64.const 32) - ) - ) - ) - (drop - (i64.shr_u - (local.get $z) - (i64.and - (local.get $w) - (i64.const 31) - ) - ) - ) - ) - (func $optimize-float-points (param $x0 f64) (param $x1 f64) (param $y0 f32) (param $y1 f32) - (drop - (f64.mul - (local.get $x0) - (local.get $x0) - ) - ) - (drop - (f32.mul - (local.get $y0) - (local.get $y0) - ) - ) - (drop - (f64.mul - (f64.add - (local.get $x0) - (local.get $x1) - ) - (f64.add - (local.get $x0) - (local.get $x1) - ) - ) - ) - (drop - (f64.abs - (f64.mul - (local.get $x0) - (local.get $x1) - ) - ) - ) - (drop - (f32.abs - (f32.mul - (local.get $y1) - (local.get $y0) - ) - ) - ) - (drop - (f64.abs - (f64.mul - (local.get $x0) - (f64.const 0) - ) - ) - ) - (drop - (f32.abs - (f32.mul - (f32.const 0) - (local.get $y0) - ) - ) - ) - (drop - (f64.abs - (f64.mul - (f64.add - (local.get $x0) - (local.get $x1) - ) - (f64.add - (local.get $x0) - (local.get $x0) - ) - ) - ) - ) - (drop - (f64.abs - (local.get $x0) - ) - ) - (drop - (f32.abs - (local.get $y0) - ) - ) - (drop - (f64.abs - (f64.sub - (f64.const 0) - (local.get $x0) - ) - ) - ) - (drop - (f32.abs - (f32.sub - (f32.const 0) - (local.get $y0) - ) - ) - ) - (drop - (f64.div - (local.get $x0) - (local.get $x0) - ) - ) - (drop - (f32.div - (local.get $y0) - (local.get $y0) - ) - ) - (drop - (f64.div - (f64.add - (local.get $x0) - (local.get $x1) - ) - (f64.add - (local.get $x0) - (local.get $x1) - ) - ) - ) - (drop - (f64.abs - (f64.div - (local.get $x0) - (local.get $x1) - ) - ) - ) - (drop - (f32.abs - (f32.div - (local.get $y1) - (local.get $y0) - ) - ) - ) - (drop - (f64.mul - (local.get $x0) - (local.get $x0) - ) - ) - (drop - (f32.mul - (local.get $y0) - (local.get $y0) - ) - ) - (drop - (f64.div - (local.get $x0) - (local.get $x0) - ) - ) - (drop - (f32.div - (local.get $y0) - (local.get $y0) - ) - ) - (drop - (f64.abs - (f64.div - (local.get $x0) - (f64.const 0) - ) - ) - ) - (drop - (f32.abs - (f32.div - (f32.const 0) - (local.get $y0) - ) - ) - ) - (drop - (f64.abs - (f64.div - (f64.add - (local.get $x0) - (local.get $x1) - ) - (f64.add - (local.get $x0) - (local.get $x0) - ) - ) - ) - ) - ) -) -(module - (type $none_=>_none (func)) - (import "env" "memory" (memory $0 (shared 256 256))) - (func $x - (drop - (i32.shr_s - (i32.shl - (i32.atomic.load8_u - (i32.const 100) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) -) -(module - (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) - (memory $0 0) - (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) - (memory.copy - (local.get $dst) - (local.get $dst) - (local.get $sz) - ) - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 0) - ) - (i32.store8 - (local.get $dst) - (i32.load8_u - (local.get $src) - ) - ) - (i32.store16 align=1 - (local.get $dst) - (i32.load16_u align=1 - (local.get $src) - ) - ) - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 3) - ) - (i32.store align=1 - (local.get $dst) - (i32.load align=1 - (local.get $src) - ) - ) - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 5) - ) - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 6) - ) - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 7) - ) - (i64.store align=1 - (local.get $dst) - (i64.load align=1 - (local.get $src) - ) - ) - (v128.store align=1 - (local.get $dst) - (v128.load align=1 - (local.get $src) - ) - ) - (memory.copy - (local.get $dst) - (local.get $src) - (local.get $sz) - ) - (memory.copy - (i32.const 0) - (i32.const 0) - (i32.load - (i32.const 3) - ) - ) - ) -) -(module - (type $none_=>_anyref (func (result anyref))) - (func $if-arms-subtype-fold (result anyref) - (ref.null extern) - ) - (func $if-arms-subtype-nofold (result anyref) - (if (result anyref) - (i32.const 0) - (ref.null extern) - (ref.null func) - ) - ) -) -(module - (type $i32_i32_i32_f64_=>_none (func (param i32 i32 i32 f64))) - (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) - (drop - (i32.extend8_s - (local.get $x) - ) - ) - (drop - (i32.extend16_s - (local.get $x) - ) - ) - ) -) -(module - (type $none_=>_none (func)) - (func $test - (if - (try (result i32) - (do - (i32.const 123) - ) - (catch_all - (i32.const 456) - ) - ) - (nop) - ) - ) -) -(module - (type $i32_=>_i32 (func (param i32) (result i32))) - (type $ref?|i32_->_i32|_=>_i32 (func (param (ref null $i32_=>_i32)) (result i32))) - (func $call_from-param (param $f (ref null $i32_=>_i32)) (result i32) - (unreachable) - ) -) diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast deleted file mode 100644 index 191189f70..000000000 --- a/test/passes/optimize-instructions_all-features.wast +++ /dev/null @@ -1,6184 +0,0 @@ -(module - (memory 0) - (type $0 (func (param i32 i64))) - (func $f (type $0) (param $i1 i32) (param $i2 i64) - (drop - (i32.and - (i32.and - (local.get $i1) - (i32.const 5) - ) - (i32.const 3) - ) - ) - (drop - (i32.or - (i32.or - (local.get $i1) - (i32.const 1) - ) - (i32.const 2) - ) - ) - (drop - (i32.xor - (i32.xor - (local.get $i1) - (i32.const -2) - ) - (i32.const -5) - ) - ) - (drop - (i32.mul - (i32.mul - (local.get $i1) - (i32.const -2) - ) - (i32.const 5) - ) - ) - ;; overflow also valid - (drop - (i32.mul - (i32.mul - (local.get $i1) - (i32.const 0xfffff) - ) - (i32.const 0x8000001) - ) - ) - (if - (i32.eqz - (local.get $i1) - ) - (drop - (i32.const 10) - ) - ) - (if - (i32.eqz - (local.get $i1) - ) - (drop - (i32.const 11) - ) - (drop - (i32.const 12) - ) - ) - (if - (i64.eqz - (local.get $i2) - ) - (drop - (i32.const 11) - ) - (drop - (i32.const 12) - ) - ) - (drop - (i32.eqz - (i32.gt_s - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.ge_s - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.lt_s - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.le_s - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.gt_u - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.ge_u - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.lt_u - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (i32.le_u - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.gt - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.ge - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.lt - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.le - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.gt - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.ge - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.lt - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.le - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.eq - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f32.ne - (f32.const 1) - (f32.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.eq - (f64.const 1) - (f64.const 2) - ) - ) - ) - (drop - (i32.eqz - (f64.ne - (f64.const 1) - (f64.const 2) - ) - ) - ) - ;; we handle only 0 in the right position, as we assume a const is there, and don't care about if - ;; both are consts here (precompute does that, so no need) - (drop - (i32.eq - (i32.const 100) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.const 0) - (i32.const 100) - ) - ) - (drop - (i32.eq - (i32.const 0) - (i32.const 0) - ) - ) - (drop - (i64.eq - (i64.const 100) - (i64.const 0) - ) - ) - (drop - (i64.eq - (i64.const 0) - (i64.const 100) - ) - ) - (drop - (i64.eq - (i64.const 0) - (i64.const 0) - ) - ) - (if - (i32.eqz - (i32.eqz - (i32.const 123) - ) - ) - (nop) - ) - (drop - (select - (i32.const 101) - (i32.const 102) - (i32.eqz - (local.get $i1) - ) - ) - ) - (drop - (select - (local.tee $i1 - (i32.const 103) - ) ;; these conflict - (local.tee $i1 - (i32.const 104) - ) - (i32.eqz - (local.get $i1) - ) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 1) - (i32.eqz - (i32.eqz - (i32.const 2) - ) - ) - ) - ) - ) - (func $load-store - (drop (i32.and (i32.load8_s (i32.const 0)) (i32.const 255))) - (drop (i32.and (i32.load8_u (i32.const 1)) (i32.const 255))) - (drop (i32.and (i32.load8_s (i32.const 2)) (i32.const 254))) - (drop (i32.and (i32.load8_u (i32.const 3)) (i32.const 1))) - (drop (i32.and (i32.load16_s (i32.const 4)) (i32.const 65535))) - (drop (i32.and (i32.load16_u (i32.const 5)) (i32.const 65535))) - (drop (i32.and (i32.load16_s (i32.const 6)) (i32.const 65534))) - (drop (i32.and (i32.load16_u (i32.const 7)) (i32.const 1))) - ;; - (i32.store8 (i32.const 8) (i32.and (i32.const -1) (i32.const 255))) - (i32.store8 (i32.const 9) (i32.and (i32.const -2) (i32.const 254))) - (i32.store16 (i32.const 10) (i32.and (i32.const -3) (i32.const 65535))) - (i32.store16 (i32.const 11) (i32.and (i32.const -4) (i32.const 65534))) - ;; - (i32.store8 (i32.const 11) (i32.wrap_i64 (i64.const 1))) - (i32.store16 (i32.const 11) (i32.wrap_i64 (i64.const 2))) - (i32.store (i32.const 11) (i32.wrap_i64 (i64.const 3))) - ;; - (i32.store8 (i32.const 7) (i32.const -1)) ;; 255 - (i32.store8 (i32.const 8) (i32.const 255)) - (i32.store8 (i32.const 9) (i32.const 256)) ;; 0 - (i32.store16 (i32.const 10) (i32.const 65535)) - (i32.store16 (i32.const 11) (i32.const 65536)) ;; 0 - (i32.store16 (i32.const 13) (i32.const -1)) ;; 65535 - (i32.store (i32.const 14) (i32.const 65536)) - ;; - (i64.store8 (i32.const 8) (i64.const 255)) - (i64.store8 (i32.const 9) (i64.const 256)) ;; 0 - (i64.store16 (i32.const 10) (i64.const 65535)) - (i64.store16 (i32.const 11) (i64.const 65536)) ;; 0 - (i64.store32 (i32.const 12) (i64.const 4294967295)) - (i64.store32 (i32.const 13) (i64.const 4294967296)) ;; 0 - (i64.store (i32.const 14) (i64.const 4294967296)) - ) - (func $and-neg1 - (drop (i32.and (i32.const 100) (i32.const -1))) - (drop (i32.and (i32.const 100) (i32.const 1))) - ) - (func $and-pos1 - (drop (i32.and (i32.eqz (i32.const 1000)) (i32.const 1))) - (drop (i32.and (i32.const 1) (i32.eqz (i32.const 1000)))) - (drop (i32.and (i32.const 100) (i32.const 1))) - (drop (i32.and (i32.lt_s (i32.const 2000) (i32.const 3000)) (i32.const 1))) - ) - (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64) - (drop (i32.and (unreachable) (i32.const 1))) ;; ok to reorder - (drop (i32.and (i32.const 1) (unreachable))) - (drop (i32.div_s (unreachable) (i32.const 1))) ;; not ok - (drop (i32.div_s (i32.const 1) (unreachable))) - ;; the various orderings - (drop (i32.and (i32.const 1) (i32.const 2))) - (drop (i32.and (local.get $x) (i32.const 3))) - (drop (i32.and (i32.const 4) (local.get $x))) - (drop (i32.and (local.get $x) (local.get $y))) - (drop (i32.and (local.get $y) (local.get $x))) - (drop (i32.and (local.get $y) (local.tee $x (i32.const -4)))) - (drop (i32.and - (block (result i32) - (i32.const -5) - ) - (local.get $x) - )) - (drop (i32.and - (local.get $x) - (block (result i32) - (i32.const -6) - ) - )) - (drop (i32.and - (block (result i32) - (i32.const 5) - ) - (loop (result i32) - (i32.const 6) - ) - )) - (drop (i32.and - (loop (result i32) - (i32.const 7) - ) - (block (result i32) - (i32.const 8) - ) - )) - (drop (i32.and - (loop (result i32) - (call $and-pos1) - (i32.const 9) - ) - (block (result i32) - (i32.const 10) - ) - )) - (drop (i32.and - (loop (result i32) - (i32.const 11) - ) - (block (result i32) - (call $and-pos1) - (i32.const 12) - ) - )) - (drop (i32.and - (loop (result i32) - (call $and-pos1) - (i32.const 13) - ) - (block (result i32) - (call $and-pos1) - (i32.const 14) - ) - )) - (drop (i32.and - (block (result i32) - (call $and-pos1) - (i32.const 14) - ) - (loop (result i32) - (call $and-pos1) - (i32.const 13) - ) - )) - (drop (i32.and - (block (result i32) - (i32.const 15) - ) - (local.get $x) - )) - (drop (i32.and - (local.get $x) - (block (result i32) - (i32.const 15) - ) - )) - (drop (i32.and - (i32.gt_s - (i32.const 16) - (i32.const 17) - ) - (i32.gt_u - (i32.const 18) - (i32.const 19) - ) - )) - (drop (i32.and - (i32.gt_u - (i32.const 20) - (i32.const 21) - ) - (i32.gt_s - (i32.const 22) - (i32.const 23) - ) - )) - (drop (i32.gt_s - (i32.const 1) - (local.get $x) - )) - (drop (i32.gt_u - (i32.const 0) - (local.get $x) - )) - (drop (i32.ne - (i32.const -1) - (local.get $x) - )) - (drop (f64.ne - (f64.const -1) - (local.get $fx) - )) - (drop (f64.lt - (f64.const -2) - (local.get $fx) - )) - (drop (f64.ge - (f64.const inf) - (local.get $fx) - )) - (drop (f64.le - (f64.const nan) - (local.get $fx) - )) - ;; skip - (drop (f64.ge - (f64.const 1) - (f64.const 2) - )) - (drop (i32.add (i32.ctz (local.get $x)) (i32.ctz (local.get $y)))) - (drop (i32.add (i32.ctz (local.get $y)) (i32.ctz (local.get $x)))) - (drop (i32.add (i32.ctz (local.get $x)) (i32.eqz (local.get $y)))) - (drop (i32.add (i32.eqz (local.get $x)) (i32.ctz (local.get $y)))) - ) - (func $ne0 (result i32) - (if (i32.ne (call $ne0) (i32.const 0)) - (nop) - ) - (if (i32.ne (i32.const 0) (call $ne0)) - (nop) - ) - ;; through an or - (if - (i32.or - (i32.ne (i32.const 0) (call $ne0)) - (i32.ne (i32.const 0) (call $ne0)) - ) - (nop) - ) - ;; but not an and - (if - (i32.and - (i32.ne (i32.const 0) (call $ne0)) - (i32.ne (i32.const 0) (call $ne0)) - ) - (nop) - ) - (i32.const 1) - ) - (func $recurse-bool - (if - (if (result i32) - (i32.const 1) - (i32.ne (call $ne0) (i32.const 0)) - (i32.ne (call $ne1) (i32.const 0)) - ) - (nop) - ) - (if - (block (result i32) - (nop) - (i32.ne (call $ne0) (i32.const 0)) - ) - (nop) - ) - ) - (func $ne1 (result i32) - (unreachable) - ) - (func $load-off-2 "load-off-2" (param $0 i32) (result i32) - (i32.store offset=2 - (i32.add - (i32.const 1) - (i32.const 3) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (i32.const 3) - (i32.const 1) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (local.get $0) - (i32.const 5) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (i32.const 7) - (local.get $0) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (i32.const -11) ;; do not fold this! - (local.get $0) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (local.get $0) - (i32.const -13) ;; do not fold this! - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (i32.const -15) - (i32.const 17) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.add - (i32.const -21) - (i32.const 19) - ) - (local.get $0) - ) - (i32.store offset=2 - (i32.const 23) - (local.get $0) - ) - (i32.store offset=2 - (i32.const -25) - (local.get $0) - ) - (drop - (i32.load offset=2 - (i32.add - (i32.const 2) - (i32.const 4) - ) - ) - ) - (drop - (i32.load offset=2 - (i32.add - (i32.const 4) - (i32.const 2) - ) - ) - ) - (drop - (i32.load offset=2 - (i32.add - (local.get $0) - (i32.const 6) - ) - ) - ) - (drop - (i32.load offset=2 - (i32.const 8) - ) - ) - (i32.load offset=2 - (i32.add - (i32.const 10) - (local.get $0) - ) - ) - ) - (func $sign-ext (param $0 i32) (param $1 i32) - ;; eq of sign-ext to const, can be a zext - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 16) - ) - (i32.const 16) - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 5) ;; weird size, but still valid - ) - (i32.const 5) - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 100) ;; non-zero - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 32767) ;; non-zero and bigger than the mask, with sign bit - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const -149) ;; non-zero and bigger than the mask, without sign bit - ) - ) - ;; eq of two sign-ext, can both be a zext - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 16) - ) - (i32.const 16) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - ;; corner cases we should not opt - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 23) ;; different shift, smaller - ) - (i32.const 0) - ) - ) - (drop - (i32.eq - (i32.shr_u ;; unsigned - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 0) - ) - ) - (drop - (i32.lt_s ;; non-eq - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 0) - ) - ) - (drop - (if (result i32) - (i32.shr_s - (i32.shl - (unreachable) ;; ignore an unreachable value - (i32.const 16) - ) - (i32.const 16) - ) - (i32.const 111) - (i32.const 222) - ) - ) - ) - (func $sign-ext-input (param $0 i32) (param $1 i32) - (drop - (i32.shr_s - (i32.shl - (i32.const 100) ;; small! - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const 127) ;; just small enough - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const 128) ;; just too big - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) ;; who knows... - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (unreachable) ;; ignore - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.div_s ;; this could be optimizable in theory, but currently we don't look into adds etc. - (i32.const 1) - (i32.const 2) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.and ;; takes the min, here it is ok - (i32.const 127) - (i32.const 128) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.and ;; takes the min, here it is not - (i32.const 128) - (i32.const 129) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.xor ;; takes the max, here it is ok - (i32.const 127) - (i32.const 126) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.xor ;; takes the max, here it is not - (i32.const 127) - (i32.const 128) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.or ;; takes the max, here it is ok - (i32.const 127) - (i32.const 126) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.or ;; takes the max, here it is not - (i32.const 127) - (i32.const 128) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl ;; adds, here it is too much - (i32.const 32) - (i32.const 2) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl ;; adds, here it is ok - (i32.const 32) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl ;; adds, here it is too much and "overflows" - (i32.const 32) - (i32.const 35) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u ;; subtracts, here it is still too much - (i32.const 256) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u ;; subtracts, here it is ok - (i32.const 256) - (i32.const 2) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u ;; subtracts, here it "overflows" - (i32.const 128) - (i32.const 35) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_s ;; subtracts, here it is still too much - (i32.const 256) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_s ;; subtracts, here it is ok - (i32.const 256) - (i32.const 2) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_s ;; subtracts, here it "overflows" - (i32.const 128) - (i32.const 35) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_s ;; subtracts, here there is a sign bit, so it stays 32 bits no matter how much we shift - (i32.const -1) - (i32.const 32) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_s ;; subtracts, here we mask out that sign bit - (i32.and - (i32.const -1) - (i32.const 2147483647) - ) - (i32.const 31) ;; adjusted after we fixed shift computation to just look at lower 5 bits - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.ne ;; 1 bit - (i32.const -1) - (i32.const -1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (f32.le - (f32.const -1) - (f32.const -1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.clz ;; assumed 5 bits - (i32.const 0) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl - (i32.clz ;; assumed 5 bits - (i32.const 0) - ) - (i32.const 2) ;; + 2, so 7 - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl - (i32.clz ;; assumed 5 bits - (i32.const 0) - ) - (i32.const 3) ;; + 3, so 8, too much - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.wrap_i64 ;; preserves 6 - (i64.clz ;; assumed 6 bits - (i64.const 0) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl - (i32.wrap_i64 ;; preserves 6 - (i64.clz ;; assumed 6 bits - (i64.const 0) - ) - ) - (i32.const 1) ;; + 1, so 7 - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl - (i32.wrap_i64 ;; preserves 6 - (i64.clz ;; assumed 6 bits - (i64.const 0) - ) - ) - (i32.const 2) ;; + 2, so 8, too much - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.eqz ;; 1 bit - (i32.const -1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.wrap_i64 ;; down to 32 - (i64.const -1) ;; 64 - ) - (i32.const 24) ;; 32 - 24 = 8 - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.wrap_i64 ;; down to 32 - (i64.const -1) ;; 64 - ) - (i32.const 25) ;; 32 - 25 = 7, ok - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.wrap_i64 ;; stay 32 - (i64.extend_i32_s - (i32.const -1) - ) - ) - (i32.const 24) ;; 32 - 24 = 8 - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.wrap_i64 ;; stay 32 - (i64.extend_i32_s - (i32.const -1) - ) - ) - (i32.const 25) ;; 32 - 25 = 7, ok - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop ;; fuzz testcase - (i32.shr_s - (i32.shl - (i32.xor ;; should be 32 bits - (i32.le_u ;; 1 bit - (local.get $0) - (i32.const 2) - ) - (local.get $0) ;; unknown, so 32 bits - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $linear-sums (param $0 i32) (param $1 i32) - (drop - (i32.add - (i32.add - (local.get $1) - (i32.const 16) - ) - (i32.shl - (i32.add - (local.get $0) - (i32.const -1) ;; -16, so cancels out! - ) - (i32.const 4) - ) - ) - ) - (drop - (i32.add - (i32.add - (local.get $1) - (i32.const 20) - ) - (i32.shl - (i32.add - (local.get $0) - (i32.const -1) ;; -8, so sum is +12 - ) - (i32.const 3) - ) - ) - ) - (drop - (i32.add ;; simple sum - (i32.const 1) - (i32.const 3) - ) - ) - (drop - (i32.add ;; nested sum - (i32.add - (i32.const 1) - (i32.const 3) - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.add - (i32.const 1) - (i32.const 3) - ) - (i32.sub ;; internal sub - (i32.const 5) - (i32.const 3) - ) - ) - ) - (drop - (i32.sub ;; external sub - (i32.add - (i32.const 1) - (i32.const 3) - ) - (i32.add - (i32.const 5) - (i32.const 3) - ) - ) - ) - (drop - (i32.sub ;; external sub - (i32.add - (i32.const 1) - (i32.const 3) - ) - (i32.sub ;; and also internal sub - (i32.const 5) - (i32.const 3) - ) - ) - ) - (drop - (i32.add - (i32.add - (i32.const 1) - (i32.const 3) - ) - (i32.sub ;; negating sub - (i32.const 0) - (i32.const 3) - ) - ) - ) - (drop - (i32.add - (i32.sub - (i32.const 0) - (i32.sub ;; two negating subs - (i32.const 0) - (i32.add - (i32.const 3) - (i32.const 20) - ) - ) - ) - (i32.add - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.add - (i32.add - (i32.const 0) - (i32.sub ;; one negating sub - (i32.const 0) - (i32.add - (i32.const 3) - (i32.const 20) - ) - ) - ) - (i32.add - (i32.const 1) - (i32.const 2) - ) - ) - ) - (drop - (i32.add - (i32.shl ;; shifted value - (i32.const 1) - (i32.const 3) - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.shl ;; shifted value - (i32.const 1) - (local.get $0) ;; but not by const - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.shl ;; shifted nested value - (i32.sub - (local.get $1) - (i32.const 10) - ) - (i32.const 3) - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.mul ;; multiplied - (i32.const 10) - (i32.const 3) - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.mul ;; multiplied by nonconstant - can't recurse - (i32.const 10) - (local.get $0) - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.mul ;; nested mul - (i32.add - (i32.const 10) - (local.get $0) - ) - (i32.const 2) - ) - (i32.add - (i32.const 5) - (i32.const 9) - ) - ) - ) - (drop - (i32.add - (i32.add - (local.get $0) - (i32.const 10) ;; cancelled out with the below - ) - (i32.sub - (i32.const -5) - (i32.const 5) - ) - ) - ) - ) - (func $almost-sign-ext (param $0 i32) - (drop - (i32.shr_s - (i32.shl - (i32.const 100) ;; too big, there is a sign bit, due to the extra shift - (i32.const 25) - ) - (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift, in theory - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.const 50) ;; small enough, no sign bit - (i32.const 25) - ) - (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift - ) - ) - ) - (func $squaring (param $0 i32) (param $1 i32) - (drop - (i32.and - (i32.and - (local.get $0) - (i32.const 11) - ) - (i32.const 200) - ) - ) - (drop - (i32.and - (i32.and - (local.get $0) - (i32.const 11) - ) - (local.get $0) ;; non-const, cannot optimize this! - ) - ) - (drop - (i32.and - (i32.and - (i32.const 11) ;; flipped order - (local.get $0) - ) - (i32.const 200) - ) - ) - (drop - (i32.or - (i32.or - (local.get $0) - (i32.const 11) - ) - (i32.const 200) - ) - ) - (drop - (i32.shl - (i32.shl - (local.get $0) - (i32.const 11) - ) - (i32.const 200) - ) - ) - (drop - (i32.shr_s - (i32.shr_s - (local.get $0) - (i32.const 11) - ) - (i32.const 200) - ) - ) - (drop - (i32.shr_u - (i32.shr_u - (local.get $0) - (i32.const 11) - ) - (i32.const 200) - ) - ) - (drop - (i32.shr_u - (i32.shr_s ;; but do not optimize a mixture or different shifts! - (local.get $0) - (i32.const 11) - ) - (i32.const 200) - ) - ) - ) - (func $sign-ext-ne (param $0 i32) (param $1 i32) - ;; ne of sign-ext to const, can be a zext - (drop - (i32.ne - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 65000) - ) - ) - (drop - (i32.ne - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 64872) ;; no sign bit - ) - ) - (drop - (i32.ne - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const -149) ;; no sign bit, not all ones - ) - ) - (drop - (i32.ne - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 111) - ) - ) - (drop - (i32.ne - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - ) - (func $sign-ext-eqz (param $0 i32) (param $1 i32) - (drop - (i32.eqz - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - ) - (func $sign-ext-boolean (param $0 i32) (param $1 i32) - (drop - (if (result i32) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 100) - (i32.const 200) - ) - ) - ) - (func $add-sub-zero (param $0 i32) (param $1 i64) - (drop - (i32.add - (local.get $0) - (i32.const 0) - ) - ) - (drop - (i32.sub - (local.get $0) - (i32.const 0) - ) - ) - (drop - (i64.add - (local.get $1) - (i64.const 0) - ) - ) - (drop - (i64.sub - (local.get $1) - (i64.const 0) - ) - ) - ) - (func $store-signext (param $0 i32) - (i32.store8 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) ;; exact size we store, sign-ext of 8 bits - ) - (i32.const 24) - ) - ) - (i32.store8 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 25) ;; 7 bits. so the ext can alter a bit we store, do not optimize - ) - (i32.const 25) - ) - ) - (i32.store8 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 23) ;; 9 bits, this is good to optimize - ) - (i32.const 23) - ) - ) - (i32.store16 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 16) ;; exact size we store, sign-ext of 16 bits - ) - (i32.const 16) - ) - ) - (i32.store16 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 17) ;; 15 bits. so the ext can alter a bit we store, do not optimize - ) - (i32.const 17) - ) - ) - (i32.store16 - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 14) ;; 17 bits, this is good to optimize - ) - (i32.const 14) - ) - ) - (i32.store - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 16) ;; 4 bytes stored, do nothing - ) - (i32.const 16) - ) - ) - (i32.store - (i32.const 8) - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 8) ;; 4 bytes stored, do nothing - ) - (i32.const 8) - ) - ) - ) - (func $sign-ext-tee (param $0 i32) (param $1 i32) - (drop - (i32.shr_s - (i32.shl - (local.tee $0 - (i32.const 128) ;; too big - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.tee $0 - (i32.const 127) ;; just right - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $sign-ext-load (param $0 i32) (param $1 i32) - (drop - (i32.shr_s - (i32.shl - (i32.load8_s ;; one byte, so perfect - (i32.const 256) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.load8_s ;; one byte, but sexted to 32 - (i32.const 256) - ) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shr_u - (i32.load8_u ;; one byte, but reduced to 7 - (i32.const 256) - ) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.load16_s ;; two, so perfect - (i32.const 256) - ) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ;; through tees, we cannot alter the load sign - (drop - (i32.shr_s - (i32.shl - (local.tee $1 - (i32.load8_s - (i32.const 1) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.tee $1 - (i32.load8_u - (i32.const 1) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.and - (local.tee $1 - (i32.load8_s - (i32.const 1) - ) - ) - (i32.const 255) - ) - ) - (drop - (i32.and - (local.tee $1 - (i32.load8_u - (i32.const 1) - ) - ) - (i32.const 255) - ) - ) - ) - (func $mask-bits (param $0 i32) (param $1 i32) - (drop - (i32.and - (local.tee $0 - (i32.const 127) ;; 7 bits - ) - (i32.const 255) ;; mask 8, so we don't need this - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) ;; 8 bits - ) - (i32.const 255) ;; mask 8, so we don't need this - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 254) ;; improper mask, small - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 1279) ;; improper mask, large - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 1290) ;; improper mask, large - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 4095) ;; proper mask, huge - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 511) ;; proper mask, large - ) - ) - (drop - (i32.and - (local.tee $0 - (i32.const 128) - ) - (i32.const 127) ;; proper mask, just too small - ) - ) - ) - (func $local-info-zero-ext (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.const 212) ;; mask is unneeded, we are small - ) - (drop - (i32.and - (local.get $x) - (i32.const 255) - ) - ) - (local.set $y - (i32.const 500) ;; mask is needed, we are too big - ) - (drop - (i32.and - (local.get $y) - (i32.const 255) - ) - ) - (local.set $0 - (i32.const 212) ;; mask is unneeded, but we are a param, not a var, so no - ) - (drop - (i32.and - (local.get $0) - (i32.const 255) - ) - ) - (local.set $z - (i32.const 212) ;; mask is unneeded, we are small - ) - (local.set $z - (i32.const 220) ;; mask is still unneeded even with 2 uses - ) - (drop - (i32.and - (local.get $z) - (i32.const 255) - ) - ) - (local.set $w - (i32.const 212) ;; mask is unneeded, we are small - ) - (local.set $w - (i32.const 1000) ;; mask is needed, one use is too big - ) - (drop - (i32.and - (local.get $w) - (i32.const 255) - ) - ) - ) - (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.const 127) ;; mask is unneeded, we are small - ) - (drop - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $y - (i32.const 128) ;; mask is needed, we are too big - ) - (drop - (i32.shr_s - (i32.shl - (local.get $y) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $0 - (i32.const 127) ;; mask is unneeded, but we are a param, not a var, so no - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.const 127) ;; mask is unneeded, we are small - ) - (local.set $z - (i32.const 100) ;; mask is still unneeded even with 2 uses - ) - (drop - (i32.shr_s - (i32.shl - (local.get $z) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $w - (i32.const 127) ;; mask is unneeded, we are small - ) - (local.set $w - (i32.const 150) ;; mask is needed, one use is too big - ) - (drop - (i32.shr_s - (i32.shl - (local.get $w) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.shr_s - (i32.shl - (local.get $0) ;; already sign-exted here, so no need later - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $y - (i32.shr_s - (i32.shl - (local.get $0) ;; already sign-exted here, but wrong bit size - (i32.const 16) - ) - (i32.const 16) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $y) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $0 - (i32.shr_s - (i32.shl - (local.get $0) ;; already sign-exted here, so no need later, but we are a param - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $0) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.shr_s - (i32.shl - (local.get $0) ;; already sign-exted here, so no need later - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.shr_s - (i32.shl - (local.get $1) ;; already sign-exted here, so no need later - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $z) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $w - (i32.shr_s - (i32.shl - (local.get $0) ;; already sign-exted here, so no need later - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $w - (i32.shr_s - (i32.shl - (local.get $0) ;; not quite a sign-ext - (i32.const 23) - ) - (i32.const 24) - ) - ) - (drop - (i32.shr_s - (i32.shl - (local.get $w) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (drop ;; odd corner case - (i32.shr_s - (i32.shl - (local.get $0) ;; param, so we should know nothing - (i32.const 24) - ) - (i32.const 23) ;; different shift, smaller - ) - ) - ) - (func $signed-loads-fill-the-bits (param $$e i32) (result i32) - (local $$0 i32) - (local $$conv i32) - (local.set $$0 - (i32.load8_s ;; one byte, but 32 bits due to sign-extend - (i32.const 1024) - ) - ) - (local.set $$conv - (i32.and - (local.get $$0) - (i32.const 255) ;; so we need this zexting! - ) - ) - (return - (i32.eq - (local.get $$conv) - (local.get $$e) - ) - ) - ) - (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32) - (local $x i32) - (local $y i32) - (local $z i32) - (local $w i32) - (local.set $x - (i32.load8_s (i32.const 1024)) ;; 8 bits, sign extended, no need to do it again - ) - (drop - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $y - (i32.load8_u (i32.const 1024)) ;; 8 bits, zext, so bad - ) - (drop - (i32.shr_s - (i32.shl - (local.get $y) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (local.set $z - (i32.load16_s (i32.const 1024)) ;; 16 bits sign-extended, wrong size - ) - (drop - (i32.shr_s - (i32.shl - (local.get $z) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32) - (drop - (i32.eq - (i32.load8_s - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.load8_s - (local.get $0) ;; flip order, we should canonicalize - ) - ) - ) - (drop - (i32.eq - (i32.load8_u ;; unsigned, bad - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (drop - (i32.eq - (i32.load8_s - (local.get $0) - ) - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 16) ;; wrong size - ) - (i32.const 16) - ) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.load8_u ;; unsigned, bad - (local.get $0) - ) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $1) - (i32.const 16) ;; wrong size - ) - (i32.const 16) - ) - (i32.load8_s - (local.get $0) - ) - ) - ) - ) - (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32) - (i32.ne - (i32.shr_s - (i32.shl - (call $unsign-diff-sizes - (i32.const -1) - (i32.const 5) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.shr_s - (i32.shl - (call $unsign-diff-sizes - (i32.const 1) - (i32.const 2006) - ) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32) - (i32.ne - (i32.shr_s - (i32.shl - (call $unsign-same-sizes - (i32.const -1) - (i32.const 5) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.shr_s - (i32.shl - (call $unsign-same-sizes - (i32.const 1) - (i32.const 2006) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (func $fuzz-almost-sign-ext - (drop - (i32.shr_s - (i32.shl - (i32.load16_u - (i32.const 2278) - ) - (i32.const 17) - ) - (i32.const 16) - ) - ) - (drop - (i32.shr_s - (i32.shl - (i32.shl - (i32.load16_u - (i32.const 2278) - ) - (i32.const 1) - ) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - (func $fuzz-comp-impossible (param $x i32) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 16) - ) - (i32.const 16) - ) - (i32.const 65535) ;; impossible to be equal, the effective sign bit is set, but not the higher bits, which the sign-ext will set on the non-const value - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 255) - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 127) ;; safe - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 128) ;; unsafe again - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 4223) ;; more big bits, so sign bit though - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 4224) ;; more big bits - ) - ) - (drop - (i32.eq - (i32.shr_s - (i32.shl - (local.get $x) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const -4) ;; safe even with more big bits, as they are all 1s - ) - ) - ) - (func $if-parallel (param $0 i32) (param $1 i32) - (drop - (if (result i32) - (local.get $0) - (i32.add (local.get $1) (i32.const 1)) - (i32.add (local.get $1) (i32.const 1)) - ) - ) - (drop - (if (result i32) - (local.tee $0 (local.get $1)) ;; side effects! - (i32.add (local.get $1) (i32.const 1)) - (i32.add (local.get $1) (i32.const 1)) - ) - ) - (drop - (if (result i32) - (local.get $0) - (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if - (i32.add (local.get $1) (unreachable)) - ) - ) - (drop - (if (result i32) - (local.tee $0 (local.get $1)) ;; side effects! - (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if - (i32.add (local.get $1) (unreachable)) - ) - ) - (drop - (if (result i32) - (unreachable) ;; !!! - (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if - (i32.add (local.get $1) (unreachable)) - ) - ) - ) - (func $select-parallel (param $0 i32) (param $1 i32) - (drop - (select - (i32.add (local.get $1) (i32.const 1)) - (i32.add (local.get $1) (i32.const 1)) - (local.get $0) - ) - ) - (drop - (select - (local.tee $0 (local.get $1)) ;; side effects! - (local.tee $0 (local.get $1)) ;; side effects! - (local.get $0) - ) - ) - (drop - (select - (i32.add (local.get $1) (i32.const 1)) - (i32.add (local.get $1) (i32.const 1)) - (local.tee $0 (local.get $1)) ;; side effects! (but no interference with values) - ) - ) - (drop - (select - (local.tee $0 (local.get $1)) ;; side effects! interference! - (local.tee $0 (local.get $1)) ;; side effects! interference! - (local.tee $0 (local.get $1)) ;; side effects! interference! - ) - ) - (drop - (select - (local.tee $0 (local.get $1)) ;; side effects! - (local.tee $0 (local.get $1)) ;; side effects! - (unreachable) ;; side effects! (but no interference with values) - ) - ) - ) - (func $zero-shifts-is-not-sign-ext - (drop - (i32.eq - (i32.const -5431187) - (i32.add - (i32.const 0) - (i32.shr_s - (i32.shl - (i32.load16_s align=1 - (i32.const 790656516) - ) - (i32.const 0) - ) - (i32.const 0) - ) - ) - ) - ) - (drop - (i32.eq - (i32.const -5431187) - (i32.add - (i32.const 0) - (i32.shr_s - (i32.shl - (i32.load16_s align=1 - (i32.const 790656516) - ) - (i32.const 1) - ) - (i32.const 0) - ) - ) - ) - ) - ) - (func $zero-ops (result i32) - (return - (i32.eq - (i32.const -1337) - (i32.shr_u - (i32.add - (i32.const 0) - (i32.shr_s - (i32.shl - (i32.load16_s align=1 - (i32.const 790656516) - ) - (i32.const 0) - ) - (i32.const 0) - ) - ) - (i32.const 0) - ) - ) - ) - ) - (func $zero-ops-64 (result i32) - (return - (i64.eq - (i64.const -1337) - (i64.shr_u - (i64.add - (i64.const 0) - (i64.shr_s - (i64.shl - (i64.load16_s align=1 - (i32.const 790656516) - ) - (i64.const 0) - ) - (i64.const 0) - ) - ) - (i64.const 0) - ) - ) - ) - ) - (func $zero-ops-64-special (result i32) - (return - (i32.wrap_i64 - (i64.popcnt - (i64.sub - (i64.shl - (i64.const 4294783828) - (i64.const 17179869183) - ) - (i64.const -7377) - ) - ) - ) - ) - ) - (func $sign-ext-1-and-ne (result i32) - (select - (i32.ne - (i32.const 1333788672) - (i32.shr_s - (i32.shl - (call $sign-ext-1-and-ne) - (i32.const 1) - ) - (i32.const 1) - ) - ) - (i32.const 2) - (i32.const 1) - ) - ) - (func $neg-shifts-and-255 (result i32) - (i32.and - (i32.shr_u - (i32.const -99) - (i32.const -32) ;; this shift does nothing - ) - (i32.const 255) - ) - ) - (func $neg-shifts-and-255-b (result i32) - (i32.and - (i32.shl - (i32.const -2349025) - (i32.const -32) ;; this shift does nothing - ) - (i32.const 255) - ) - ) - (func $shifts-square-overflow (param $x i32) (result i32) - (i32.shr_u - (i32.shr_u - (local.get $x) - (i32.const 65535) ;; 31 bits effectively - ) - (i32.const 32767) ;; also 31 bits, so two shifts that force the value into nothing for sure - ) - ) - (func $shifts-square-no-overflow-small (param $x i32) (result i32) - (i32.shr_u - (i32.shr_u - (local.get $x) - (i32.const 1031) ;; 7 bits effectively - ) - (i32.const 4098) ;; 2 bits effectively - ) - ) - (func $shifts-square-overflow-64 (param $x i64) (result i64) - (i64.shr_u - (i64.shr_u - (local.get $x) - (i64.const 65535) ;; 63 bits effectively - ) - (i64.const 64767) ;; also 63 bits, so two shifts that force the value into nothing for sure - ) - ) - (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64) - (i64.shr_u - (i64.shr_u - (local.get $x) - (i64.const 1031) ;; 7 bits effectively - ) - (i64.const 4098) ;; 2 bits effectively - ) - ) - (func $shifts-square-unreachable (param $x i32) (result i32) - (i32.shr_u - (i32.shr_u - (unreachable) - (i32.const 1031) ;; 7 bits effectively - ) - (i32.const 4098) ;; 2 bits effectively - ) - ) - (func $mix-shifts (result i32) - (i32.shr_s - (i32.shl - (i32.const 23) - (i32.const -61) - ) - (i32.const 168) - ) - ) - (func $actually-no-shifts (result i32) - (i32.add - (i32.shl - (i32.const 23) - (i32.const 32) ;; really 0 - ) - (i32.const 10) - ) - ) - (func $less-shifts-than-it-seems (param $x i32) (result i32) - (i32.add - (i32.shl - (i32.const 200) - (i32.const 36) ;; really 4 - ) - (i32.shl - (i32.const 100) - (i32.const 4) - ) - ) - ) - (func $and-popcount32 (result i32) - (i32.and - (i32.popcnt - (i32.const -1) - ) - (i32.const 31) - ) - ) - (func $and-popcount32-big (result i32) - (i32.and - (i32.popcnt - (i32.const -1) - ) - (i32.const 63) - ) - ) - (func $and-popcount64 (result i64) ;; these are TODOs - (i64.and - (i64.popcnt - (i64.const -1) - ) - (i64.const 63) - ) - ) - (func $and-popcount64-big (result i64) - (i64.and - (i64.popcnt - (i64.const -1) - ) - (i64.const 127) - ) - ) - (func $and-popcount64-bigger (result i64) - (i64.and - (i64.popcnt - (i64.const -1) - ) - (i64.const 255) - ) - ) - (func $optimizeAddedConstants-filters-through-nonzero (result i32) - (i32.sub - (i32.add - (i32.shl - (i32.const -536870912) - (i32.wrap_i64 - (i64.const 0) - ) - ) - (i32.const -32768) - ) - (i32.const -1024) - ) - ) - (func $optimizeAddedConstants-filters-through-nonzero-b (result i32) - (i32.sub - (i32.add - (i32.shl - (i32.const -536870912) - (i32.wrap_i64 - (i64.const -1) - ) - ) - (i32.const -32768) - ) - (i32.const -1024) - ) - ) - (func $return-proper-value-from-shift-left-by-zero (result i32) - (if (result i32) - (i32.sub - (i32.add - (loop $label$0 (result i32) - (block $label$1 - (br_if $label$1 - (i32.shl - (i32.load - (i32.const 0) - ) - (i32.const -31904) ;; really 0 shifts - ) - ) - ) - (i32.const -62) - ) - (i32.const 38) - ) - (i32.const -2) - ) - (i32.const 1) - (i32.const 0) - ) - ) - (func $de-morgan-2 (param $x i32) (param $y i32) - (drop - (i32.and (i32.eqz (local.get $x)) (i32.eqz (local.get $y))) - ) - (drop - (i32.or (i32.eqz (local.get $x)) (i32.eqz (local.get $y))) - ) - (drop - (i32.xor (i32.eqz (local.get $x)) (i32.eqz (local.get $y))) - ) - (drop - (i32.and (i32.eqz (local.get $x)) (local.get $y)) - ) - (drop - (i32.and (local.get $x) (i32.eqz (local.get $y))) - ) - (drop - (i32.and (i32.eqz (local.get $x)) (i32.wrap_i64 (i64.const 2))) - ) - (drop - (i32.and (i32.wrap_i64 (i64.const 1)) (i32.eqz (local.get $y))) - ) - ) - (func $subzero1 (param $0 i32) (result i32) - (i32.add - (i32.sub - (i32.const 1) - (i32.clz - (local.get $0) - ) - ) - (i32.const 31) - ) - ) - (func $subzero2 (param $0 i32) (result i32) - (i32.add - (i32.const 31) - (i32.sub - (i32.const 1) - (i32.clz - (local.get $0) - ) - ) - ) - ) - (func $subzero3 (param $0 i32) (param $1 i32) (result i32) - (i32.add - (i32.sub - (i32.const 0) - (i32.clz - (local.get $0) - ) - ) - (local.get $1) - ) - ) - (func $subzero4 (param $0 i32) (param $1 i32) (result i32) - (i32.add - (local.get $0) - (i32.sub - (i32.const 0) - (i32.clz - (local.get $1) - ) - ) - ) - ) - (func $mul-32-power-2 (param $x i32) (result i32) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 4) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 5) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 1) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (call $mul-32-power-2 (i32.const 123)) ;; side effects - (i32.const 0) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 0xffffffff) - ) - ) - ) - (drop - (call $mul-32-power-2 - (i32.mul - (local.get $x) - (i32.const 0x80000000) - ) - ) - ) - (unreachable) - ) - (func $mul-64-power-2 (param $x i64) (result i64) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 4) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 5) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 1) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 0) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (call $mul-64-power-2 (i64.const 123)) ;; side effects - (i64.const 0) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 0xffffffffffffffff) - ) - ) - ) - (drop - (call $mul-64-power-2 - (i64.mul - (local.get $x) - (i64.const 0x8000000000000000) - ) - ) - ) - (unreachable) - ) - (func $div-32-power-2 (param $x i32) (result i32) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 4) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 5) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 1) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (call $div-32-power-2 (i32.const 123)) ;; side effects - (i32.const 0) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 0xffffffff) - ) - ) - ) - (drop - (call $div-32-power-2 - (i32.div_u - (local.get $x) - (i32.const 0x80000000) - ) - ) - ) - (unreachable) - ) - (func $urem-32-power-2 (param $x i32) (result i32) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 4) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 5) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 1) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 0xffffffff) - ) - ) - ) - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 0x80000000) - ) - ) - ) - ;; (unsigned)x % 1 - (drop - (call $urem-32-power-2 - (i32.rem_u - (local.get $x) - (i32.const 1) - ) - ) - ) - (unreachable) - ) - (func $fdiv-32-power-2 (param $x f32) - (drop (f32.div - (local.get $x) - (f32.const 2) - )) - (drop (f32.div - (local.get $x) - (f32.const -2) - )) - (drop (f32.div - (local.get $x) - (f32.const 4294967296) - )) - (drop (f32.div - (local.get $x) - (f32.const 18446744073709551616) - )) - (drop (f32.div - (local.get $x) - (f32.const 0x1p-126) - )) - (drop (f32.div - (local.get $x) - (f32.const 0x1p+126) - )) - (drop (f32.div - (local.get $x) - (f32.const -0x1p-126) - )) - (drop (f32.div - (local.get $x) - (f32.const -0x1p+126) - )) - (drop (f32.div - (local.get $x) - (f32.const 0x1p-127) ;; skip - )) - (drop (f32.div - (local.get $x) - (f32.const 0x1p-127) ;; skip - )) - (drop (f32.div - (local.get $x) - (f32.const 0) ;; skip - )) - (drop (f32.div - (local.get $x) - (f32.const nan) ;; skip - )) - (drop (f32.div - (local.get $x) - (f32.const inf) ;; skip - )) - (drop (f32.div - (local.get $x) - (f32.const -inf) ;; skip - )) - ) - (func $fdiv-64-power-2 (param $x f64) - (drop (f64.div - (local.get $x) - (f64.const 2) - )) - (drop (f64.div - (local.get $x) - (f64.const -2) - )) - (drop (f64.div - (local.get $x) - (f64.const 4294967296) - )) - (drop (f64.div - (local.get $x) - (f64.const 18446744073709551616) - )) - (drop (f64.div - (local.get $x) - (f64.const 0x1p-1022) - )) - (drop (f64.div - (local.get $x) - (f64.const 0x1p+1022) - )) - (drop (f64.div - (local.get $x) - (f64.const -0x1p-1022) - )) - (drop (f64.div - (local.get $x) - (f64.const -0x1p+1022) - )) - (drop (f64.div - (local.get $x) - (f64.const 0x1p-1023) ;; skip - )) - (drop (f64.div - (local.get $x) - (f64.const 0x1p+1023) ;; skip - )) - (drop (f64.div - (local.get $x) - (f64.const 0) ;; skip - )) - (drop (f64.div - (local.get $x) - (f64.const nan) ;; skip - )) - (drop (f64.div - (local.get $x) - (f64.const inf) ;; skip - )) - (drop (f64.div - (local.get $x) - (f64.const -inf) ;; skip - )) - ) - (func $srem-by-const (param $x i32) (param $y i64) - ;; (signed)x % 1 - (drop (i32.rem_s - (local.get $x) - (i32.const 1) - )) - (drop (i64.rem_s - (local.get $y) - (i64.const 1) - )) - ;; (signed)x % 0x80000000 -> x & 0x7FFFFFFF - (drop (i32.rem_s - (local.get $x) - (i32.const 0x80000000) - )) - ;; (signed)x % 0x8000000000000000 -> x & 0x7FFFFFFFFFFFFFFF - (drop (i64.rem_s - (local.get $y) - (i64.const 0x8000000000000000) - )) - ) - (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64) - ;; eqz((signed)x % 4) - (drop (i32.eqz - (i32.rem_s - (local.get $x) - (i32.const 4) - ) - )) - (drop (i64.eqz - (i64.rem_s - (local.get $y) - (i64.const 4) - ) - )) - ;; eqz((signed)x % -4) - (drop (i32.eqz - (i32.rem_s - (local.get $x) - (i32.const -4) - ) - )) - (drop (i64.eqz - (i64.rem_s - (local.get $y) - (i64.const -4) - ) - )) - ;; (signed)x % 4 == 0 - (drop (i32.eq - (i32.rem_s - (local.get $x) - (i32.const 4) - ) - (i32.const 0) - )) - (drop (i64.eq - (i64.rem_s - (local.get $y) - (i64.const 2) - ) - (i64.const 0) - )) - ;; (signed)x % -4 == 0 - (drop (i32.eq - (i32.rem_s - (local.get $x) - (i32.const -4) - ) - (i32.const 0) - )) - (drop (i64.eq - (i64.rem_s - (local.get $y) - (i64.const -4) - ) - (i64.const 0) - )) - ;; (signed)x % 2 != 0 - (drop (i32.ne - (i32.rem_s - (local.get $x) - (i32.const 2) - ) - (i32.const 0) - )) - (drop (i64.ne - (i64.rem_s - (local.get $y) - (i64.const 2) - ) - (i64.const 0) - )) - ;; (signed)x % -1 == 0 -> 0 == 0 - (drop (i32.eq - (i32.rem_s - (local.get $x) - (i32.const -1) - ) - (i32.const 0) - )) - ;; (signed)x % 0x80000000 == 0 - (drop (i32.eq - (i32.rem_s - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 0) - )) - ;; (signed)x % 0x80000000 != 0 - (drop (i32.ne - (i32.rem_s - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 0) - )) - ;; (signed)x % 0x8000000000000000 == 0 - (drop (i64.eq - (i64.rem_s - (local.get $y) - (i64.const 0x8000000000000000) - ) - (i64.const 0) - )) - ;; (signed)x % 0x8000000000000000 != 0 - (drop (i64.ne - (i64.rem_s - (local.get $y) - (i64.const 0x8000000000000000) - ) - (i64.const 0) - )) - ;; - (drop (i32.eq - (i32.rem_s - (local.get $x) - (i32.const 3) ;; skip - ) - (i32.const 0) - )) - (drop (i64.eq - (i64.rem_s - (local.get $y) - (i64.const 3) ;; skip - ) - (i64.const 0) - )) - ) - (func $orZero (param $0 i32) (result i32) - (i32.or - (local.get $0) - (i32.const 0) - ) - ) - (func $andZero (param $0 i32) (result i32) - (drop - (i32.and - (local.get $0) - (i32.const 0) - ) - ) - (drop - (i32.and - (call $andZero (i32.const 1234)) ;; side effects - (i32.const 0) - ) - ) - (unreachable) - ) - (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64) - (drop - (i32.or - (i32.const 0) - (local.get $x32) - ) - ) - (drop - (i32.shl - (local.get $x32) - (i32.const 0) - ) - ) - (drop - (i32.shr_u - (local.get $x32) - (i32.const 0) - ) - ) - (drop - (i32.shr_s - (local.get $x32) - (i32.const 0) - ) - ) - (drop - (i64.or - (i64.const 0) - (local.get $x64) - ) - ) - (drop - (i64.shl - (local.get $x64) - (i64.const 0) - ) - ) - (drop - (i64.shr_u - (local.get $x64) - (i64.const 0) - ) - ) - (drop - (i64.shr_s - (local.get $x64) - (i64.const 0) - ) - ) - (drop - (i32.mul - (local.get $x32) - (i32.const 0) - ) - ) - (drop - (i64.mul - (local.get $x64) - (i64.const 0) - ) - ) - (drop - (f32.mul - (local.get $y32) - (f32.const 0) - ) - ) - (drop - (f64.mul - (local.get $y64) - (f64.const 0) - ) - ) - (drop - (i32.mul - (local.get $x32) - (i32.const 1) - ) - ) - (drop - (i64.mul - (local.get $x64) - (i64.const 1) - ) - ) - (drop - (f32.mul - (local.get $y32) - (f32.const 1) - ) - ) - (drop - (f64.mul - (local.get $y64) - (f64.const 1) - ) - ) - (drop - (i32.and - (local.get $x32) - (i32.const 0) - ) - ) - (drop - (i64.and - (local.get $x64) - (i64.const 0) - ) - ) - (drop - (i32.and - (unreachable) - (i32.const 0) - ) - ) - (drop - (i64.and - (unreachable) - (i64.const 0) - ) - ) - (drop - (i32.div_s - (local.get $x32) - (i32.const 1) - ) - ) - (drop - (i32.div_u - (local.get $x32) - (i32.const 1) - ) - ) - (drop - (i64.div_s - (local.get $x64) - (i64.const 1) - ) - ) - (drop - (i64.div_u - (local.get $x64) - (i64.const 1) - ) - ) - (drop - (f32.div - (local.get $y32) - (f32.const 1) - ) - ) - (drop - (f64.div - (local.get $y64) - (f64.const 1) - ) - ) - (drop - (f32.div - (local.get $y32) - (f32.const 1.2) - ) - ) - (drop - (i32.mul - (local.get $x32) - (i32.const -1) - ) - ) - (drop - (i64.mul - (local.get $x64) - (i64.const -1) - ) - ) - (drop - (f32.mul - (local.get $y32) - (f32.const -1) - ) - ) - (drop - (f64.mul - (local.get $y64) - (f64.const -1) - ) - ) - (drop - (i32.eq - (i32.add - (local.get $x32) - (i32.const 10) - ) - (i32.const 20) - ) - ) - (drop - (i32.le_u - (i32.add - (local.get $x32) - (i32.const 10) - ) - (i32.const 20) - ) - ) - (drop - (i32.eq - (i32.sub - (local.get $x32) - (i32.const 10) - ) - (i32.const 20) - ) - ) - (drop - (i64.eq - (i64.add - (local.get $x64) - (i64.const 10) - ) - (i64.const 20) - ) - ) - (drop - (i32.eq - (i32.const 20) - (i32.add - (local.get $x32) - (i32.const 10) - ) - ) - ) - (drop - (i32.eq - (i32.add - (local.get $x32) - (i32.const 10) - ) - (i32.add - (local.get $x32) - (i32.const 20) - ) - ) - ) - (drop - (i32.eq - (i32.sub - (local.get $x32) - (i32.const 10) - ) - (i32.const 20) - ) - ) - (drop - (i32.eq - (i32.add - (local.get $x32) - (i32.const 10) - ) - (i32.sub - (local.get $x32) - (i32.const 20) - ) - ) - ) - (drop - (i32.eq - (i32.sub - (local.get $x32) - (i32.const 10) - ) - (i32.add - (local.get $x32) - (i32.const 20) - ) - ) - ) - (drop - (i32.eq - (i32.sub - (local.get $x32) - (i32.const 10) - ) - (i32.sub - (local.get $x32) - (i32.const 20) - ) - ) - ) - (drop - (i64.le_s - (i64.sub - (local.get $x64) - (i64.const 288230376151711744) - ) - (i64.const 9223372036854775807) - ) - ) - ) - (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32) - (drop (i32.add (local.get $x) (i32.const 0x40))) - (drop (i32.sub (local.get $x) (i32.const 0x40))) - (drop (i32.add (local.get $x) (i32.const 0x2000))) - (drop (i32.add (local.get $x) (i32.const 0x100000))) - (drop (i32.add (local.get $x) (i32.const 0x8000000))) - - (drop (i64.add (local.get $y) (i64.const 0x40))) - (drop (i64.sub (local.get $y) (i64.const 0x40))) - (drop (i64.add (local.get $y) (i64.const 0x2000))) - (drop (i64.add (local.get $y) (i64.const 0x100000))) - (drop (i64.add (local.get $y) (i64.const 0x8000000))) - - (drop (i64.add (local.get $y) (i64.const 0x400000000))) - (drop (i64.add (local.get $y) (i64.const 0x20000000000))) - (drop (i64.add (local.get $y) (i64.const 0x1000000000000))) - (drop (i64.add (local.get $y) (i64.const 0x80000000000000))) - (drop (i64.add (local.get $y) (i64.const 0x4000000000000000))) - - (drop (f32.add (local.get $z) (f32.const 0x40))) - ) - (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32) - (drop - (i32.shl - (i32.const 0) - (local.get $x) - ) - ) - (drop - (i32.shr_u - (i32.const 0) - (local.get $x) - ) - ) - (drop - (i32.shr_s - (i32.const 0) - (local.get $x) - ) - ) - (drop - (i64.shl - (i64.const 0) - (local.get $y) - ) - ) - (drop - (i32.shl - (i32.const 0) - (unreachable) - ) - ) - ) - (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32) - (drop - (i32.sub - (local.get $x) - (local.get $x) - ) - ) - (drop - (i64.sub - (local.get $y) - (local.get $y) - ) - ) - (drop - (f64.sub - (local.get $z) - (local.get $z) - ) - ) - (drop - (i32.sub - (local.get $x) - (local.get $xx) - ) - ) - (drop - (i32.sub - (unreachable) - (unreachable) - ) - ) - (drop - (i32.add - (local.get $x) - (local.get $x) - ) - ) - ;; more ops - (drop - (i32.xor - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.ne - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.lt_s - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.lt_u - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.gt_s - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.gt_u - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.and - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.or - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.eq - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.le_s - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.le_u - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.ge_s - (local.get $x) - (local.get $x) - ) - ) - (drop - (i32.ge_u - (local.get $x) - (local.get $x) - ) - ) - (drop - (i64.xor - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.ne - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.lt_s - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.lt_u - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.gt_s - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.gt_u - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.and - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.or - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.eq - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.le_s - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.le_u - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.ge_s - (local.get $y) - (local.get $y) - ) - ) - (drop - (i64.ge_u - (local.get $y) - (local.get $y) - ) - ) - ) - (func $all_ones (param $x i32) (param $y i64) - (drop - (i32.and - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i32.or - (local.get $x) - (i32.const -1) - ) - ) - (drop - (i32.or - (local.tee $x - (i32.const 1337) - ) - (i32.const -1) - ) - ) - (drop - (i64.and - (local.get $y) - (i64.const -1) - ) - ) - (drop - (i64.or - (local.get $y) - (i64.const -1) - ) - ) - ) - (func $xor (param $x i32) (param $y i64) - (drop - (i32.xor - (local.get $x) - (i32.const 0) - ) - ) - ) - (func $select-on-const (param $x i32) (param $y i64) - (drop - (select - (i32.const 2) - (local.get $x) - (i32.const 0) - ) - ) - (drop - (select - (i32.const 3) - (local.get $x) - (i32.const 1) - ) - ) - (drop - (select - (i32.const 4) - (local.tee $x - (i32.const 5) - ) - (i32.const 0) - ) - ) - (drop - (select - (local.tee $x - (i32.const 6) - ) - (i32.const 7) - (i32.const 0) - ) - ) - (drop - (select - (i32.const 4) - (local.tee $x - (i32.const 5) - ) - (i32.const 1) - ) - ) - (drop - (select - (local.tee $x - (i32.const 6) - ) - (i32.const 7) - (i32.const 1) - ) - ) - (drop - (select - (i32.const 1) - (i32.const 0) - (local.get $x) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 1) - (local.get $x) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 1) - (i32.lt_s - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (select - (i32.const 1) - (i32.const 0) - (i32.lt_s - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 1) - (i32.ge_s - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (select - (i32.const 1) - (i32.const 0) - (i32.gt_s - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (select - (i32.const 0) - (i32.const 1) - (i32.gt_s - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (select - (i32.const 1) - (i32.const 0) - (i32.ge_s - (local.get $x) - (i32.const 0) - ) - ) - ) - (drop - (select - (i64.const 1) - (i64.const 0) - (local.get $x) - ) - ) - (drop - (select - (i64.const 0) - (i64.const 1) - (local.get $x) - ) - ) - (drop - (select - (i64.const 1) - (i64.const 0) - (i64.eqz - (local.get $y) - ) - ) - ) - (drop - (select - (i64.const 0) - (i64.const 1) - (i64.eqz - (local.get $y) - ) - ) - ) - (drop - (select - (i64.const 0) - (i64.const 1) - (i64.lt_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (select - (i64.const 1) - (i64.const 0) - (i64.lt_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (select - (i64.const 0) - (i64.const 1) - (i64.ge_s - (local.get $y) - (i64.const 0) - ) - ) - ) - (drop - (select - (i64.const 1) - (i64.const 0) - (i64.ge_s - (local.get $y) - (i64.const 0) - ) - ) - ) - ;; optimize boolean - (drop - (select - (local.get $x) - (i32.const 0) - (i32.eqz - (i32.const 0) - ) - ) - ) - (drop - (select - (local.get $x) - (i32.const 2) - (i32.eqz - (i32.const 2) - ) - ) - ) - (drop - (select - (local.get $x) - (i32.const 2) - (i32.eqz - (i32.eqz - (local.get $x) - ) - ) - ) - ) - (drop - (select - (local.get $y) - (i64.const 0) - (i64.eqz - (i64.const 0) - ) - ) - ) - (drop - (select - (local.get $y) - (i64.const 2) - (i64.eqz - (i64.const 2) - ) - ) - ) - ) - (func $optimize-boolean (param $x i32) (param $y i64) - ;; bool(-x) -> bool(x) - (drop - (select - (i32.const 1) - (i32.const 2) - (i32.sub - (i32.const 0) - (local.get $x) - ) - ) - ) - ;; i32(bool(expr)) == 1 -> bool(expr) - (drop (i32.eq - (i32.and - (local.get $x) - (i32.const 1) - ) - (i32.const 1) - )) - ;; i32(bool(expr)) != 1 -> !bool(expr) - (drop (i32.ne - (i32.and - (local.get $x) - (i32.const 1) - ) - (i32.const 1) - )) - ;; i64(bool(expr)) != 0 -> i32(bool(expr)) - (drop (i64.ne - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - (i64.const 0) - )) - ;; eqz((i32(bool(expr)) != 0) != 0) - (drop (i32.eqz - (i32.ne - (i32.ne - (i32.shr_u - (local.get $x) - (i32.const 31) - ) - (i32.const 0) - ) - (i32.const 0) - ) - )) - ;; i32.eqz(wrap(i64(x))) - (drop (i32.eqz - (i32.wrap_i64 - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - ) - )) - ;; eqz((i64(bool(expr)) != 0) != 0) - (drop (i32.eqz - (i32.ne - (i64.ne - (i64.shr_u - (local.get $y) - (i64.const 63) - ) - (i64.const 0) - ) - (i32.const 0) - ) - )) - ;; eqz((i64(bool(expr)) != 0) != 0) - (drop (i32.eqz - (i32.ne - (i64.ne - (local.get $y) - (i64.const 0) - ) - (i32.const 0) - ) - )) - ;; i32.eqz(wrap(i64(x))) -> skip - (drop (i32.eqz - (i32.wrap_i64 - (local.get $y) - ) - )) - ;; i64(bool(expr)) == 1 -> i32(bool(expr)) - (drop (i64.eq - (i64.and - (local.get $y) - (i64.const 1) - ) - (i64.const 1) - )) - ;; i64(bool(expr)) != 1 -> !i64(bool(expr)) - (drop (i64.ne - (i64.and - (local.get $y) - (i64.const 1) - ) - (i64.const 1) - )) - ;; i32(bool(expr)) & 1 -> bool(expr) - (drop (i32.and - (i32.and - (local.get $x) - (i32.const 1) - ) - (i32.const 1) - )) - ;; i32(bool(expr)) | 1 -> 1 - (drop (i32.or - (i32.and - (local.get $x) - (i32.const 1) - ) - (i32.const 1) - )) - ;; i64(bool(expr)) & 1 -> i64(bool(expr)) - (drop (i64.and - (i64.and - (local.get $y) - (i64.const 1) - ) - (i64.const 1) - )) - ;; i64(bool(expr)) | 1 -> 1 - (drop (i64.or - (i64.and - (local.get $y) - (i64.const 1) - ) - (i64.const 1) - )) - ;; i32(bool(expr)) != 0 -> i32(bool(expr)) - (drop (i32.ne - (i32.and - (local.get $x) - (i32.const 1) - ) - (i32.const 0) - )) - ;; i32(bool(expr)) != 0 -> i32(bool(expr)) - (drop (i32.ne - (i64.ne - (local.get $y) - (i64.const 0) - ) - (i32.const 0) - )) - ;; (i32(expr) != 0) != 0 -> (expr != 0) - (drop (i32.ne - (i32.ne - (local.get $x) - (i32.const 0) - ) - (i32.const 0) - )) - ;; (signed)x % 4 ? 1 : 0 - (drop (if (result i32) - (i32.rem_s - (local.get $x) - (i32.const 4) - ) - (i32.const 1) - (i32.const 0) - )) - ;; (signed)x % min_s ? 1 : 0 - (drop (if (result i32) - (i32.rem_s - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 1) - (i32.const 0) - )) - ) - (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64) - ;; ~(1 << x) -> rotl(-2, x) - (drop (i32.xor - (i32.shl - (i32.const 1) - (local.get $x) - ) - (i32.const -1) - )) - (drop (i64.xor - (i64.shl - (i64.const 1) - (local.get $z) - ) - (i64.const -1) - )) - ) - (func $getFallthrough ;; unit tests for Properties::getFallthrough - (local $x0 i32) - (local $x1 i32) - (local $x2 i32) - (local $x3 i32) - (local $x4 i32) - (local $x5 i32) - (local $x6 i32) - (local $x7 i32) - ;; the trivial case - (local.set $x0 (i32.const 1)) - (drop (i32.and (local.get $x0) (i32.const 7))) - ;; tees - (local.set $x1 (local.tee $x2 (i32.const 1))) - (drop (i32.and (local.get $x1) (i32.const 7))) - ;; loop - (local.set $x3 (loop (result i32) (i32.const 1))) - (drop (i32.and (local.get $x3) (i32.const 7))) - ;; if - two sides, can't - (local.set $x4 (if (result i32) (i32.const 1) (i32.const 2) (i32.const 3))) - (drop (i32.and (local.get $x4) (i32.const 7))) - ;; if - one side, can - (local.set $x5 (if (result i32) (i32.const 1) (unreachable) (i32.const 3))) - (drop (i32.and (local.get $x5) (i32.const 7))) - ;; if - one side, can - (local.set $x6 (if (result i32) (i32.const 1) (i32.const 3) (unreachable))) - (drop (i32.and (local.get $x6) (i32.const 7))) - ;; br_if with value - (drop - (block $out (result i32) - (local.set $x7 (br_if $out (i32.const 1) (i32.const 1))) - (drop (i32.and (local.get $x7) (i32.const 7))) - (unreachable) - ) - ) - ) - (func $tee-with-unreachable-value (result f64) - (local $var$0 i32) - (block $label$1 (result f64) - (local.tee $var$0 - (br_if $label$1 ;; the f64 does not actually flow through this, it's unreachable (and the type is wrong - but unchecked) - (f64.const 1) - (unreachable) - ) - ) - ) - ) - (func $add-sub-zero-reorder-1 (param $temp i32) (result i32) - (i32.add - (i32.add - (i32.sub - (i32.const 0) ;; this zero looks like we could remove it by subtracting the get of $temp from the parent, but that would reorder it *after* the tee :( - (local.get $temp) - ) - (local.tee $temp ;; cannot move this tee before the get - (i32.const 1) - ) - ) - (i32.const 2) - ) - ) - (func $add-sub-zero-reorder-2 (param $temp i32) (result i32) - (i32.add - (i32.add - (local.tee $temp ;; in this order, the tee already comes first, so all is good for the optimization - (i32.const 1) - ) - (i32.sub - (i32.const 0) - (local.get $temp) - ) - ) - (i32.const 2) - ) - ) - (func $const-float-zero (param $fx f32) (param $fy f64) - ;; x - 0.0 ==> x - (drop (f32.sub - (local.get $fx) - (f32.const 0) - )) - (drop (f64.sub - (local.get $fy) - (f64.const 0) - )) - ;; x + (-0.0) ==> x - (drop (f32.add - (local.get $fx) - (f32.const -0) - )) - (drop (f64.add - (local.get $fy) - (f64.const -0) - )) - ;; x - (-0.0) ==> x + 0.0 - (drop (f32.sub - (local.get $fx) - (f32.const -0) ;; skip - )) - (drop (f64.sub - (local.get $fy) - (f64.const -0) ;; skip - )) - ;; 0.0 - x ==> 0.0 - x - (drop (f32.sub - (f32.const 0) - (local.get $fx) ;; skip - )) - (drop (f64.sub - (f64.const 0) - (local.get $fy) ;; skip - )) - ;; x + 0.0 ==> x + 0.0 - (drop (f32.add - (local.get $fx) ;; skip - (f32.const 0) - )) - (drop (f64.add - (local.get $fy) ;; skip - (f64.const 0) - )) - (drop (f32.sub - (f32.const -nan:0x34546d) ;; skip - (f32.const 0) - )) - ) - (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) - (drop (i32.sub - (local.get $x) - (i32.const -1) - )) - (drop (i64.sub - (local.get $y) - (i64.const -1) - )) - ;; (unsigned)x > -1 ==> 0 - (drop (i32.gt_u - (local.get $x) - (i32.const -1) - )) - (drop (i64.gt_u - (local.get $y) - (i64.const -1) - )) - (drop (i32.gt_s - (local.get $x) - (i32.const -1) - )) - (drop (i64.gt_s - (local.get $y) - (i64.const -1) - )) - (drop (i64.extend_i32_s - (i64.gt_u - (i64.const 0) - (i64.const -1) - ) - )) - ;; (unsigned)x <= -1 ==> 1 - (drop (i32.le_u - (local.get $x) - (i32.const -1) - )) - (drop (i64.le_u - (local.get $y) - (i64.const -1) - )) - (drop (i32.le_s - (local.get $x) - (i32.const -1) - )) - (drop (i64.le_s - (local.get $y) - (i64.const -1) - )) - ;; (unsigned)x >= -1 ==> x == -1 - (drop (i32.ge_u - (local.get $x) - (i32.const -1) - )) - (drop (i64.ge_u - (local.get $y) - (i64.const -1) - )) - ;; (unsigned)x < -1 ==> x != -1 - (drop (i32.lt_u - (local.get $x) - (i32.const -1) - )) - (drop (i64.lt_u - (local.get $y) - (i64.const -1) - )) - ;; x * -1 - (drop (i32.mul - (local.get $x) - (i32.const -1) - )) - (drop (i64.mul - (local.get $y) - (i64.const -1) - )) - (drop (f32.mul ;; skip - (local.get $fx) - (f32.const -1) - )) - (drop (f64.mul ;; skip - (local.get $fy) - (f64.const -1) - )) - ;; (unsigned)x / -1 - (drop (i32.div_u - (local.get $x) - (i32.const -1) - )) - (drop (i64.div_u - (local.get $y) - (i64.const -1) - )) - ) - (func $rhs-is-const (param $x i32) (param $y i64) (param $fx f32) (param $fy f64) - ;; signed divs - ;; i32(x) / -2147483648 -> x == -2147483648 - (drop (i32.div_s - (local.get $x) - (i32.const -2147483648) - )) - ;; i64(x) / -9223372036854775808 -> x == -9223372036854775808 - (drop (i64.div_s - (local.get $y) - (i64.const -9223372036854775808) - )) - ;; skip - (drop (i64.div_s - (local.get $y) - (i64.const -2147483648) - )) - - ;; unsigned divs - ;; u32(x) / -2 => x >= -2 - (drop (i32.div_u - (local.get $x) - (i32.const -2) - )) - ;; u32(x) / -1 => x == -1 - (drop (i32.div_u - (local.get $x) - (i32.const -1) - )) - ;; u32(x) / (i32.min + 1) - (drop (i32.div_u - (local.get $x) - (i32.const -2147483647) - )) - ;; u32(x) / i32.min => x >>> 31 - (drop (i32.div_u - (local.get $x) - (i32.const -2147483648) - )) - ;; u64(x) / -1 => u64(x == -1) - (drop (i64.div_u - (local.get $y) - (i64.const -1) - )) - ;; u64(x) / i64.min => x >>> 63 - (drop (i64.div_u - (local.get $y) - (i64.const -9223372036854775808) - )) - - ;; (unsigned)x >= 0 => i32(1) - (drop (i32.ge_u - (local.get $x) - (i32.const 0) - )) - (drop (i64.ge_u - (local.get $y) - (i64.const 0) - )) - - ;; (unsigned)x < 0 => i32(0) - (drop (i32.lt_u - (local.get $x) - (i32.const 0) - )) - (drop (i64.lt_u - (local.get $y) - (i64.const 0) - )) - - ;; (unsigned)x > 0 => x != 0 - (drop (i32.gt_u - (local.get $x) - (i32.const 0) - )) - (drop (i64.gt_u - (local.get $y) - (i64.const 0) - )) - - ;; (unsigned)x <= 0 => x == 0 - (drop (i32.le_u - (local.get $x) - (i32.const 0) - )) - (drop (i64.le_u - (local.get $y) - (i64.const 0) - )) - - ;; i32(x) <= 0x7fffffff => i32(1) - (drop (i32.le_s - (local.get $x) - (i32.const 0x7fffffff) - )) - ;; i64(x) <= 0x7fffffffffffffff => i32(1) - (drop (i64.le_s - (local.get $y) - (i64.const 0x7fffffffffffffff) - )) - - ;; i32(x) >= 0x80000000 => i32(1) - (drop (i32.ge_s - (local.get $x) - (i32.const 0x80000000) - )) - ;; i64(x) >= 0x8000000000000000 => i32(1) - (drop (i64.ge_s - (local.get $y) - (i64.const 0x8000000000000000) - )) - - ;; i32(x) < 0x80000000 => 0 - (drop (i32.lt_s - (local.get $x) - (i32.const 0x80000000) - )) - ;; i64(x) < 0x8000000000000000 => 0 - (drop (i64.lt_s - (local.get $y) - (i64.const 0x8000000000000000) - )) - - ;; i32(x) > 0x7fffffff => 0 - (drop (i32.gt_s - (local.get $x) - (i32.const 0x7fffffff) - )) - ;; i64(x) > 0x7fffffffffffffff => 0 - (drop (i64.gt_s - (local.get $y) - (i64.const 0x7fffffffffffffff) - )) - - ;; i32(x) < 0x7fffffff => x != 0x7fffffff - (drop (i32.lt_s - (local.get $x) - (i32.const 0x7fffffff) - )) - ;; i64(x) < 0x7fffffffffffffff => x != 0x7fffffffffffffff - (drop (i64.lt_s - (local.get $y) - (i64.const 0x7fffffffffffffff) - )) - - ;; i32(x) > 0x80000000 => x != 0x80000000 - (drop (i32.gt_s - (local.get $x) - (i32.const 0x80000000) - )) - ;; i64(x) > 0x8000000000000000 => x != 0x8000000000000000 - (drop (i64.gt_s - (local.get $y) - (i64.const 0x8000000000000000) - )) - - ;; i32(x) <= 0x80000000 => x == 0x80000000 - (drop (i32.le_s - (local.get $x) - (i32.const 0x80000000) - )) - ;; i64(x) <= 0x8000000000000000 => x == 0x8000000000000000 - (drop (i64.le_s - (local.get $y) - (i64.const 0x8000000000000000) - )) - - ;; i32(x) >= 0x7fffffff => x == 0x7fffffff - (drop (i32.ge_s - (local.get $x) - (i32.const 0x7fffffff) - )) - ;; i64(x) >= 0x7fffffffffffffff => x == 0x7fffffffffffffff - (drop (i64.ge_s - (local.get $y) - (i64.const 0x7fffffffffffffff) - )) - - ;; -x * 1 => x * -1 - (drop (f32.mul - (f32.neg - (local.get $fx) - ) - (f32.const 1) - )) - ;; -x * -2.1 => x * 2.1 - (drop (f64.mul - (f64.neg - (local.get $fy) - ) - (f64.const -2.1) - )) - ;; 2 * -x => x * -2 - (drop (f64.mul - (f64.const 2) - (f64.neg - (local.get $fy) - ) - )) - ;; -x / inf => x / -inf - (drop (f32.div - (f32.neg - (local.get $fx) - ) - (f32.const inf) - )) - ;; -x / -0.0 => x / 0.0 - (drop (f64.div - (f64.neg - (local.get $fy) - ) - (f64.const -0.0) - )) - ;; -x / nan => x / -nan - (drop (f64.div - (f64.neg - (local.get $fy) - ) - (f64.const nan) - )) - ;; 5.0 / -x => -5 / x - (drop (f64.div - (f64.const 5) - (f64.neg - (local.get $fy) - ) - )) - ) - (func $lhs-is-neg-one (param $x i32) (param $y i64) - ;; -1 >> x ==> -1 - (drop (i32.shr_s - (i32.const -1) - (local.get $x) - )) - (drop (i64.shr_s - (i64.const -1) - (local.get $y) - )) - ;; rotl(-1, x) ==> -1 - (drop (i32.rotl - (i32.const -1) - (local.get $x) - )) - (drop (i64.rotl - (i64.const -1) - (local.get $y) - )) - ;; rotr(-1, x) ==> -1 - (drop (i32.rotr - (i32.const -1) - (local.get $x) - )) - (drop (i64.rotr - (i64.const -1) - (local.get $y) - )) - ;; skip - (drop (i32.shr_s - (i32.const -1) - (call $ne0) ;; side effect - )) - ;; skip - (drop (i32.shr_u - (i32.const -1) - (local.get $x) - )) - ) - (func $lhs-is-const (param $x i32) (param $y i64) - ;; 0 - (x - 1) - (drop (i32.sub - (i32.const 0) - (i32.sub - (local.get $x) - (i32.const 1) - ) - )) - (drop (i64.sub - (i64.const 0) - (i64.sub - (local.get $y) - (i64.const 1) - ) - )) - ;; -1 - (x + 1) - (drop (i32.sub - (i32.const -1) - (i32.add - (local.get $x) - (i32.const 1) - ) - )) - (drop (i64.sub - (i64.const -1) - (i64.add - (local.get $y) - (i64.const 1) - ) - )) - ;; 1 - (2 - x) - (drop (i32.sub - (i32.const 1) - (i32.sub - (i32.const 2) - (local.get $x) - ) - )) - (drop (i64.sub - (i64.const 1) - (i64.sub - (i64.const 2) - (local.get $y) - ) - )) - ;; 0 - (0x80000000 - x) - (drop (i32.sub - (i32.const 0) - (i32.sub - (i32.const 0x80000000) - (local.get $x) - ) - )) - ) - (func $pre-combine-or (param $x i32) (param $y i32) - (drop (i32.or - (i32.gt_s - (local.get $x) - (local.get $y) - ) - (i32.eq - (local.get $y) ;; ordering should not stop us - (local.get $x) - ) - )) - (drop (i32.or - (i32.eq ;; ordering should not stop us - (local.get $y) - (local.get $x) - ) - (i32.gt_s - (local.get $x) - (local.get $y) - ) - )) - (drop (i32.or - (i32.gt_s - (local.get $x) - (local.get $y) - ) - (i32.eq - (local.get $x) - (i32.const 1) ;; not equal - ) - )) - (drop (i32.or - (i32.gt_s - (local.get $x) - (i32.const 1) ;; not equal - ) - (i32.eq - (local.get $x) - (local.get $y) - ) - )) - (drop (i32.or - (i32.gt_s - (call $ne0) ;; side effects - (local.get $y) - ) - (i32.eq - (call $ne0) - (local.get $y) - ) - )) - (drop (i32.or - (i32.gt_s - (local.get $y) - (call $ne0) ;; side effects - ) - (i32.eq - (local.get $y) - (call $ne0) - ) - )) - ) - (func $combine-or (param $x i32) (param $y i32) - (drop (i32.or - (i32.gt_s - (local.get $x) - (local.get $y) - ) - (i32.eq - (local.get $x) - (local.get $y) - ) - )) - ;; TODO: more stuff here - ) - (func $select-into-arms (param $x i32) (param $y i32) - (if - (select - (i32.eqz (i32.eqz (local.get $x))) - (i32.eqz (i32.eqz (local.get $y))) - (local.get $y) - ) - (unreachable) - ) - ) - (func $optimize-boolean-context (param $x i32) (param $y i32) - ;; 0 - x ==> x - (if - (i32.sub - (i32.const 0) - (local.get $x) - ) - (unreachable) - ) - (drop (select - (local.get $x) - (local.get $y) - (i32.sub - (i32.const 0) - (local.get $x) - ) - )) - ) - (func $optimize-relationals (param $x i32) (param $y i32) (param $X i64) (param $Y i64) - ;; eqz(x + 0x7FFFFFFF) -> x == -2147483647 - (drop (i32.eqz - (i32.add - (local.get $x) - (i32.const 0x7FFFFFFF) - ) - )) - ;; eqz(x + 0x80000000) -> x == -2147483648 - (drop (i32.eqz - (i32.add - (local.get $x) - (i32.const 0x80000000) - ) - )) - ;; eqz(x + 0x80000001) -> x == 2147483647 - (drop (i32.eqz - (i32.add - (local.get $x) - (i32.const 0x80000001) - ) - )) - ;; eqz(x - y) - (drop (i32.eqz - (i32.sub - (local.get $x) - (local.get $y) - ) - )) - (drop (i64.eqz - (i64.sub - (local.get $X) - (local.get $Y) - ) - )) - ;; x - y == 0 - (drop (i32.eq - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - (drop (i64.eq - (i64.sub - (local.get $X) - (local.get $Y) - ) - (i64.const 0) - )) - ;; x - y != 0 - (drop (i32.ne - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - (drop (i64.ne - (i64.sub - (local.get $X) - (local.get $Y) - ) - (i64.const 0) - )) - ;; i32(x - y) > 0 -> x > y - (drop (i32.gt_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; i32(x - y) >= 0 -> x >= y - (drop (i32.ge_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; u32(x - y) > 0 -> x != y - (drop (i32.gt_u - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; u32(x - y) >= 0 -> 1 - (drop (i32.ge_u - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; u64(x - y) >= 0 -> i32(1) - (drop (i64.ge_u - (i64.sub - (local.get $X) - (local.get $Y) - ) - (i64.const 0) - )) - ;; i32(x - y) < 0 -> x < y - (drop (i32.lt_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; i32(x - y) <= 0 -> x <= y - (drop (i32.le_s - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; u32(x - y) < 0 -> 0 - (drop (i32.lt_u - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; u64(x - y) < 0 -> i32(0) - (drop (i64.lt_u - (i64.sub - (local.get $X) - (local.get $Y) - ) - (i64.const 0) - )) - ;; u32(x - y) <= 0 -> x == y - (drop (i32.le_u - (i32.sub - (local.get $x) - (local.get $y) - ) - (i32.const 0) - )) - ;; i32(x - 0x80000000) == 0 -> x == 0x80000000 - (drop (i32.eq - (i32.sub - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 0) - )) - ;; i32(x - 0x80000000) != 0 -> x == 0x80000000 - (drop (i32.ne - (i32.sub - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 0) - )) - ;; i32(x - { 0x80000000 }) < 0 -> skip - (drop (i32.lt_s - (i32.sub - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 0) - )) - ;; i32(x - { 0x80000000 }) >= 0 -> skip - (drop (i32.ge_s - (i32.sub - (local.get $x) - (i32.const 0x80000000) - ) - (i32.const 0) - )) - ;; i32(x - { 0x80000000 }) > 0 -> skip - (drop (i32.gt_s - (i32.sub - (local.get $x) - (block (result i32) - (i32.const 0x80000000) - ) - ) - (i32.const 0) - )) - ;; i32(x - { 0x80000000 }) <= 0 -> skip - (drop (i32.gt_s - (i32.sub - (local.get $x) - (block (result i32) - (i32.const 0x80000000) - ) - ) - (i32.const 0) - )) - ) - (func $unsigned-context (param $x i32) (param $y i64) - (drop (i32.div_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const 3) - )) - (drop (i32.div_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const -3) ;; skip - )) - (drop (i32.div_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const 0x80000000) ;; skip - )) - (drop (i64.div_s - (i64.and - (local.get $y) - (i64.const 0x7fffffffffffffff) - ) - (i64.const 2) - )) - (drop (i64.div_s - (i64.and - (local.get $y) - (i64.const 0x7fffffffffffffff) - ) - (i64.const -1) ;; skip - )) - (drop (i32.rem_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const 3) - )) - (drop (i32.shr_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const 7) - )) - (drop (i32.ge_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const 7) - )) - (drop (i32.ge_s - (i32.and - (local.get $x) - (i32.const 0x7fffffff) - ) - (i32.const -7) ;; skip - )) - ) - (func $optimize-float-mul-by-two (param $0 f64) (param $1 f32) - (drop (f64.mul - (local.get $0) - (f64.const 2) - )) - (drop (f32.mul - (local.get $1) - (f32.const 2) - )) - - (drop (f64.mul - (call $tee-with-unreachable-value) ;; side effect - (f64.const 2) - )) - (drop (f64.mul - (f64.neg (local.get $0)) ;; complex expression - (f64.const 2) - )) - ) - (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) - ;; unary - (drop (f64.abs (f64.abs (local.get $w)))) - (drop (f64.ceil (f64.ceil (local.get $w)))) - (drop (f64.floor (f64.floor (local.get $w)))) - (drop (f64.trunc (f64.trunc (local.get $w)))) - (drop (f64.nearest (f64.nearest (local.get $w)))) - - (drop (f64.nearest (f64.trunc (local.get $w)))) ;; skip - (drop (f64.trunc (f64.nearest (local.get $w)))) ;; skip - - (drop (f64.neg (f64.neg (local.get $w)))) - (drop (f64.neg (f64.neg (f64.neg (local.get $w))))) - (drop (f64.neg (f64.neg (f64.neg (f64.neg (local.get $w)))))) - - (drop (i32.eqz (i32.eqz (local.get $x)))) ;; skip - (drop (i32.eqz (i32.eqz (i32.eqz (local.get $x))))) - (drop (i32.eqz (i32.eqz (i64.eqz (i64.const 1))))) - (drop (i32.eqz (i32.eqz (i32.ne (local.get $x) (i32.const 2))))) - - (drop (i32.eqz - (i32.eqz - (i32.and - (local.get $x) - (i32.const 1) - ) - ) - )) - - ;; binary - ;; ((signed)x % y) % y - (drop (i32.rem_s - (i32.rem_s - (local.get $x) - (local.get $y) - ) - (local.get $y) - )) - ;; ((unsigned)x % y) % y - (drop (i32.rem_u - (i32.rem_u - (local.get $x) - (local.get $y) - ) - (local.get $y) - )) - ;; 0 - (0 - y) - (drop (i32.sub - (i32.const 0) - (i32.sub - (i32.const 0) - (local.get $y) - ) - )) - ;; x - (x - y) - (drop (i32.sub - (local.get $x) - (i32.sub - (local.get $x) - (local.get $y) - ) - )) - ;; y - (x - y) - skip - (drop (i32.sub - (local.get $y) - (i32.sub - (local.get $x) - (local.get $y) - ) - )) - ;; x ^ (x ^ y) - (drop (i32.xor - (local.get $x) - (i32.xor - (local.get $x) - (local.get $y) - ) - )) - ;; x ^ (y ^ x) - (drop (i32.xor - (local.get $x) - (i32.xor - (local.get $y) - (local.get $x) - ) - )) - ;; (x ^ y) ^ x - (drop (i32.xor - (i32.xor - (local.get $x) - (local.get $y) - ) - (local.get $x) - )) - ;; (y ^ x) ^ x - (drop (i32.xor - (i32.xor - (local.get $y) - (local.get $x) - ) - (local.get $x) - )) - ;; x ^ (x ^ x) - (drop (i32.xor - (local.get $x) - (i32.xor - (local.get $x) - (local.get $x) - ) - )) - ;; x & (x & y) - (drop (i32.and - (local.get $x) - (i32.and - (local.get $x) - (local.get $y) - ) - )) - ;; x & (y & x) - (drop (i32.and - (local.get $x) - (i32.and - (local.get $y) - (local.get $x) - ) - )) - ;; (x & y) & x - (drop (i32.and - (i32.and - (local.get $x) - (local.get $y) - ) - (local.get $x) - )) - ;; (y & x) & x - (drop (i32.and - (i32.and - (local.get $y) - (local.get $x) - ) - (local.get $x) - )) - ;; x | (x | y) - (drop (i32.or - (local.get $x) - (i32.or - (local.get $x) - (local.get $y) - ) - )) - ;; x | (y | x) - (drop (i32.or - (local.get $x) - (i32.or - (local.get $y) - (local.get $x) - ) - )) - ;; (x | y) | x - (drop (i32.or - (i32.or - (local.get $x) - (local.get $y) - ) - (local.get $x) - )) - ;; (y | x) | x - (drop (i32.or - (i32.or - (local.get $y) - (local.get $x) - ) - (local.get $x) - )) - ;; (y | x) | z - skip - (drop (i32.or - (i32.or - (local.get $y) - (local.get $x) - ) - (local.get $z) - )) - ;; (z | x) | y - skip - (drop (i32.or - (i32.or - (local.get $z) - (local.get $x) - ) - (local.get $y) - )) - ;; (SE() | x) | x - (drop (i32.or - (i32.or - (call $ne0) ;; side effect - (local.get $x) - ) - (local.get $x) - )) - ;; (x | SE()) | SE() - skip - (drop (i32.or - (i32.or - (local.get $x) - (call $ne0) ;; side effect - ) - (call $ne0) ;; side effect - )) - ;; x | (SE() | x) - (drop (i32.or - (local.get $x) - (i32.or - (local.get $x) - (call $ne0) ;; side effect - ) - )) - ;; SE() | (x | SE()) - skip - (drop (i32.or - (call $ne0) ;; side effect - (i32.or - (call $ne0) ;; side effect - (local.get $x) - ) - )) - ;; (y % x) % y - skip - (drop (i32.rem_s - (i32.rem_s - (local.get $y) - (local.get $x) - ) - (local.get $y) - )) - ;; y % (x % y) - skip - (drop (i32.rem_u - (local.get $y) - (i32.rem_u - (local.get $x) - (local.get $y) - ) - )) - ;; x | (y | x) where x and y cannot be reordered - skip - (drop - (i32.or - (local.get $x) - (i32.or - (local.tee $x - (i32.const 1) - ) - (local.get $x) - ) - ) - ) - (drop - (i32.or - (i32.or - (local.get $x) - (local.tee $x - (i32.const 1) - ) - ) - (local.get $x) - ) - ) - ;; x ^ (y ^ x) where x and y cannot be reordered - skip - (drop - (i32.xor - (local.get $x) - (i32.xor - (local.tee $x - (i32.const 1) - ) - (local.get $x) - ) - ) - ) - (drop - (i32.xor - (i32.xor - (local.get $x) - (local.tee $x - (i32.const 1) - ) - ) - (local.get $x) - ) - ) - ) - (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64) - ;; i32 - (drop (i32.shl - (local.get $x) - (i32.const 32) - )) - (drop (i32.shr_s - (local.get $x) - (i32.const 32) - )) - (drop (i32.shr_u - (local.get $x) - (i32.const 64) - )) - (drop (i32.rotl - (local.get $x) - (i32.const 64) - )) - (drop (i32.rotr - (local.get $x) - (i32.const 64) - )) - ;; i64 - (drop (i64.shl - (local.get $z) - (i64.const 64) - )) - (drop (i64.shr_s - (local.get $z) - (i64.const 64) - )) - (drop (i64.shr_u - (local.get $z) - (i64.const 128) - )) - (drop (i64.rotl - (local.get $z) - (i64.const 128) - )) - (drop (i64.rotr - (local.get $z) - (i64.const 128) - )) - - ;; i32 - (drop (i32.shl - (local.get $x) - (i32.and - (local.get $y) - (i32.const 31) - ) - )) - (drop (i32.shl - (local.get $x) - (i32.and - (local.get $y) - (i32.const 63) - ) - )) - (drop (i32.shr_s - (local.get $x) - (i32.and - (local.get $y) - (i32.const 31) - ) - )) - (drop (i32.shr_u - (local.get $x) - (i32.and - (local.get $y) - (i32.const 31) - ) - )) - ;; i64 - (drop (i64.shl - (local.get $z) - (i64.and - (local.get $w) - (i64.const 63) - ) - )) - (drop (i64.shl - (local.get $z) - (i64.and - (local.get $w) - (i64.const 127) - ) - )) - (drop (i64.shr_s - (local.get $z) - (i64.and - (local.get $w) - (i64.const 63) - ) - )) - (drop (i64.shr_u - (local.get $z) - (i64.and - (local.get $w) - (i64.const 63) - ) - )) - ;; i32(x) >> (y & 32) -> x - (drop (i32.shr_u - (local.get $x) - (i32.and - (local.get $y) - (i32.const 32) - ) - )) - ;; i64(x) >> (y & 64) -> x - (drop (i64.shr_u - (local.get $z) - (i64.and - (local.get $w) - (i64.const 128) - ) - )) - - ;; skip - (drop (i64.shl - (local.get $z) - (i64.and - (local.get $w) - (i64.const 32) - ) - )) - ;; skip - (drop (i64.shr_u - (local.get $z) - (i64.and - (local.get $w) - (i64.const 31) - ) - )) - ) - (func $optimize-float-points (param $x0 f64) (param $x1 f64) (param $y0 f32) (param $y1 f32) - ;; abs(x) * abs(x) ==> x * x - (drop (f64.mul - (f64.abs (local.get $x0)) - (f64.abs (local.get $x0)) - )) - (drop (f32.mul - (f32.abs (local.get $y0)) - (f32.abs (local.get $y0)) - )) - (drop (f64.mul - (f64.abs (f64.add (local.get $x0) (local.get $x1))) - (f64.abs (f64.add (local.get $x0) (local.get $x1))) - )) - - ;; abs(x) * abs(y) ==> abs(x * y) - (drop (f64.mul - (f64.abs (local.get $x0)) - (f64.abs (local.get $x1)) - )) - (drop (f32.mul - (f32.abs (local.get $y1)) - (f32.abs (local.get $y0)) - )) - - (drop (f64.mul - (f64.abs (local.get $x0)) - (f64.abs (f64.const 0)) ;; skip - )) - (drop (f32.mul - (f32.abs (f32.const 0)) ;; skip - (f32.abs (local.get $y0)) - )) - (drop (f64.mul - (f64.abs (f64.add (local.get $x0) (local.get $x1))) - (f64.abs (f64.add (local.get $x0) (local.get $x0))) - )) - - - ;; abs(-x) ==> abs(x) - (drop (f64.abs - (f64.neg (local.get $x0)) - )) - (drop (f32.abs - (f32.neg (local.get $y0)) - )) - - ;; abs(0 - x) ==> skip for non-fast math - (drop (f64.abs - (f64.sub - (f64.const 0) - (local.get $x0) - ) - )) - (drop (f32.abs - (f32.sub - (f32.const 0) - (local.get $y0) - ) - )) - - ;; abs(x) / abs(x) ==> x / x - (drop (f64.div - (f64.abs (local.get $x0)) - (f64.abs (local.get $x0)) - )) - (drop (f32.div - (f32.abs (local.get $y0)) - (f32.abs (local.get $y0)) - )) - (drop (f64.div - (f64.abs (f64.add (local.get $x0) (local.get $x1))) - (f64.abs (f64.add (local.get $x0) (local.get $x1))) - )) - - ;; abs(x) / abs(y) ==> abs(x / y) - (drop (f64.div - (f64.abs (local.get $x0)) - (f64.abs (local.get $x1)) - )) - (drop (f32.div - (f32.abs (local.get $y1)) - (f32.abs (local.get $y0)) - )) - - ;; abs(x * x) ==> x * x - (drop (f64.abs - (f64.mul - (local.get $x0) - (local.get $x0) - ) - )) - (drop (f32.abs - (f32.mul - (local.get $y0) - (local.get $y0) - ) - )) - - ;; abs(x / x) ==> x / x - (drop (f64.abs - (f64.div - (local.get $x0) - (local.get $x0) - ) - )) - (drop (f32.abs - (f32.div - (local.get $y0) - (local.get $y0) - ) - )) - - (drop (f64.div - (f64.abs (local.get $x0)) - (f64.abs (f64.const 0)) ;; skip - )) - (drop (f32.div - (f32.abs (f32.const 0)) ;; skip - (f32.abs (local.get $y0)) - )) - (drop (f64.div - (f64.abs (f64.add (local.get $x0) (local.get $x1))) - (f64.abs (f64.add (local.get $x0) (local.get $x0))) - )) - ) -) -;; atomics -(module - (import "env" "memory" (memory $0 (shared 256 256))) - (func $x - (drop - (i32.shr_s - (i32.shl - (i32.atomic.load8_u ;; can't be signed - (i32.const 100) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) -) -;; bulk memory -(module - (memory 0) - (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) - (memory.copy ;; skip - (local.get $dst) - (local.get $dst) - (local.get $sz) - ) - - (memory.copy ;; skip - (local.get $dst) - (local.get $src) - (i32.const 0) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 1) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 2) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 3) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 4) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 5) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 6) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 7) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 8) - ) - - (memory.copy - (local.get $dst) - (local.get $src) - (i32.const 16) - ) - - (memory.copy ;; skip - (local.get $dst) - (local.get $src) - (local.get $sz) - ) - - (memory.copy ;; skip - (i32.const 0) - (i32.const 0) - (i32.load - (i32.const 3) ;; side effect - ) - ) - ) -) -;; reference types -(module - ;; These functions test if an `if` with subtyped arms is correctly folded - ;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold) - (func $if-arms-subtype-fold (result anyref) - (if (result anyref) - (i32.const 0) - (ref.null extern) - (ref.null extern) - ) - ) - ;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold) - (func $if-arms-subtype-nofold (result anyref) - (if (result anyref) - (i32.const 0) - (ref.null extern) - (ref.null func) - ) - ) -) -;; sign-extensions -(module - (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) - (drop (i32.extend8_s (i32.extend8_s (local.get $x)))) - (drop (i32.extend16_s (i32.extend16_s (local.get $x)))) - ) -) -;; exceptions -(module - (func $test - (if - (try (result i32) - (do - (i32.eqz - (i32.eqz - (i32.const 123) - ) - ) - ) - (catch_all - (i32.eqz - (i32.eqz - (i32.const 456) - ) - ) - ) - ) - (nop) - ) - ) -) -;; typed function references -(module - (type $i32-i32 (func (param i32) (result i32))) - ;; this function has a reference parameter. we analyze parameters, and should - ;; not be confused by a type that has no bit size, in particular. this test - ;; just verifies that we do not crash on that. - (func $call_from-param (param $f (ref null $i32-i32)) (result i32) - (unreachable) - ) -) diff --git a/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt b/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt deleted file mode 100644 index e450f9cc8..000000000 --- a/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt +++ /dev/null @@ -1,384 +0,0 @@ -(module - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) - (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) - (type $none_=>_f64 (func (result f64))) - (memory $0 0) - (func $conditionals (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local.set $0 - (i32.const 0) - ) - (loop $while-in - (local.set $3 - (i32.const 0) - ) - (loop $while-in6 - (local.set $6 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $0 - (if (result i32) - (if (result i32) - (i32.rem_s - (i32.add - (i32.mul - (local.get $0) - (local.tee $7 - (i32.add - (local.get $0) - (i32.const 2) - ) - ) - ) - (i32.const 17) - ) - (i32.const 5) - ) - (i32.eqz - (i32.rem_u - (i32.add - (i32.mul - (local.get $0) - (local.get $0) - ) - (i32.const 11) - ) - (i32.const 3) - ) - ) - (i32.const 1) - ) - (local.get $7) - (local.get $6) - ) - ) - (br_if $while-in6 - (i32.gt_s - (local.get $4) - (local.tee $3 - (i32.add - (local.get $3) - (i32.const 1) - ) - ) - ) - ) - ) - (br_if $while-in - (i32.ne - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (i32.const 27000) - ) - ) - ) - (return - (local.get $5) - ) - ) - (func $side-effect (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local.set $0 - (i32.const 0) - ) - (loop $while-in - (local.set $3 - (i32.const 0) - ) - (loop $while-in6 - (local.set $6 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $0 - (if (result i32) - (i32.or - (i32.eqz - (i32.rem_s - (i32.add - (i32.mul - (local.get $0) - (local.tee $7 - (local.get $0) - ) - ) - (i32.const 17) - ) - (i32.const 5) - ) - ) - (i32.eqz - (i32.rem_u - (i32.add - (i32.mul - (local.get $0) - (local.get $0) - ) - (unreachable) - ) - (i32.const 3) - ) - ) - ) - (local.get $7) - (local.get $6) - ) - ) - (br_if $while-in6 - (i32.gt_s - (local.get $4) - (local.tee $3 - (i32.add - (local.get $3) - (i32.const 1) - ) - ) - ) - ) - ) - (br_if $while-in - (i32.ne - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (i32.const 27000) - ) - ) - ) - (return - (local.get $5) - ) - ) - (func $flip (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local.set $0 - (i32.const 0) - ) - (loop $while-in - (local.set $3 - (i32.const 0) - ) - (loop $while-in6 - (local.set $6 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $0 - (if (result i32) - (if (result i32) - (i32.rem_u - (i32.add - (i32.mul - (local.get $0) - (local.get $0) - ) - (i32.const 100) - ) - (i32.const 3) - ) - (i32.eqz - (i32.rem_s - (i32.add - (i32.mul - (local.get $0) - (i32.eqz - (local.get $0) - ) - ) - (i32.const 17) - ) - (i32.const 5) - ) - ) - (i32.const 1) - ) - (local.get $7) - (local.get $6) - ) - ) - (br_if $while-in6 - (i32.gt_s - (local.get $4) - (local.tee $3 - (i32.add - (local.get $3) - (i32.const 1) - ) - ) - ) - ) - ) - (br_if $while-in - (i32.ne - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (i32.const 27000) - ) - ) - ) - (return - (local.get $5) - ) - ) - (func $invalidate-conditionalizeExpensiveOnBitwise (param $0 i32) (param $1 i32) (result i32) - (if - (i32.eqz - (i32.and - (i32.lt_u - (i32.and - (i32.shr_s - (i32.shl - (i32.sub - (local.get $1) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 255) - ) - (i32.const 3) - ) - (i32.ne - (local.tee $1 - (i32.const 0) - ) - (i32.const 0) - ) - ) - ) - (return - (local.get $0) - ) - ) - (return - (local.get $1) - ) - ) - (func $invalidate-conditionalizeExpensiveOnBitwise-ok (param $0 i32) (param $1 i32) (result i32) - (if - (i32.eqz - (if (result i32) - (local.tee $1 - (i32.const 0) - ) - (i32.lt_u - (i32.and - (i32.shr_s - (i32.shl - (i32.sub - (local.get $0) - (i32.const 1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 255) - ) - (i32.const 3) - ) - (i32.const 0) - ) - ) - (return - (local.get $0) - ) - ) - (return - (local.get $1) - ) - ) - (func $conditionalize-if-type-change (result f64) - (local $0 i32) - (drop - (loop $label$1 (result f32) - (block $label$2 (result f32) - (drop - (block $label$3 (result f32) - (br_if $label$1 - (i32.or - (f32.gt - (br_if $label$3 - (f32.const 1) - (local.get $0) - ) - (br $label$2 - (f32.const 71) - ) - ) - (i64.eqz - (select - (i64.const 58) - (i64.const -982757) - (i64.eqz - (i64.const 0) - ) - ) - ) - ) - ) - ) - ) - (f32.const 1) - ) - ) - ) - (f64.const -nan:0xfffffffffffff) - ) - (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) - (block - (drop - (local.get $dst) - ) - (drop - (local.get $dst) - ) - (drop - (local.get $sz) - ) - ) - (block - (drop - (local.get $dst) - ) - (drop - (local.get $src) - ) - ) - ) -) diff --git a/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.wast b/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.wast deleted file mode 100644 index b97597582..000000000 --- a/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.wast +++ /dev/null @@ -1,378 +0,0 @@ -(module - (type $0 (func (param i32 i32) (result i32))) - (memory $0 0) - (func $conditionals (type $0) (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local.set $0 - (i32.const 0) - ) - (loop $while-in - (local.set $3 - (i32.const 0) - ) - (loop $while-in6 - (local.set $6 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $0 - (if (result i32) - (i32.or ;; this or is very expensive. we should compute one side, then see if we even need the other - (i32.eqz - (i32.rem_s - (i32.add - (i32.mul - (local.tee $7 ;; side effect, so we can't do this one - (i32.add - (local.get $0) - (i32.const 2) - ) - ) - (local.get $0) - ) - (i32.const 17) - ) - (i32.const 5) - ) - ) - (i32.eqz - (i32.rem_u - (i32.add - (i32.mul - (local.get $0) - (local.get $0) - ) - (i32.const 11) - ) - (i32.const 3) - ) - ) - ) - (local.get $7) - (local.get $6) - ) - ) - (br_if $while-in6 - (i32.lt_s - (local.tee $3 - (i32.add - (local.get $3) - (i32.const 1) - ) - ) - (local.get $4) - ) - ) - ) - (br_if $while-in - (i32.ne - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (i32.const 27000) - ) - ) - ) - (return - (local.get $5) - ) - ) - (func $side-effect (type $0) (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local.set $0 - (i32.const 0) - ) - (loop $while-in - (local.set $3 - (i32.const 0) - ) - (loop $while-in6 - (local.set $6 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $0 - (if (result i32) - (i32.or ;; this or is very expensive, but has a side effect on both sides - (i32.eqz - (i32.rem_s - (i32.add - (i32.mul - (local.tee $7 - (i32.add - (local.get $0) - (i32.const 0) - ) - ) - (local.get $0) - ) - (i32.const 17) - ) - (i32.const 5) - ) - ) - (i32.eqz - (i32.rem_u - (i32.add - (i32.mul - (local.get $0) - (local.get $0) - ) - (unreachable) - ) - (i32.const 3) - ) - ) - ) - (local.get $7) - (local.get $6) - ) - ) - (br_if $while-in6 - (i32.lt_s - (local.tee $3 - (i32.add - (local.get $3) - (i32.const 1) - ) - ) - (local.get $4) - ) - ) - ) - (br_if $while-in - (i32.ne - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (i32.const 27000) - ) - ) - ) - (return - (local.get $5) - ) - ) - (func $flip (type $0) (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local.set $0 - (i32.const 0) - ) - (loop $while-in - (local.set $3 - (i32.const 0) - ) - (loop $while-in6 - (local.set $6 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $0 - (if (result i32) - (i32.or ;; this or is very expensive, and the first side has no side effect - (i32.eqz - (i32.rem_s - (i32.add - (i32.mul - (i32.eqz - (i32.add - (local.get $0) - (i32.const 0) - ) - ) - (local.get $0) - ) - (i32.const 17) - ) - (i32.const 5) - ) - ) - (i32.eqz - (i32.rem_u - (i32.add - (i32.mul - (local.get $0) - (local.get $0) - ) - (i32.const 100) - ) - (i32.const 3) - ) - ) - ) - (local.get $7) - (local.get $6) - ) - ) - (br_if $while-in6 - (i32.lt_s - (local.tee $3 - (i32.add - (local.get $3) - (i32.const 1) - ) - ) - (local.get $4) - ) - ) - ) - (br_if $while-in - (i32.ne - (local.tee $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (i32.const 27000) - ) - ) - ) - (return - (local.get $5) - ) - ) - (func $invalidate-conditionalizeExpensiveOnBitwise (param $0 i32) (param $1 i32) (result i32) - (if - (i32.eqz - (i32.and - (i32.lt_s - (i32.and - (i32.shr_s - (i32.shl - (i32.add - (local.get $1) ;; conflict with tee - (i32.const -1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 255) - ) - (i32.const 3) - ) - (i32.ne - (local.tee $1 - (i32.const 0) - ) - (i32.const 0) - ) - ) - ) - (return (local.get $0)) - ) - (return (local.get $1)) - ) - (func $invalidate-conditionalizeExpensiveOnBitwise-ok (param $0 i32) (param $1 i32) (result i32) - (if - (i32.eqz - (i32.and - (i32.lt_s - (i32.and - (i32.shr_s - (i32.shl - (i32.add - (local.get $0) ;; no conflict - (i32.const -1) - ) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const 255) - ) - (i32.const 3) - ) - (i32.ne - (local.tee $1 - (i32.const 0) - ) - (i32.const 0) - ) - ) - ) - (return (local.get $0)) - ) - (return (local.get $1)) - ) - - (func $conditionalize-if-type-change (result f64) - (local $0 i32) - (drop - (loop $label$1 (result f32) - (block $label$2 (result f32) - (drop - (block $label$3 (result f32) - (br_if $label$1 - (i32.or ;; this turns into an if, but then the if might not be unreachable - (f32.gt - (br_if $label$3 - (f32.const 1) - (local.get $0) - ) - (br $label$2 - (f32.const 71) - ) - ) - (i64.eqz - (select - (i64.const 58) - (i64.const -982757) - (i64.eqz - (i64.const 0) - ) - ) - ) - ) - ) - ) - ) - (f32.const 1) - ) - ) - ) - (f64.const -nan:0xfffffffffffff) - ) - (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) - (memory.copy ;; nop - (local.get $dst) - (local.get $dst) - (local.get $sz) - ) - - (memory.copy ;; nop - (local.get $dst) - (local.get $src) - (i32.const 0) - ) - ) -) - |