summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-01-21 19:34:57 -0500
committerGitHub <noreply@github.com>2021-01-21 16:34:57 -0800
commit7a83bc744fff43349e6612263f11bce1fe8dbf34 (patch)
tree87bd8d4e3c1c3bea6e883f08848539e47f3f62f0
parent3f4d3b3eff5d8112a9da3674a5f5eea696ca3c7d (diff)
downloadbinaryen-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.
-rwxr-xr-xauto_update_tests.py14
-rwxr-xr-xscripts/fuzz_opt.py5
-rw-r--r--scripts/test/shared.py7
-rwxr-xr-xscripts/update_lit_checks.py179
-rw-r--r--test/lit/passes/optimize-instructions-atomics.wast33
-rw-r--r--test/lit/passes/optimize-instructions-bulk-memory.wast160
-rw-r--r--test/lit/passes/optimize-instructions-exceptions.wast40
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast33
-rw-r--r--test/lit/passes/optimize-instructions-ignore-traps.wast760
-rw-r--r--test/lit/passes/optimize-instructions-sign-ext.wast21
-rw-r--r--test/lit/passes/optimize-instructions-typed-function-references.wast16
-rw-r--r--test/lit/passes/optimize-instructions.wast11557
-rw-r--r--test/passes/optimize-instructions_all-features.txt5704
-rw-r--r--test/passes/optimize-instructions_all-features.wast6184
-rw-r--r--test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt384
-rw-r--r--test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.wast378
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)
- )
- )
-)
-